diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6d402d2a4cfa5ff49ab94e9ff8141ebb64ccea83..a3433756d678fa76434aed887e2515f8d76a61e9 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -113,6 +113,14 @@ macro(add_list_string_option name val helpstr) add_definitions("-D${name}=\"${value}\"") endif() endmacro(add_list_string_option) + +function(make_version VERSION_VALUE) + math(EXPR RESULT "0") + foreach (ARG ${ARGN}) + math(EXPR RESULT "${RESULT} * 16 + ${ARG}") + endforeach() + set(${VERSION_VALUE} "${RESULT}" PARENT_SCOPE) +endfunction() #################################################### # compilation flags ############################################# @@ -162,7 +170,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC ") # add autotools definitions that were maybe used! set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP" + "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 " @@ -242,6 +250,8 @@ add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace") add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace") add_boolean_option(DISABLE_LOG_X False "Deactivate all LOG_* macros") add_boolean_option(USRP_REC_PLAY False "Enable USRP record playback mode") +add_boolean_option(UE_NAS_USE_TUN False "Enable UE NAS TUN device instead of ue_ip.ko") +add_boolean_option(BASIC_SIMULATOR False "Has to be True when building the basic simulator, False otherwise") add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") @@ -280,19 +290,24 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR}) # RRC ###### -add_list2_option(RRC_ASN1_VERSION "Rel10" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA") +add_list2_option(RRC_ASN1_VERSION "Rel14" "ASN.1 version of RRC interface" "Rel8" "Rel10" "Rel14" "CBA") if (${RRC_ASN1_VERSION} STREQUAL "Rel8") - set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn) + make_version(RRC_VERSION 8 6 0) + set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn) elseif (${RRC_ASN1_VERSION} STREQUAL "CBA") - set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn) + make_version(RRC_VERSION 10 2 0) + add_definitions(-DCBA) + set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn) elseif (${RRC_ASN1_VERSION} STREQUAL "Rel10") - set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn) + make_version(RRC_VERSION 10 2 0) + set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn) else() - set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e30.asn) + make_version(RRC_VERSION 14 3 0) + set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/RRC-e30.asn) endif (${RRC_ASN1_VERSION} STREQUAL "Rel8") - -set (RRC_FULL_DIR ${asn1_generated_dir}/${RRC_ASN1_VERSION}) +add_definitions(-DRRC_VERSION=${RRC_VERSION}) +set (RRC_FULL_DIR ${asn1_generated_dir}/RRC_${RRC_ASN1_VERSION}) if(NOT EXISTS ${asn1c_call}) message( FATAL_ERROR "The script ${asn1c_call} must be present" ) endif(NOT EXISTS ${asn1c_call}) @@ -314,7 +329,8 @@ file(GLOB rrc_h ${RRC_FULL_DIR}/*.h) set(rrc_h ${rrc_h} ${RRC_FULL_DIR}/asn1_constants.h) set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code add_library(RRC_LIB ${rrc_h} ${rrc_source} - ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg.c) + ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c + ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c) include_directories ("${RRC_FULL_DIR}") # add the command to generate the source code @@ -330,18 +346,20 @@ add_custom_command ( # Same limitation as described in RRC: unknown generated file list # so we generate it at cmake time ############## -add_list1_option(S1AP_VERSION R10 "S1AP Asn.1 grammar version" R8 R9 R10) +add_list1_option(S1AP_RELEASE R10 "S1AP ASN.1 grammar version" R8 R9 R10) set(S1AP_DIR ${OPENAIR3_DIR}/S1AP) -if (${S1AP_VERSION} STREQUAL "R10") - set (ASN1RELDIR R10.5) - add_definitions("-DUPDATE_RELEASE_9 -DUPDATE_RELEASE_10") -elseif (${S1AP_VERSION} STREQUAL "R9") - set (ASN1RELDIR R9.8) - add_definitions("-DUPDATE_RELEASE_9") -else(${S1AP_VERSION} STREQUAL "R8") +if (${S1AP_RELEASE} STREQUAL "R8") + make_version(S1AP_VERSION 8 10 0) set (ASN1RELDIR R8.10) -endif(${S1AP_VERSION} STREQUAL "R10") +elseif (${S1AP_RELEASE} STREQUAL "R9") + make_version(S1AP_VERSION 9 8 0) + set (ASN1RELDIR R9.8) +elseif (${S1AP_RELEASE} STREQUAL "R10") + make_version(S1AP_VERSION 10 5 0) + set (ASN1RELDIR R10.5) +endif(${S1AP_RELEASE} STREQUAL "R8") +add_definitions(-DS1AP_VERSION=${S1AP_VERSION}) set(S1AP_ASN_DIR ${S1AP_DIR}/MESSAGES/ASN1/${ASN1RELDIR}) set(S1AP_ASN_FILES ${S1AP_ASN_DIR}/S1AP-CommonDataTypes.asn @@ -349,7 +367,7 @@ set(S1AP_ASN_FILES ${S1AP_ASN_DIR}/S1AP-IEs.asn ${S1AP_ASN_DIR}/S1AP-PDU.asn ) -set(S1AP_C_DIR ${asn1_generated_dir}/${ASN1RELDIR}) +set(S1AP_C_DIR ${asn1_generated_dir}/S1AP_${ASN1RELDIR}) #message("calling ${asn1c_call} ${S1AP_C_DIR} ${S1AP_ASN_FILES}") execute_process(COMMAND ${asn1c_call} ${S1AP_C_DIR} ${S1AP_ASN_FILES} RESULT_VARIABLE ret) @@ -361,7 +379,7 @@ execute_process(COMMAND python ${S1AP_DIR}/MESSAGES/ASN1/asn1tostruct.py -f${S1A if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "asn1tostruct.py: error") endif (NOT ${ret} STREQUAL 0) -execute_process(COMMAND ${fix_asn1c_call} ${S1AP_C_DIR} S1AP ${S1AP_VERSION} +execute_process(COMMAND ${fix_asn1c_call} ${S1AP_C_DIR} S1AP ${S1AP_RELEASE} RESULT_VARIABLE ret) if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "${fix_asn1c_call}: error") @@ -382,7 +400,7 @@ add_custom_command ( OUTPUT ${S1AP_OAI_generated} COMMAND ${asn1c_call} ${S1AP_C_DIR} ${S1AP_ASN_FILES} COMMAND python ${S1AP_DIR}/MESSAGES/ASN1/asn1tostruct.py -f${S1AP_ASN_DIR}/S1AP-PDU-Contents.asn -o${S1AP_C_DIR} - COMMAND ${fix_asn1c_call} ${S1AP_C_DIR} S1AP ${S1AP_VERSION} + COMMAND ${fix_asn1c_call} ${S1AP_C_DIR} S1AP ${S1AP_RELEASE} DEPENDS ${S1AP_ASN_FILES} ) add_library(S1AP_LIB @@ -416,13 +434,16 @@ add_library(S1AP_ENB # Same limitation as described in RRC/S1AP: unknown generated file list # so we generate it at cmake time ############## -add_list1_option(X2AP_VERSION R11 "X2AP Asn.1 grammar version" R10 R11) +add_list1_option(X2AP_RELEASE R11 "X2AP ASN.1 grammar version" R10 R11) set(X2AP_DIR ${OPENAIR2_DIR}/X2AP) -if (${X2AP_VERSION} STREQUAL "R11") - set (ASN1RELDIR R11.2) -elseif (${X2AP_VERSION} STREQUAL "R10") +if (${X2AP_RELEASE} STREQUAL "R10") + make_version(S1AP_VERSION 10 0 0) set (ASN1RELDIR R.UNKNOWN) -endif(${X2AP_VERSION} STREQUAL "R11") +elseif (${X2AP_RELEASE} STREQUAL "R11") + make_version(S1AP_VERSION 11 2 0) + set (ASN1RELDIR R11.2) +endif(${X2AP_RELEASE} STREQUAL "R10") +add_definitions(-DX2AP_VERSION=${X2AP_VERSION}) set(X2AP_ASN_DIR ${X2AP_DIR}/MESSAGES/ASN1/${ASN1RELDIR}) set(X2AP_ASN_FILES ${X2AP_ASN_DIR}/X2AP-CommonDataTypes.asn @@ -432,7 +453,7 @@ set(X2AP_ASN_FILES ${X2AP_ASN_DIR}/X2AP-Containers.asn ) -set(X2AP_C_DIR ${asn1_generated_dir}/${ASN1RELDIR}) +set(X2AP_C_DIR ${asn1_generated_dir}/X2AP_${ASN1RELDIR}) #message("calling ${asn1c_call} ${X2AP_C_DIR} ${X2AP_ASN_FILES}") execute_process(COMMAND ${asn1c_call} ${X2AP_C_DIR} ${X2AP_ASN_FILES} RESULT_VARIABLE ret) @@ -444,7 +465,7 @@ execute_process(COMMAND python ${X2AP_DIR}/MESSAGES/ASN1/asn1tostruct.py -f ${X2 if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "asn1tostruct.py: error") endif (NOT ${ret} STREQUAL 0) -execute_process(COMMAND ${fix_asn1c_call} ${X2AP_C_DIR} X2AP ${X2AP_VERSION} +execute_process(COMMAND ${fix_asn1c_call} ${X2AP_C_DIR} X2AP ${X2AP_RELEASE} RESULT_VARIABLE ret) if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "${fix_asn1c_call}: error") @@ -465,7 +486,7 @@ add_custom_command ( OUTPUT ${X2AP_OAI_generated} COMMAND ${asn1c_call} ${X2AP_C_DIR} ${X2AP_ASN_FILES} COMMAND python ${X2AP_DIR}/MESSAGES/ASN1/asn1tostruct.py -f ${X2AP_ASN_DIR}/X2AP-PDU-Contents.asn -o ${X2AP_C_DIR} - COMMAND ${fix_asn1c_call} ${X2AP_C_DIR} X2AP ${X2AP_VERSION} + COMMAND ${fix_asn1c_call} ${X2AP_C_DIR} X2AP ${X2AP_RELEASE} DEPENDS ${X2AP_ASN_FILES} ) @@ -561,14 +582,26 @@ add_library(oai_mobipass MODULE ${TPLIB_MOBIPASS_SOURCE} ) get_target_property(mobipas_cflags oai_mobipass COMPILE_FLAGS) set_target_properties(oai_mobipass PROPERTIES COMPILE_FLAGS "${mobipass_cflags} -fvisibility=hidden") +# TCP bridge libraries +###################################################################### + +# this one is for internal use at Eurecom and is not documented set(HWLIB_TCP_BRIDGE_SOURCE ${OPENAIR_TARGETS}/ARCH/tcp_bridge/tcp_bridge.c ) -add_library(oai_tcp_bridge MODULE ${HWLIB_TCP_BRIDGE_SOURCE} ) +add_library(tcp_bridge MODULE ${HWLIB_TCP_BRIDGE_SOURCE} ) -#get_target_property(tcp_bridge_cflags oai_tcp_bridge COMPILE_FLAGS) -#set_target_properties(oai_tcp_bridge PROPERTIES COMPILE_FLAGS "${tcp_bridge_cflags} -fvisibility=hidden") -set_target_properties(oai_tcp_bridge PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") +#get_target_property(tcp_bridge_cflags tcp_bridge COMPILE_FLAGS) +#set_target_properties(tcp_bridge PROPERTIES COMPILE_FLAGS "${tcp_bridge_cflags} -fvisibility=hidden") +set_target_properties(tcp_bridge PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") + +# this one is to connect OAI eNB and OAI UE in the basic simulator +# see targets/ARCH/tcp_bridge/README.tcp_bridge_oai for usage +set(HWLIB_TCP_BRIDGE_OAI_SOURCE + ${OPENAIR_TARGETS}/ARCH/tcp_bridge/tcp_bridge_oai.c + ) +add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} ) +set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") ########################################################## @@ -599,7 +632,6 @@ add_boolean_option(MESSAGE_CHART_GENERATOR False "For generating sequenc add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams") add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchanges in sequence diagrams") -add_boolean_option(FLEXRAN_AGENT_SB_IF False "enable FlexRAN agent to inteface with a SDN controller") add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION with max 256 UE") add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE") @@ -638,12 +670,6 @@ add_boolean_option(DEBUG_PHY False "Enable PHY layer debugging opt add_boolean_option(DEBUG_PHY_PROC False "Enable debugging of PHY layer procedures") add_boolean_option(DEBUG_DLSCH False "Enable debugging of DLSCH physical layer channel") -########################## -# 802.21 options -########################## -add_boolean_option(ENABLE_RAL False "ENABLE 802.21 INTERFACE") -add_boolean_option(USE_3GPP_ADDR_AS_LINK_ADDR False "As per attribute name") - ########################## # NAS LAYER OPTIONS ########################## @@ -712,7 +738,7 @@ include_directories("${OPENAIR_BIN_DIR}") # add directories to find all include files # the internal rule is to use generic names such as defs.h # but to make it uniq name as adding the relative path in the include directtive -# example: #include "RRC/LITE/defs.h" +# example: #include "RRC/LTE/rrc_defs.h" #find_path (include_dirs_all *.h ${OPENAIR_DIR}) #find_path (include_dirs_all *.h PATHS /usr/include NO_CMAKE_PATH) #include_directories("${include_dirs_all}") @@ -744,11 +770,8 @@ include_directories("${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0") include_directories("${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0") include_directories("${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0") include_directories("${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0") -include_directories("${OPENAIR2_DIR}/RRC/LITE/MESSAGES") -include_directories("${OPENAIR2_DIR}/RRC/LITE") -include_directories("${OPENAIR3_DIR}/RAL-LTE/INTERFACE-802.21/INCLUDE") -include_directories("${OPENAIR3_DIR}/RAL-LTE/LTE_RAL_ENB/INCLUDE") -include_directories("${OPENAIR3_DIR}/RAL-LTE/LTE_RAL_UE/INCLUDE") +include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES") +include_directories("${OPENAIR2_DIR}/RRC/LTE") include_directories("${OPENAIR_DIR}/common/utils") include_directories("${OPENAIR_DIR}/common/utils/itti") include_directories("${OPENAIR3_DIR}/NAS/COMMON") @@ -769,6 +792,8 @@ include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/USERSPACE/LIB/") include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS") include_directories("${OPENAIR2_DIR}/ENB_APP") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC") +include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC") +include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP") include_directories("${OPENAIR2_DIR}/UTIL/OSA") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc") @@ -783,99 +808,101 @@ include_directories("${OPENAIR2_DIR}/UTIL/OTG") include_directories("${OPENAIR2_DIR}/UTIL/CLI") include_directories("${OPENAIR2_DIR}/UTIL/OPT") include_directories("${OPENAIR2_DIR}/UTIL/OMV") -include_directories("${OPENAIR2_DIR}/RRC/LITE/MESSAGES") +include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES") include_directories("${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/shared") include_directories("${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/include") include_directories("${OPENAIR_DIR}") # Utilities Library ################ -if (FLEXRAN_AGENT_SB_IF) - # set the version of protobuf messages, V3 not supported yet - add_list1_option(FLPT_VERSION V2 "FLPT MSG protobuf grammar version" V2 V3) - - if (${FLPT_VERSION} STREQUAL "V2") - set (FLPTDIR V2) - elseif (${FLPT_VERSION} STREQUAL "V3") - set (FLPTDIR V3) - endif(${FLPT_VERSION} STREQUAL "V2") - - set(FLPT_MSG_DIR ${OPENAIR2_DIR}/ENB_APP/MESSAGES/${FLPTDIR} ) - set(FLPT_MSG_FILES - ${FLPT_MSG_DIR}/header.proto - ${FLPT_MSG_DIR}/flexran.proto - ${FLPT_MSG_DIR}/stats_common.proto - ${FLPT_MSG_DIR}/stats_messages.proto - ${FLPT_MSG_DIR}/time_common.proto - ${FLPT_MSG_DIR}/controller_commands.proto - ${FLPT_MSG_DIR}/mac_primitives.proto - ${FLPT_MSG_DIR}/config_messages.proto - ${FLPT_MSG_DIR}/config_common.proto - ${FLPT_MSG_DIR}/control_delegation.proto - ) +# set the version of protobuf messages, V3 not supported yet +add_list1_option(FLPT_VERSION V2 "FLPT MSG protobuf grammar version" V2 V3) + +if (${FLPT_VERSION} STREQUAL "V2") + set (FLPTDIR V2) +elseif (${FLPT_VERSION} STREQUAL "V3") + set (FLPTDIR V3) +endif(${FLPT_VERSION} STREQUAL "V2") + +set(FLPT_MSG_DIR ${OPENAIR2_DIR}/ENB_APP/MESSAGES/${FLPTDIR} ) +set(FLPT_MSG_FILES + ${FLPT_MSG_DIR}/header.proto + ${FLPT_MSG_DIR}/flexran.proto + ${FLPT_MSG_DIR}/stats_common.proto + ${FLPT_MSG_DIR}/stats_messages.proto + ${FLPT_MSG_DIR}/time_common.proto + ${FLPT_MSG_DIR}/controller_commands.proto + ${FLPT_MSG_DIR}/mac_primitives.proto + ${FLPT_MSG_DIR}/config_messages.proto + ${FLPT_MSG_DIR}/config_common.proto + ${FLPT_MSG_DIR}/control_delegation.proto + ) - set(FLPT_C_DIR ${protobuf_generated_dir}/${FLPTDIR}) - #message("calling protoc_call=${protoc_call} FLPT_C_DIR=${FLPT_C_DIR} FLPT_MSG_FILES=${FLPT_MSG_FILES}") - execute_process(COMMAND ${protoc_call} ${FLPT_C_DIR} ${FLPT_MSG_DIR} ${FLPT_MSG_FILES}) - file(GLOB FLPT_source ${FLPT_C_DIR}/*.c) - set(FLPT_OAI_generated - ${FLPT_C_DIR}/header.pb-c.c - ${FLPT_C_DIR}/flexran.pb-c.c - ${FLPT_C_DIR}/stats_common.pb-c.c - ${FLPT_C_DIR}/stats_messages.pb-c.c - ${FLPT_C_DIR}/time_common.pb-c.c - ${FLPT_C_DIR}/controller_commands.pb-c.c - ${FLPT_C_DIR}/mac_primitives.pb-c.c - ${FLPT_C_DIR}/config_messages.pb-c.c - ${FLPT_C_DIR}/config_common.pb-c.c - ${FLPT_C_DIR}/control_delegation.pb-c.c - ) +set(FLPT_C_DIR ${protobuf_generated_dir}/${FLPTDIR}) +#message("calling protoc_call=${protoc_call} FLPT_C_DIR=${FLPT_C_DIR} FLPT_MSG_FILES=${FLPT_MSG_FILES}") +execute_process(COMMAND ${protoc_call} ${FLPT_C_DIR} ${FLPT_MSG_DIR} ${FLPT_MSG_FILES}) +file(GLOB FLPT_source ${FLPT_C_DIR}/*.c) +set(FLPT_OAI_generated + ${FLPT_C_DIR}/header.pb-c.c + ${FLPT_C_DIR}/flexran.pb-c.c + ${FLPT_C_DIR}/stats_common.pb-c.c + ${FLPT_C_DIR}/stats_messages.pb-c.c + ${FLPT_C_DIR}/time_common.pb-c.c + ${FLPT_C_DIR}/controller_commands.pb-c.c + ${FLPT_C_DIR}/mac_primitives.pb-c.c + ${FLPT_C_DIR}/config_messages.pb-c.c + ${FLPT_C_DIR}/config_common.pb-c.c + ${FLPT_C_DIR}/control_delegation.pb-c.c + ) - file(GLOB flpt_h ${FLPT_C_DIR}/*.h) - set(flpt_h ${flpt_h} ) +file(GLOB flpt_h ${FLPT_C_DIR}/*.h) +set(flpt_h ${flpt_h} ) - add_library(FLPT_MSG - ${FLPT_OAI_generated} - ${FLPT_source} - ) - set(FLPT_MSG_LIB FLPT_MSG) - #message("prpt c dir is : ${FLPT_C_DIR}") - include_directories (${FLPT_C_DIR}) - - add_library(ASYNC_IF - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/socket_link.c - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/link_manager.c - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/message_queue.c - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/ringbuffer_queue.c - ) - set(ASYNC_IF_LIB ASYNC_IF) - include_directories(${OPENAIR2_DIR}/UTIL/ASYNC_IF) - - add_library(FLEXRAN_AGENT - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_handler.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c - ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c - ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c - ) - set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) - #include_directories(${OPENAIR2_DIR}/ENB_APP) +add_library(FLPT_MSG + ${FLPT_OAI_generated} + ${FLPT_source} + ) +set(FLPT_MSG_LIB FLPT_MSG) +#message("prpt c dir is : ${FLPT_C_DIR}") +include_directories (${FLPT_C_DIR}) + +add_library(ASYNC_IF + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/socket_link.c + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/link_manager.c + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/message_queue.c + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/ringbuffer_queue.c + ) +set(ASYNC_IF_LIB ASYNC_IF) +include_directories(${OPENAIR2_DIR}/UTIL/ASYNC_IF) + +add_library(FLEXRAN_AGENT + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_handler.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_timer.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c + ) +set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) +#include_directories(${OPENAIR2_DIR}/ENB_APP) - set(PROTOBUF_LIB "protobuf-c") +set(PROTOBUF_LIB "protobuf-c") - FIND_PATH(LIBYAML_INCLUDE_DIR NAMES yaml.h) - FIND_LIBRARY(LIBYAML_LIBRARIES NAMES yaml libyaml) +FIND_PATH(LIBYAML_INCLUDE_DIR NAMES yaml.h) +FIND_LIBRARY(LIBYAML_LIBRARIES NAMES yaml libyaml) - INCLUDE(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Yaml DEFAULT_MSG LIBYAML_LIBRARIES LIBYAML_INCLUDE_DIR) - MARK_AS_ADVANCED(LIBYAML_INCLUDE_DIR LIBYAML_LIBRARIES) +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Yaml DEFAULT_MSG LIBYAML_LIBRARIES LIBYAML_INCLUDE_DIR) +MARK_AS_ADVANCED(LIBYAML_INCLUDE_DIR LIBYAML_LIBRARIES) - #set(PROTOBUF_LIB "protobuf") #for Cpp -endif() +#set(PROTOBUF_LIB "protobuf") #for Cpp add_library(HASHTABLE @@ -893,9 +920,9 @@ endif() include_directories(${OPENAIR_DIR}/common/utils/msc) set(UTIL_SRC - ${OPENAIR2_DIR}/UTIL/CLI/cli.c - ${OPENAIR2_DIR}/UTIL/CLI/cli_cmd.c - ${OPENAIR2_DIR}/UTIL/CLI/cli_server.c +# ${OPENAIR2_DIR}/UTIL/CLI/cli.c +# ${OPENAIR2_DIR}/UTIL/CLI/cli_cmd.c +# ${OPENAIR2_DIR}/UTIL/CLI/cli_server.c ${OPENAIR2_DIR}/UTIL/FIFO/pad_list.c ${OPENAIR2_DIR}/UTIL/LISTS/list.c ${OPENAIR2_DIR}/UTIL/LISTS/list2.c @@ -903,32 +930,32 @@ set(UTIL_SRC ${OPENAIR2_DIR}/UTIL/LOG/vcd_signal_dumper.c ${OPENAIR2_DIR}/UTIL/MATH/oml.c ${OPENAIR2_DIR}/UTIL/MEM/mem_block.c - ${OPENAIR2_DIR}/UTIL/OCG/OCG.c - ${OPENAIR2_DIR}/UTIL/OCG/OCG_create_dir.c - ${OPENAIR2_DIR}/UTIL/OCG/OCG_detect_file.c - ${OPENAIR2_DIR}/UTIL/OCG/OCG_generate_report.c - ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_filename.c - ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_XML.c - ${OPENAIR2_DIR}/UTIL/OCG/OCG_save_XML.c - ${OPENAIR2_DIR}/UTIL/OMG/common.c - ${OPENAIR2_DIR}/UTIL/OMG/grid.c - ${OPENAIR2_DIR}/UTIL/OMG/job.c - ${OPENAIR2_DIR}/UTIL/OMG/mobility_parser.c - ${OPENAIR2_DIR}/UTIL/OMG/omg.c +# ${OPENAIR2_DIR}/UTIL/OCG/OCG.c +# ${OPENAIR2_DIR}/UTIL/OCG/OCG_create_dir.c +# ${OPENAIR2_DIR}/UTIL/OCG/OCG_detect_file.c +# ${OPENAIR2_DIR}/UTIL/OCG/OCG_generate_report.c +# ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_filename.c +# ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_XML.c +# ${OPENAIR2_DIR}/UTIL/OCG/OCG_save_XML.c +# ${OPENAIR2_DIR}/UTIL/OMG/common.c +# ${OPENAIR2_DIR}/UTIL/OMG/grid.c +# ${OPENAIR2_DIR}/UTIL/OMG/job.c +# ${OPENAIR2_DIR}/UTIL/OMG/mobility_parser.c +# ${OPENAIR2_DIR}/UTIL/OMG/omg.c #${OPENAIR2_DIR}/UTIL/OMG/omg_hashtable.c - ${OPENAIR2_DIR}/UTIL/OMG/rwalk.c - ${OPENAIR2_DIR}/UTIL/OMG/rwp.c - ${OPENAIR2_DIR}/UTIL/OMG/static.c - ${OPENAIR2_DIR}/UTIL/OMG/steadystaterwp.c - ${OPENAIR2_DIR}/UTIL/OMG/trace.c - ${OPENAIR2_DIR}/UTIL/OMG/trace_hashtable.c +# ${OPENAIR2_DIR}/UTIL/OMG/rwalk.c +# ${OPENAIR2_DIR}/UTIL/OMG/rwp.c +# ${OPENAIR2_DIR}/UTIL/OMG/static.c +# ${OPENAIR2_DIR}/UTIL/OMG/steadystaterwp.c +# ${OPENAIR2_DIR}/UTIL/OMG/trace.c +# ${OPENAIR2_DIR}/UTIL/OMG/trace_hashtable.c ${OPENAIR2_DIR}/UTIL/OPT/probe.c - ${OPENAIR2_DIR}/UTIL/OTG/otg_tx.c - ${OPENAIR2_DIR}/UTIL/OTG/otg.c - ${OPENAIR2_DIR}/UTIL/OTG/otg_kpi.c - ${OPENAIR2_DIR}/UTIL/OTG/otg_models.c - ${OPENAIR2_DIR}/UTIL/OTG/otg_form.c - ${OPENAIR2_DIR}/UTIL/OTG/otg_rx.c +# ${OPENAIR2_DIR}/UTIL/OTG/otg_tx.c +# ${OPENAIR2_DIR}/UTIL/OTG/otg.c +# ${OPENAIR2_DIR}/UTIL/OTG/otg_kpi.c +# ${OPENAIR2_DIR}/UTIL/OTG/otg_models.c +# ${OPENAIR2_DIR}/UTIL/OTG/otg_form.c +# ${OPENAIR2_DIR}/UTIL/OTG/otg_rx.c ) add_library(UTIL ${UTIL_SRC}) @@ -962,21 +989,30 @@ set(SECU_CN_SRC ) add_library(SECU_CN ${SECU_CN_SRC}) -# Scheduler +# Physical Channel Procedures Scheduling ################################" set(SCHED_SRC ${OPENAIR1_DIR}/SCHED/fapi_l1.c ${OPENAIR1_DIR}/SCHED/phy_procedures_lte_eNb.c - ${OPENAIR1_DIR}/SCHED/phy_procedures_lte_ue.c ${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c - ${OPENAIR1_DIR}/SCHED/ru_procedures.c -# ${OPENAIR1_DIR}/SCHED/phy_mac_stub.c - ${OPENAIR1_DIR}/SCHED/pucch_pc.c - ${OPENAIR1_DIR}/SCHED/pusch_pc.c - ${OPENAIR1_DIR}/SCHED/srs_pc.c ) add_library(SCHED_LIB ${SCHED_SRC}) +set(SCHED_SRC_RU + ${OPENAIR1_DIR}/SCHED/ru_procedures.c + ${OPENAIR1_DIR}/SCHED/prach_procedures.c +) +add_library(SCHED_RU_LIB ${SCHED_SRC_RU}) + +set(SCHED_SRC_UE + ${OPENAIR1_DIR}/SCHED_UE/phy_procedures_lte_ue.c + ${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c + ${OPENAIR1_DIR}/SCHED_UE/pucch_pc.c + ${OPENAIR1_DIR}/SCHED_UE/pusch_pc.c + ${OPENAIR1_DIR}/SCHED_UE/srs_pc.c +) +add_library(SCHED_UE_LIB ${SCHED_SRC_UE}) + # nFAPI ################################# set(NFAPI_COMMON_SRC @@ -1031,64 +1067,39 @@ include_directories(${NFAPI_USER_DIR}) # Layer 1 ############################# -set(PHY_SRC +set(PHY_TURBOSRC + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder.c +) +set(PHY_TURBOIF + ${OPENAIR1_DIR}/PHY/CODING/coding_load.c +) + +add_library(coding MODULE ${PHY_TURBOSRC} ) +set(PHY_SRC_COMMON # depend on code generation from asn1c ${RRC_FULL_DIR}/asn1_constants.h # actual source - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pss.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots_mbsfn.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_coding.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_modulation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_demodulation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/power_control.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_decoding.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_scrambling.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/uci_tools.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pbch.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/edci.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pcfich.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pucch.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pch.c +# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slss.c +# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sldch.c +# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slsch.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/group_hopping.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/srs_modulation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/drs_modulation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_modulation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_coding.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_decoding.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/rar_tools.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich_common.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pcfich_common.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch_common.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/power_control.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach_common.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pucch_common.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_scrambling.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/srs_modulation.c ${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c - ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c - ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c - ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c - ${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c - ${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c - ${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_timefreq.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_est_freq_offset.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_eNB_measurements.c - ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/adjust_gain.c ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec.c ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_uespec.c ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold.c @@ -1100,13 +1111,11 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c ${OPENAIR1_DIR}/PHY/CODING/crc_byte.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${PHY_TURBOIF} ${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c ${OPENAIR1_DIR}/PHY/CODING/viterbi.c ${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c - ${OPENAIR1_DIR}/PHY/INIT/lte_init.c + ${OPENAIR1_DIR}/PHY/INIT/init_top.c ${OPENAIR1_DIR}/PHY/INIT/lte_parms.c ${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c @@ -1122,15 +1131,98 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c ${OPENAIR1_DIR}/PHY/TOOLS/lut.c ) + +set(PHY_SRC + # actual source + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pss.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots_mbsfn.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_coding.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_modulation.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pbch.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/edci.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pcfich.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pucch.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_decoding.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/rar_tools.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/uci_tools.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_eNB_measurements.c + ${OPENAIR1_DIR}/PHY/INIT/lte_init.c + ) + +set(PHY_SRC_RU + # actual source + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c + ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c + ${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c + ${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c + ${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c + ${OPENAIR1_DIR}/PHY/INIT/lte_init_ru.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach.c + + ) + +set(PHY_SRC_UE + # actual source + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/sss_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/uci_tools_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/pbch_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dci_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/phich_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/pcfich_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/pucch_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/prach_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/pmch_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/pch_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/slss.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/sldch.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/slsch.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/drs_modulation.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/ulsch_coding.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/rar_tools_ue.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/initial_sync.c + ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c + ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c + ${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz_ue.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_timefreq.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_est_freq_offset.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c + ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/adjust_gain.c + ${OPENAIR1_DIR}/PHY/INIT/lte_init_ue.c + ) + if (${SMBV}) set(PHY_SRC "${PHY_SRC} ${OPENAIR1_DIR}/PHY/TOOLS/smbv.c") endif (${SMBV}) if (${COMPILATION_AVX2} STREQUAL "True") - set(PHY_SRC ${PHY_SRC} ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c) + set(PHY_SRC_UE ${PHY_SRC_UE} ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c) endif () +add_library(PHY_COMMON ${PHY_SRC_COMMON}) add_library(PHY ${PHY_SRC}) +add_library(PHY_UE ${PHY_SRC_UE}) +add_library(PHY_RU ${PHY_SRC_RU}) #Layer 2 library ##################### @@ -1140,7 +1232,7 @@ set(RLC_DIR ${OPENAIR2_DIR}/LAYER2/RLC) set(RLC_UM_DIR ${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0) set(RLC_AM_DIR ${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0) set(RLC_TM_DIR ${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0) -set(RRC_DIR ${OPENAIR2_DIR}/RRC/LITE) +set(RRC_DIR ${OPENAIR2_DIR}/RRC/LTE) set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0) set(L2_SRC ${OPENAIR2_DIR}/LAYER2/openair2_proc.c @@ -1184,14 +1276,61 @@ set(L2_SRC ${RRC_DIR}/rrc_eNB_UE_context.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface.c + ${RRC_DIR}/L2_interface_common.c + ${RRC_DIR}/L2_interface_ue.c ) + +set(L2_SRC_UE + ${PDCP_DIR}/pdcp.c + ${PDCP_DIR}/pdcp_fifo.c + ${PDCP_DIR}/pdcp_sequence_manager.c + ${PDCP_DIR}/pdcp_primitives.c + ${PDCP_DIR}/pdcp_util.c + ${PDCP_DIR}/pdcp_security.c + ${PDCP_DIR}/pdcp_netlink.c + ${RLC_AM_DIR}/rlc_am.c + ${RLC_AM_DIR}/rlc_am_init.c + ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c + ${RLC_AM_DIR}/rlc_am_timer_reordering.c + ${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c + ${RLC_AM_DIR}/rlc_am_segment.c + ${RLC_AM_DIR}/rlc_am_segments_holes.c + ${RLC_AM_DIR}/rlc_am_in_sdu.c + ${RLC_AM_DIR}/rlc_am_receiver.c + ${RLC_AM_DIR}/rlc_am_retransmit.c + ${RLC_AM_DIR}/rlc_am_windows.c + ${RLC_AM_DIR}/rlc_am_rx_list.c + ${RLC_AM_DIR}/rlc_am_reassembly.c + ${RLC_AM_DIR}/rlc_am_status_report.c + ${RLC_TM_DIR}/rlc_tm.c + ${RLC_TM_DIR}/rlc_tm_init.c + ${RLC_UM_DIR}/rlc_um.c + ${RLC_UM_DIR}/rlc_um_fsm.c + ${RLC_UM_DIR}/rlc_um_control_primitives.c + ${RLC_UM_DIR}/rlc_um_segment.c + ${RLC_UM_DIR}/rlc_um_reassembly.c + ${RLC_UM_DIR}/rlc_um_receiver.c + ${RLC_UM_DIR}/rlc_um_dar.c + ${RLC_DIR}/rlc_mac.c + ${RLC_DIR}/rlc.c + ${RLC_DIR}/rlc_rrc.c + ${RLC_DIR}/rlc_mpls.c + ${RRC_DIR}/rrc_UE.c + ${RRC_DIR}/rrc_common.c + ${RRC_DIR}/L2_interface_common.c + ${RRC_DIR}/L2_interface_ue.c + ) + set (MAC_SRC + #${PHY_INTERFACE_DIR}/phy_stub_UE.c ${PHY_INTERFACE_DIR}/IF_Module.c ${MAC_DIR}/main.c - ${MAC_DIR}/ue_procedures.c - ${MAC_DIR}/ra_procedures.c + #${MAC_DIR}/main_ue.c + #${MAC_DIR}/ue_procedures.c + #${MAC_DIR}/ra_procedures.c ${MAC_DIR}/l1_helpers.c ${MAC_DIR}/rar_tools.c + #${MAC_DIR}/rar_tools_ue.c ${MAC_DIR}/eNB_scheduler.c ${MAC_DIR}/eNB_scheduler_dlsch.c ${MAC_DIR}/eNB_scheduler_ulsch.c @@ -1200,23 +1339,26 @@ set (MAC_SRC ${MAC_DIR}/eNB_scheduler_primitives.c ${MAC_DIR}/eNB_scheduler_RA.c ${MAC_DIR}/eNB_scheduler_fairRR.c + ${MAC_DIR}/eNB_scheduler_phytest.c ${MAC_DIR}/pre_processor.c ${MAC_DIR}/config.c + #${MAC_DIR}/config_ue.c ) -if (FLEXRAN_AGENT_SB_IF) - -set (MAC_SRC ${MAC_SRC} - ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue.c - ${MAC_DIR}/flexran_agent_scheduler_dataplane.c - ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue_remote.c -) - -endif() +set (MAC_SRC_UE + ${PHY_INTERFACE_DIR}/phy_stub_UE.c + ${MAC_DIR}/main_ue.c + ${MAC_DIR}/ue_procedures.c + ${MAC_DIR}/ra_procedures.c + ${MAC_DIR}/l1_helpers.c + ${MAC_DIR}/rar_tools_ue.c + ${MAC_DIR}/config_ue.c + ) set (ENB_APP_SRC ${OPENAIR2_DIR}/ENB_APP/enb_app.c ${OPENAIR2_DIR}/ENB_APP/enb_config.c + ${OPENAIR2_DIR}/ENB_APP/RRC_config_tools.c ) add_library(L2 @@ -1225,45 +1367,16 @@ add_library(L2 ${ENB_APP_SRC}) # ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) -include_directories(${NFAPI_USER_DIR}) - -if (FLEXRAN_AGENT_SB_IF) - -#Test for adding a shared library -add_library(default_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue.c) -add_library(remote_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue_remote.c) +add_library(L2_UE + ${L2_SRC_UE} + ${MAC_SRC_UE} +) -endif() +include_directories(${NFAPI_USER_DIR}) # L3 Libs ########################## -set(RAL_LTE_DIR ${OPENAIR3_DIR}/RAL-LTE/) -if (${ENABLE_RAL}) - set(RAL_LTE_SRC - ${RRC_DIR}/rrc_UE_ral.c - ${RRC_DIR}/rrc_eNB_ral.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_action.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_main.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_mih_msg.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_parameters.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_process.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_rrc_msg.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_subscribe.c - ${RAL_LTE_DIR}LTE_RAL_ENB/SRC/lteRALenb_thresholds.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_action.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_main.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_mih_msg.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_parameters.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_process.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_rrc_msg.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_subscribe.c - ${RAL_LTE_DIR}LTE_RAL_UE/SRC/lteRALue_thresholds.c - ) - add_library(RAL ${RAL_LTE_SRC}) - set(RAL_LIB RAL) -endif() - # CN libs ########################## @@ -1554,6 +1667,17 @@ if(NAS_UE) endif() +# nbiot +add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16") +set (NBIOT_SOURCES + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c +) +add_library(NB_IoT MODULE ${NBIOT_SOURCES} ) + +# shared library loader +set (SHLIB_LOADER_SOURCES + ${OPENAIR_DIR}/common/utils/load_module_shlib.c +) # Make lfds as a own source code (even if it is a outside library) # For better intergration with compilation flags & structure of cmake @@ -1599,8 +1723,8 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_channel.c -${OPENAIR1_DIR}/SIMULATION/TOOLS/abstraction.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_tv_channel.c +${OPENAIR1_DIR}/SIMULATION/TOOLS/abstraction.c ${OPENAIR1_DIR}/SIMULATION/RF/rf.c ${OPENAIR1_DIR}/SIMULATION/RF/dac.c ${OPENAIR1_DIR}/SIMULATION/RF/adc.c @@ -1626,6 +1750,7 @@ include_directories("${NFAPI_DIR}/nfapi/inc") include_directories("${NFAPI_DIR}/sim_common/inc") include_directories("${NFAPI_DIR}/pnf_sim/inc") + # System packages that are required # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ # or cmake provide a generic interface to pkg-config that widely used @@ -1708,6 +1833,16 @@ if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h") endif() list(APPEND ATLAS_LIBRARIES lapack) + +# for ubuntu 17.10, directories are different +elseif(EXISTS "/usr/include/x86_64-linux-gnu/cblas.h") + + include_directories("/usr/include/x86_64-linux-gnu") + LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") + list(APPEND ATLAS_LIBRARIES cblas) + list(APPEND ATLAS_LIBRARIES atlas) + list(APPEND ATLAS_LIBRARIES lapack) + else() message("No Blas/Atlas libs found, some targets will fail") endif() @@ -1771,15 +1906,16 @@ add_executable(lte-softmodem ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c @@ -1793,9 +1929,9 @@ add_executable(lte-softmodem target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB - NFAPI_USER_LIB + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) @@ -1810,17 +1946,18 @@ add_executable(lte-softmodem-nos1 ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c ${OPENAIR_DIR}/common/utils/system.c ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} @@ -1830,14 +1967,92 @@ add_executable(lte-softmodem-nos1 ) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - -Wl,--end-group ) + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + -Wl,--end-group z dl ) target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${T_LIB}) +# lte-uesoftmodem is UE implementation +####################################### + +add_executable(lte-uesoftmodem + ${rrc_h} + ${s1ap_h} + ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c + ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c + ${XFORMS_SOURCE} + ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ) + +target_link_libraries (lte-uesoftmodem + -Wl,--start-group + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + -Wl,--end-group z dl) + +target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES}) +target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem ${T_LIB}) + +# lte-uesoftmodem-nos1 is UE implementation +################################################### +add_executable(lte-uesoftmodem-nos1 + ${rrc_h} + ${s1ap_h} +# ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c + ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c + ${XFORMS_SOURCE} + ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ) + +target_link_libraries (lte-uesoftmodem-nos1 + -Wl,--start-group + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + -Wl,--end-group z dl ) + +target_link_libraries (lte-uesoftmodem-nos1 ${LIBXML2_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 ${T_LIB}) + # USIM process ################# #add_executable(usim @@ -1876,8 +2091,7 @@ add_executable(oaisim ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c - ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c - ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c +# ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c ${OPENAIR_TARGETS}/SIMU/USER/sinr_sim.c ${OPENAIR_TARGETS}/SIMU/USER/cor_SF_sim.c ${OPENAIR_TARGETS}/SIMU/USER/oaisim_functions.c @@ -1889,8 +2103,7 @@ add_executable(oaisim ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} - ${OPENAIR_TARGETS}/COMMON/create_tasks.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${XFORMS_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -1901,14 +2114,13 @@ add_executable(oaisim target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim -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 SECU_OSA ${ITTI_LIB} - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB - NFAPI_USER_LIB - -Wl,--end-group ) + RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE ${MSC_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} + ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + -Wl,--end-group z dl) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp z - ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} ) + ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim forms) target_link_libraries (oaisim ${T_LIB}) @@ -1923,11 +2135,10 @@ add_executable(oaisim_nos1 ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c - ${OPENAIR_TARGETS}/RT/USER/lte-enb.c + ${OPENAIR1_DIR}/SCHED/prach_procedures.c ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c - ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c - ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c +# ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c ${OPENAIR_TARGETS}/SIMU/USER/sinr_sim.c ${OPENAIR_TARGETS}/SIMU/USER/cor_SF_sim.c ${OPENAIR_TARGETS}/SIMU/USER/oaisim_functions.c @@ -1936,7 +2147,7 @@ add_executable(oaisim_nos1 ${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 + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_DIR}/common/utils/system.c ${XFORMS_SOURCE} ${T_SOURCE} @@ -1946,8 +2157,8 @@ add_executable(oaisim_nos1 target_include_directories(oaisim_nos1 PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim_nos1 -Wl,--start-group - RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} SIMU SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - -Wl,--end-group ) + RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS ${MSC_LIB} ${ITTI_LIB} SIMU L2_UE ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + -Wl,--end-group z dl ) target_link_libraries (oaisim_nos1 ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} @@ -1965,28 +2176,30 @@ target_link_libraries (oaisim_nos1 ${T_LIB}) #special case for dlim TM4, which uses its own version of phy_scope code add_executable(dlsim_tm4 - ${OPENAIR_BIN_DIR}/messages_xml.h +# ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/dlsim_tm4.c ${OPENAIR1_DIR}/PHY/TOOLS/lte_phy_scope_tm4.c ${T_SOURCE} ) target_link_libraries (dlsim_tm4 - -Wl,--start-group SIMU UTIL SCHED_LIB PHY LFDS ${ITTI_LIB} -Wl,--end-group + -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY LFDS ${ITTI_LIB} -Wl,--end-group pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} ) foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) add_executable(${myExe} - ${OPENAIR_BIN_DIR}/messages_xml.h +# ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c ${XFORMS_SOURCE} ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} ) target_link_libraries (${myExe} - -Wl,--start-group SIMU UTIL SCHED_LIB PHY LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} + -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group + pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) endforeach(myExe) @@ -1998,7 +2211,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR2_DIR}/COMMON/messages_def.h ${OPENAIR2_DIR}/COMMON/messages_types.h ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h - ${OPENAIR_BIN_DIR}/messages_xml.h +# ${OPENAIR_BIN_DIR}/messages_xml.h ) target_link_libraries (test_epc_generate_scenario -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} @@ -2022,7 +2235,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) @@ -2091,7 +2304,7 @@ endforeach() # castxml doesn't work with c11 (gcc 5 default) # force castxml and clang compilation with gnu89 standard # we can't use cXX standard as pthread_rwlock_t is gnu standard -list(APPEND itti_compiler_options "-std=gnu89") +list(APPEND itti_compiler_options "-std=gnu89;-D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'") set (ITTI_H ${ITTI_DIR}/intertask_interface_types.h) if(EXISTS /usr/bin/gccxml) set(xml_command gccxml ${itti_compiler_options} -fxml=${OPENAIR_BIN_DIR}/messages.xml ${ITTI_H}) @@ -2122,7 +2335,7 @@ add_custom_command ( # retrieve the compiler options to send it to gccxml get_directory_property(DirDefs COMPILE_DEFINITIONS ) foreach( d ${DirDefs} ) - set(module_cc_opt_tmp "${module_cc_opt_tmp} -D${d}") + set(module_cc_opt "${module_cc_opt} -D${d}") endforeach() get_directory_property( DirDefs INCLUDE_DIRECTORIES ) foreach( d ${DirDefs} ) @@ -2179,7 +2392,7 @@ list(APPEND oai_nw_drv_src device.c common.c ioctl.c classifier.c tool.c) if(OAI_NW_DRIVER_USE_NETLINK) list(APPEND oai_nw_drv_src netlink.c) endif() -make_driver(oai_nw_drv ${OPENAIR2_DIR}/NETWORK_DRIVER/LITE ${oai_nw_drv_src}) +make_driver(oai_nw_drv ${OPENAIR2_DIR}/NETWORK_DRIVER/LTE ${oai_nw_drv_src}) # Exmimo board drivers ######################### @@ -2232,3 +2445,8 @@ ADD_CUSTOM_TARGET(oarf DEPENDS ${OCT_FILES} ) +include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt) + + + + diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf index e09e068c63fed4af59d20935eae3fb6f9b0f5155..0994acdf9de168ddf746784ad837f23dcda68001 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf index 1f992daba20cdee1a33e1939db2686bb6bf95e0a..5e8cd8007ea7550c2838aac43ae21aad78b18c0d 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf index bb7df8b72d654171fb088bc8ddfe95d6b9b64883..53eae1d531f80bd133b6ba5060262fa452c5145e 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf index ff97827b579a4d97fe5b0a593b14247eb349c0fb..d30a57041c1818b9fb1abd96a9f630abfc10bac0 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf index ebb9e417e7be717f810692a4a5ac42e564cbc58a..e90eb3fe518c751e471632f30400026d9a0ce1e3 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf index 4e8910276639267344316f765e9f9f20f50e1a0c..5dbecd3813f90eabcd4568d2dc3c2116c6726d5c 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf index beaf5ae0f1405da2c8647f8970c7971b3a99a2a2..1397184cc7994da3aa3d41c6d977aa3d53998a5d 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf index b0efe66e14189d82f486524396309de98bd4e9fe..caebb36eb27af79b81f4d5e97775e308673f2045 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf index 1b33c7b3c216e7ef2e8573806db0176461ffa93f..fe90cdb338f1796733f554999c79ff71497d357e 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf index dc64a69c00cbf028ccbefc73e30b45096ed28851..5d9027ce150c8926b8bdedaf833b87cddc5536cf 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf index c93ce24d0841f73f64b3cf5f0ebbbb28a98c9818..539f0bd744cf91222e11f0a3467eaa3f8f319f25 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf index 57f7ef83b92e484d13eb4234982dc807ffafeccc..58b088002fb37a396183cc6a51ef455d2aee6862 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/connection.py b/cmake_targets/autotests/v2/connection.py index 1952b8b72f713ff2eb7cff44802b6b18fc138f63..3a254f89b8b0fe02dbbd43fecddbad5ea17ee087 100644 --- a/cmake_targets/autotests/v2/connection.py +++ b/cmake_targets/autotests/v2/connection.py @@ -13,7 +13,7 @@ class connection: try: (pid, fd) = os.forkpty() except BaseException, e: - log("ERROR: forkpty for '" + description + "': " + e) + log("ERROR: forkpty for '" + description + "': " + str(e)) (pid, fd) = (-1, -1) if pid == -1: @@ -26,7 +26,7 @@ class connection: os.execvp('sshpass', ['sshpass', '-p', password, 'ssh', user + '@' + host]) except BaseException, e: - log("ERROR: execvp for '" + description + "': " + e) + log("ERROR: execvp for '" + description + "': " + str(e)) log("ERROR: execvp failed for '" + description + "'") os._exit(1) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index a9ba2c56d165e2b402592c63167b9e5d53f64e4f..3c6f6b3327bd741689dd168eb418e1fb8d136572 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -42,7 +42,6 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf MSC_GEN="False" XFORMS="True" -FLEXRAN_AGENT_SB_IF="True" UE_EXPANSION="False" PRINT_STATS="False" VCD_TIMING="False" @@ -69,6 +68,8 @@ UE_TIMING_TRACE="False" DISABLE_LOG_X="False" USRP_REC_PLAY="False" BUILD_ECLIPSE=0 +UE_NAS_USE_TUN="False" +BASIC_SIMULATOR=0 trap handle_ctrl_c INT function print_help() { @@ -101,8 +102,6 @@ Options Specify conf_nvram_path (default \"$conf_nvram_path\") --UE-gen-nvram [output path] Specify gen_nvram_path (default \"$gen_nvram_path\") --a | --agent - Enables agent for software-defined control of the eNB -r | --3gpp-release default is Rel14, Rel8 limits the implementation to 3GPP Release 8 version @@ -160,6 +159,11 @@ Options Build eclipse project files. Paths are auto corrected by fixprj.sh --usrp-recplay Build for I/Q record-playback modes +--ue-nas-use-tun + Use TUN devices for the UEs instead of ue_ip.ko +--basic-simulator + Generates a basic [1 UE + 1 eNB + no channel] simulator. + See targets/ARCH/tcp_bridge/README.tcp_bridge_oai for documentation. Usage (first build): oaisim (eNB + UE): ./build_oai -I --oaisim -x --install-system-files Eurecom EXMIMO + COTS UE : ./build_oai -I --eNB -x --install-system-files @@ -205,8 +209,7 @@ function main() { echo_info "Will compile eNB" shift;; -a | --agent) - FLEXRAN_AGENT=1 - echo_info "Will compile eNB with agent support" + echo_info "FlexRAN support is always compiled into the eNB" shift;; --UE) UE=1 @@ -356,6 +359,14 @@ function main() { USRP_REC_PLAY="True" echo_info "Enabling USRP record playback mode" shift 1;; + --ue-nas-use-tun) + UE_NAS_USE_TUN="True" + echo_info "Enabling UE NAS TUN device usage instead of ue_ip.ko" + shift 1;; + --basic-simulator) + BASIC_SIMULATOR=1 + echo_info "Compiling the basic simulator" + shift 1;; -h | --help) print_help exit 1;; @@ -368,7 +379,11 @@ function main() { CMAKE_CMD="$CMAKE_CMD .." echo_info "CMAKE_CMD=$CMAKE_CMD" - + if [ "$eNB" = "1" ] && [ "$UE" = "1" ]; then + echo_error "Cannot build UE and eNB on one build_oai execution" + echo_error "use 2 build_oai invocations" + exit + fi ######################################################### # check validity of HW and TP parameters for eNB ######################################################### @@ -470,11 +485,9 @@ function main() { flash_firmware_bladerf fi fi - if [ "$FLEXRAN_AGENT" == "1" ] ; then - echo_info "installing protobuf/protobuf-c for flexran agent support" - install_protobuf_from_source - install_protobuf_c_from_source - fi + echo_info "installing protobuf/protobuf-c for flexran agent support" + install_protobuf_from_source + install_protobuf_c_from_source fi if [ "$INSTALL_OPTIONAL" = "1" ] ; then @@ -499,10 +512,20 @@ function main() { DIR=$OPENAIR_DIR/cmake_targets if [ "$NOS1" = "1" ] ; then lte_build_dir=lte_noS1_build_oai - lte_exec=lte-softmodem-nos1 + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem-nos1 + fi + if [ "$UE" = "1" ] ; then + lte_exec=lte-uesoftmodem-nos1 + fi else lte_build_dir=lte_build_oai - lte_exec=lte-softmodem + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem + fi + if [ "$UE" = "1" ] ; then + lte_exec=lte-uesoftmodem + fi fi # configuration module libraries, one currently available, using libconfig @@ -522,9 +545,6 @@ function main() { echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file echo "set ( XFORMS $XFORMS )" >> $cmake_file - if [ "$FLEXRAN_AGENT" = "1" ] ; then - echo "set ( FLEXRAN_AGENT_SB_IF $FLEXRAN_AGENT_SB_IF )" >> $cmake_file - fi echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file echo "set ( PHY_TX_THREAD $UE_EXPANSION )" >> $cmake_file echo "set ( PRE_SCD_THREAD $UE_EXPANSION )" >> $cmake_file @@ -561,6 +581,9 @@ function main() { compilations \ $lte_build_dir $config_libconfig_shlib \ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so + compilations \ + $lte_build_dir coding \ + libcoding.so $dbin/libcoding.so if [ "$NOS1" = "1" ] ; then compilations \ @@ -626,12 +649,17 @@ function main() { if [ "$SIMUS_PHY" = "1" ] ; then # lte unitary simulators compilation echo_info "Compiling unitary tests simulators" - simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" + # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim + #simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" + simlist="dlsim ulsim" for f in $simlist ; do compilations \ lte-simulators $f \ $f $dbin/$f.$REL done + compilations \ + lte-simulators coding \ + libcoding.so $dbin/libcoding.so fi # Core simulators @@ -687,9 +715,6 @@ function main() { echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file echo "set ( XFORMS $XFORMS )" >> $cmake_file - if [ "$FLEXRAN_AGENT" = "1" ] ; then - echo "set ( FLEXRAN_AGENT_SB_IF $FLEXRAN_AGENT_SB_IF )" >> $cmake_file - fi echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file echo "set ( PHY_TX_THREAD $UE_EXPANSION )" >> $cmake_file echo "set ( PRE_SCD_THREAD $UE_EXPANSION )" >> $cmake_file @@ -697,6 +722,7 @@ function main() { echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set ( T_TRACER $T_TRACER )" >> $cmake_file + echo "set ( UE_NAS_USE_TUN $UE_NAS_USE_TUN )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file [ "$CLEAN" = "1" ] && rm -rf $DIR/$oaisim_build_dir/build mkdir -p $DIR/$oaisim_build_dir/build @@ -705,6 +731,12 @@ function main() { compilations \ $oaisim_build_dir $oaisim_exec \ $oaisim_exec $dbin/$oaisim_exec.$REL + compilations \ + $oaisim_build_dir $config_libconfig_shlib \ + lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so + compilations \ + $oaisim_build_dir coding \ + libcoding.so $dbin/libcoding.so if [ "$NOS1" != "1" ] ; then @@ -773,9 +805,6 @@ function main() { cp $DIR/oaisim_mme_build_oai/CMakeLists.template $cmake_file echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( XFORMS $XFORMS )" >> $cmake_file - if [ "$FLEXRAN_AGENT" = "1" ] ; then - echo "set ( FLEXRAN_AGENT_SB_IF $FLEXRAN_AGENT_SB_IF )" >> $cmake_file - fi echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file echo "set ( PHY_TX_THREAD $UE_EXPANSION )" >> $cmake_file echo "set ( PRE_SCD_THREAD $UE_EXPANSION )" >> $cmake_file @@ -795,17 +824,10 @@ function main() { # Telnet server compilation ##################### if [ "$BUILD_TELNETSRV" = "1" ] ; then - - telnetsrv_build_dir=telnetsrv - mkdir -p $DIR/$telnetsrv_build_dir/build - cd $DIR/$telnetsrv_build_dir/build - echo_info "Compiling telnet server library ..." - - [ "$CLEAN" = "1" ] && rm -rf $DIR/$telnetsrv_build_dir - cmake_file=$OPENAIR_DIR/common/utils/$telnetsrv_build_dir/CMakeLists.txt - cd $DIR/$telnetsrv_build_dir/build - eval "$CMAKE_CMD $OPENAIR_DIR/common/utils/$telnetsrv_build_dir/" - make + build_dir=$lte_build_dir + compilations \ + $build_dir telnetsrv \ + libtelnetsrv.so $dbin/libtelnetsrv.so fi # build RF device and transport protocol libraries @@ -919,6 +941,122 @@ fi else echo_info "10. Bypassing the Tests ..." fi + + # basic simulator + ##################### + if [ "$BASIC_SIMULATOR" = "1" ]; then + echo_info "Build basic simulator" + [ "$CLEAN" = "1" ] && rm -rf $OPENAIR_DIR/cmake_targets/basic_simulator + [ "$CLEAN" = "1" ] && rm -rf $OPENAIR_DIR/cmake_targets/nas_sim_tools/build + mkdir -p $OPENAIR_DIR/cmake_targets/basic_simulator + mkdir -p $OPENAIR_DIR/cmake_targets/basic_simulator/enb + mkdir -p $OPENAIR_DIR/cmake_targets/basic_simulator/ue + mkdir -p $OPENAIR_DIR/cmake_targets/nas_sim_tools/build + + # enb + + cmake_file=$OPENAIR_DIR/cmake_targets/basic_simulator/enb/CMakeLists.txt + echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file + echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file + echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file + echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file + echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file + echo "set ( XFORMS $XFORMS )" >> $cmake_file + echo "set ( RF_BOARD \"OAI_USRP\")" >> $cmake_file + echo "set ( TRANSP_PRO \"None\")" >> $cmake_file + echo "set(PACKAGE_NAME \"simulator_enb\")" >> $cmake_file + echo "set (DEADLINE_SCHEDULER \"False\" )" >> $cmake_file + echo "set (CPU_AFFINITY \"False\" )" >> $cmake_file + echo "set ( T_TRACER \"True\" )" >> $cmake_file + echo "set (UE_AUTOTEST_TRACE $UE_AUTOTEST_TRACE)" >> $cmake_file + echo "set (UE_DEBUG_TRACE $UE_DEBUG_TRACE)" >> $cmake_file + echo "set (UE_TIMING_TRACE $UE_TIMING_TRACE)" >> $cmake_file + echo "set (DISABLE_LOG_X $DISABLE_LOG_X)" >> $cmake_file + echo "set (USRP_REC_PLAY $USRP_REC_PLAY)" >> $cmake_file + echo "set (BASIC_SIMULATOR \"True\" )" >> $cmake_file + echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt)' >> $cmake_file + + echo_info "Build eNB" + echo_info "logs are in $dlog/basic_simulator_enb.txt" + set +e + { + cd $OPENAIR_DIR/cmake_targets/basic_simulator/enb + cmake . + make -j`nproc` coding params_libconfig tcp_bridge_oai lte-softmodem + ln -sf libtcp_bridge_oai.so liboai_device.so + cd ../.. + } > $dlog/basic_simulator_enb.txt 2>&1 + set -e + if [ -s $OPENAIR_DIR/cmake_targets/basic_simulator/enb/lte-softmodem -a \ + -s $OPENAIR_DIR/cmake_targets/basic_simulator/enb/libcoding.so -a \ + -s $OPENAIR_DIR/cmake_targets/basic_simulator/enb/libparams_libconfig.so -a \ + -s $OPENAIR_DIR/cmake_targets/basic_simulator/enb/libtcp_bridge_oai.so ] ; then + echo_success "eNB compiled" + check_warnings "$dlog/basic_simulator_enb.txt" + else + echo_error "eNB compilation failed" + exit 1 + fi + + # ue + + echo_info "Compile conf2uedata" + cd $OPENAIR_DIR/cmake_targets/nas_sim_tools/build + eval $CMAKE_CMD + compilations \ + nas_sim_tools conf2uedata \ + conf2uedata $dbin/conf2uedata + + cmake_file=$OPENAIR_DIR/cmake_targets/basic_simulator/ue/CMakeLists.txt + echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file + echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file + echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file + echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file + echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file + echo "set ( XFORMS $XFORMS )" >> $cmake_file + echo "set ( RF_BOARD \"OAI_USRP\")" >> $cmake_file + echo "set ( TRANSP_PRO \"None\")" >> $cmake_file + echo "set(PACKAGE_NAME \"simulator_ue\")" >> $cmake_file + echo "set (DEADLINE_SCHEDULER \"False\" )" >> $cmake_file + echo "set (CPU_AFFINITY \"False\" )" >> $cmake_file + echo "set ( T_TRACER \"False\" )" >> $cmake_file + echo "set (UE_AUTOTEST_TRACE $UE_AUTOTEST_TRACE)" >> $cmake_file + echo "set (UE_DEBUG_TRACE $UE_DEBUG_TRACE)" >> $cmake_file + echo "set (UE_TIMING_TRACE $UE_TIMING_TRACE)" >> $cmake_file + echo "set (DISABLE_LOG_X $DISABLE_LOG_X)" >> $cmake_file + echo "set (USRP_REC_PLAY $USRP_REC_PLAY)" >> $cmake_file + echo "set (LINUX True )" >> $cmake_file + echo "set (PDCP_USE_NETLINK True )" >> $cmake_file + echo "set (BASIC_SIMULATOR \"True\" )" >> $cmake_file + echo "set (UE_NAS_USE_TUN \"True\" )" >> $cmake_file + echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt)' >> $cmake_file + + echo_info "Build UE" + echo_info "logs are in $dlog/basic_simulator_ue.txt" + set +e + { + cd $OPENAIR_DIR/cmake_targets/basic_simulator/ue + cmake . + make -j`nproc` coding params_libconfig tcp_bridge_oai lte-uesoftmodem + ln -sf libtcp_bridge_oai.so liboai_device.so + cd ../.. + } > $dlog/basic_simulator_ue.txt 2>&1 + set -e + if [ -s $OPENAIR_DIR/cmake_targets/basic_simulator/ue/lte-uesoftmodem -a \ + -s $OPENAIR_DIR/cmake_targets/basic_simulator/ue/libcoding.so -a \ + -s $OPENAIR_DIR/cmake_targets/basic_simulator/ue/libparams_libconfig.so -a \ + -s $OPENAIR_DIR/cmake_targets/basic_simulator/ue/libtcp_bridge_oai.so ] ; then + echo_success "UE compiled" + check_warnings "$dlog/basic_simulator_ue.txt" + else + echo_error "UE compilation failed" + exit 1 + fi + + echo_info "Generate UE SIM data" + $OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o $OPENAIR_DIR/cmake_targets/basic_simulator/ue + + fi } main "$@" diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index ca754449d7f9c6bbea10e1dcf726160df18a9f97..b7e83a92a03282f9dfae9b54633a8ea745763cee 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -8,5 +8,5 @@ set(DEBUG_PHY False) set(MU_RECIEVER False) set(NAS_UE False) set(MESSAGE_CHART_GENERATOR False) - +set(RRC_ASN1_VERSION "Rel14") include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt) diff --git a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template index e0f100ca0af9128c153a5748ea0cb1280b16bc26..bc416cff55fef58c4a19492585c07addd4f60115 100644 --- a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template +++ b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template @@ -30,7 +30,7 @@ set ( MESSAGE_CHART_GENERATOR_RLC_MAC False ) set ( MESSAGE_CHART_GENERATOR_PHY False ) set ( MSG_PRINT False ) set ( MU_RECEIVER False ) -set ( NAS_ADDRESS_FIX True ) +set ( NAS_ADDRESS_FIX False ) set ( NAS_BUILT_IN_UE False) set ( NAS_MME False ) set ( NAS_UE False ) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 1ea97c030f2b07169c0009920e55be800c7da3c1..722db38ffc947ca71e2cbc56e839b90567cd74c3 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -95,6 +95,7 @@ get_distribution_release() { check_supported_distribution() { local distribution=$(get_distribution_release) case "$distribution" in + "ubuntu18.04") return 0 ;; "ubuntu17.10") return 0 ;; "ubuntu17.04") return 0 ;; "ubuntu16.04") return 0 ;; @@ -210,7 +211,7 @@ install_protobuf_from_source(){ #cd protobuf-2.6.1/ rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz - tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $USER --no-same-owner + tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $(groups | cut -d" " -f1) --no-same-owner cd protobuf-3.3.0/ ./configure echo "Compiling protobuf" @@ -249,14 +250,14 @@ install_usrp_uhd_driver_from_source(){ cd /tmp echo "Downloading UHD driver" rm -rf /tmp/uhd - git clone git://github.com/EttusResearch/uhd.git + git clone https://github.com/EttusResearch/uhd.git cd uhd git checkout tags/release_003_010_001_001 mkdir -p host/build cd host/build $CMAKE ../ echo "Compiling UHD" - make + make -j`nproc` make test $SUDO make install $SUDO ldconfig @@ -267,7 +268,7 @@ check_install_usrp_uhd_driver(){ if [[ "$OS_DISTRO" == "ubuntu" ]]; then #first we remove old installation $SUDO apt-get remove -y uhd || true - $SUDO apt-get remove libuhd-dev libuhd003 uhd-host -y + $SUDO apt-get remove libuhd-dev libuhd003 uhd-host -y || true v=$(lsb_release -cs) $SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main" #The new USRP repository @@ -277,10 +278,11 @@ check_install_usrp_uhd_driver(){ $SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake + $SUDO pip install requests if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source $SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware - install_ursp_uhd_driver_from_source + install_usrp_uhd_driver_from_source else $SUDO $INSTALLER -y install uhd uhd-devel uhd-firmware fi @@ -487,19 +489,24 @@ check_install_oai_software() { $SUDO apt install -y software-properties-common case "$(get_distribution_release)" in "ubuntu14.04") - specific_packages="libtasn1-3-dev gccxml libgnutls-dev libatlas-dev" + specific_packages="libtasn1-3-dev gccxml libgnutls-dev libatlas-dev iproute libconfig8-dev" # For iperf3 $SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe" $SUDO apt-get update ;; "ubuntu16.04") - specific_packages="libtasn1-6-dev gccxml libgnutls-dev libatlas-dev" + specific_packages="libtasn1-6-dev gccxml libgnutls-dev libatlas-dev iproute libconfig8-dev" ;; "ubuntu17.04") - specific_packages="libtasn1-6-dev castxml libgnutls28-dev libatlas-dev" + specific_packages="libtasn1-6-dev castxml libgnutls28-dev libatlas-dev iproute libconfig8-dev" ;; "ubuntu17.10") - specific_packages="libtasn1-6-dev castxml libgnutls28-dev" + specific_packages="libtasn1-6-dev castxml libgnutls28-dev iproute libconfig8-dev" + LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" + LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + ;; + "ubuntu18.04") + specific_packages="libtasn1-6-dev castxml libgnutls28-dev iproute2 libconfig-dev" LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" ;; @@ -523,12 +530,10 @@ check_install_oai_software() { gtkwave \ guile-2.0-dev \ iperf \ - iproute \ iptables \ iptables-dev \ libatlas-base-dev \ libblas-dev \ - libconfig8-dev \ libffi-dev \ libforms-bin \ libforms-dev \ @@ -644,7 +649,8 @@ check_install_oai_software() { lapack \ lapack-devel \ blas \ - blas-devel + blas-devel \ + libyaml-devel fi install_asn1c_from_source diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1 index 5cdab5ffd8cae3b43bb41b6908924de5ec04985b..fe819c27162df2174c27cc2cc93aa250b00c3bd1 100755 --- a/cmake_targets/tools/fix_asn1 +++ b/cmake_targets/tools/fix_asn1 @@ -5,6 +5,7 @@ RRC_Rel14=( "SystemInformation-r8-IEs.h" 4df485c5ddf2540eca271876cdc512caa19b0890 "fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff" + "SystemInformation-NB-r13-IEs.h" 6d91332d5c39205819b06e5e36efe62ff8e5b33b "fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff" ) RRC_Rel10=( diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff new file mode 100644 index 0000000000000000000000000000000000000000..37ac4cd85855c7436de8d1ab89a25e7041b3c9c6 --- /dev/null +++ b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff @@ -0,0 +1,47 @@ +48a49,70 +> struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member { +> SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present; +> union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u { +> SystemInformationBlockType2_NB_r13_t sib2_r13; +> SystemInformationBlockType3_NB_r13_t sib3_r13; +> SystemInformationBlockType4_NB_r13_t sib4_r13; +> SystemInformationBlockType5_NB_r13_t sib5_r13; +> SystemInformationBlockType14_NB_r13_t sib14_r13; +> SystemInformationBlockType16_NB_r13_t sib16_r13; +> /* +> * This type is extensible, +> * possible extensions are below. +> */ +> SystemInformationBlockType15_NB_r14_t sib15_v1430; +> SystemInformationBlockType20_NB_r14_t sib20_v1430; +> SystemInformationBlockType22_NB_r14_t sib22_v1430; +> } choice; +> +> /* Context for parsing across buffer boundaries */ +> asn_struct_ctx_t _asn_ctx; +> }; +> +52,72c74 +< A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member { +< SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present; +< union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u { +< SystemInformationBlockType2_NB_r13_t sib2_r13; +< SystemInformationBlockType3_NB_r13_t sib3_r13; +< SystemInformationBlockType4_NB_r13_t sib4_r13; +< SystemInformationBlockType5_NB_r13_t sib5_r13; +< SystemInformationBlockType14_NB_r13_t sib14_r13; +< SystemInformationBlockType16_NB_r13_t sib16_r13; +< /* +< * This type is extensible, +< * possible extensions are below. +< */ +< SystemInformationBlockType15_NB_r14_t sib15_v1430; +< SystemInformationBlockType20_NB_r14_t sib20_v1430; +< SystemInformationBlockType22_NB_r14_t sib22_v1430; +< } choice; +< +< /* Context for parsing across buffer boundaries */ +< asn_struct_ctx_t _asn_ctx; +< } ) list; +--- +> A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member) list; diff --git a/cmake_targets/tools/init_nas_nos1 b/cmake_targets/tools/init_nas_nos1 index 9bcaa0afb5bd8d0961315443620aa7d643374df8..f7347e55083c19c85e7a51f5b159a389808d2afa 100755 --- a/cmake_targets/tools/init_nas_nos1 +++ b/cmake_targets/tools/init_nas_nos1 @@ -44,11 +44,11 @@ load_module $OPENAIR_DIR/targets/bin/nasmesh.ko if [ "$1" = "eNB" ]; then echo "bring up oai0 interface for enb" sudo ifconfig oai0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255 - $OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.1 -t 10.0.1.9 -r 1 + $OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.1 -t 10.0.1.2 -r 1 else if [ "$1" = "UE" ]; then echo "bring up oai0 interface for UE" sudo ifconfig oai0 10.0.1.9 netmask 255.255.255.0 broadcast 10.0.1.255 - $OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.9 -t 10.0.1.1 -r 1 + $OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.2 -t 10.0.1.1 -r 1 fi fi diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index cb24cc52222f3a4fed6af979b61882a4db234c39..040cd92fafaad3f799a9e2ac5baa212daf67e355 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index ff66d22a1c847bd783ccd43211709b1e5bf741c1..7860742804ea72b9a0e1b5d387f3a15af485ed4f 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -197,25 +197,40 @@ int i; return cfgptr; } -void end_configmodule() + +/* free memory allocated when reading parameters */ +/* config module could be initialized again after this call */ +void end_configmodule(void) { if (cfgptr != NULL) { if (cfgptr->end != NULL) { printf ("[CONFIG] calling config module end function...\n"); cfgptr->end(); } - if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); - printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); - for (int i=0; i<cfgptr->num_cfgP; i++) { - if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); - } + printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); for(int i=0; i<cfgptr->numptrs ; i++) { if (cfgptr->ptrs[i] != NULL) { free(cfgptr->ptrs[i]); + cfgptr->ptrs[i]=NULL; } - cfgptr->ptrs[i]=NULL; } + cfgptr->numptrs=0; + } +} + +/* free all memory used by config module */ +/* should be called only at program exit */ +void free_configmodule(void) +{ + if (cfgptr != NULL) { + end_configmodule(); + if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); + printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); + for (int i=0; i<cfgptr->num_cfgP; i++) { + if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); + } + free(cfgptr); cfgptr=NULL; diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index 76f074cd6c38cf805938f28567237368b2d8e253..724cd1dbf528f5e38e865d05d94d1b050a006e84 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -40,15 +40,18 @@ #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2... #define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module -/* rtflags bit position definitions */ -#define CONFIG_PRINTPARAMS 1 // print parameters values while processing -#define CONFIG_DEBUGPTR 2 // print memory allocation/free debug messages -#define CONFIG_DEBUGCMDLINE 4 // print command line processing messages -#define CONFIG_HELP 8 // print help message -#define CONFIG_ABORT 16 // config failed,abort execution -#define CONFIG_NOOOPT 32 // no -O option found when parsing command line - +/* default values for configuration module parameters */ +#define DEFAULT_CFGMODE "libconfig" // use libconfig file +#define DEFAULT_CFGFILENAME "oai.conf" // default config file +/* rtflags bit position definitions */ +#define CONFIG_PRINTPARAMS 1 // print parameters values while processing +#define CONFIG_DEBUGPTR 1<<1 // print memory allocation/free debug messages +#define CONFIG_DEBUGCMDLINE 1<<2 // print command line processing messages +#define CONFIG_NOABORTONCHKF 1<<3 // disable abort execution when parameter checking function fails +#define CONFIG_HELP 1<<20 // print help message +#define CONFIG_ABORT 1<<21 // config failed,abort execution +#define CONFIG_NOOOPT 1<<22 // no -O option found when parsing command line typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP); typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix); typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix); diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index a7de5e3098ffabc47226eb8c04ab0381b3593af8..6f153535fb56c2cf0ef5c8cb7599899195604abc 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -55,16 +55,61 @@ #define PARAMFLAG_PARAMSET (1 << 16) // parameter has been explicitely set in get functions #define PARAMFLAG_PARAMSETDEF (1 << 17) // parameter has been set to default value in get functions + +/* checkedparam_t is possibly used in paramdef_t for specific parameter value validation */ +#define CONFIG_MAX_NUMCHECKVAL 20 +typedef struct paramdef paramdef_t; +typedef union checkedparam { + struct { + int (*f1)(paramdef_t *param); /* check an integer against a list of authorized values */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1; + struct { + int (*f1a)(paramdef_t *param); /* check an integer against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values in config file */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1a; + struct { + int (*f2)(paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */ + int okintrange[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store min and max values */ + + } s2; + struct { + int (*f3)(paramdef_t *param); /* check a string against a list of authorized values */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3; + struct { + int (*f3a)(paramdef_t *param); /* check a string against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3a; + struct { + int (*f4)(paramdef_t *param); /* generic check function, no arguments but the param description */ + + } s4; + struct { + void (*checkfunc)(void) ; + } s5; +} checkedparam_t; + +/* paramdef is used to describe a parameter, array of paramdef_t strustures is used as the main parameter in */ +/* config apis used to retrieve parameters values */ typedef struct paramdef { - char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ - char *helpstr; /* help string */ - unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ - union { /* pointer to the parameter value, completed by the config module */ + char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ + char *helpstr; /* help string */ + unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ + union { /* pointer to the parameter value, completed by the config module */ char **strptr; char **strlistptr; uint8_t *u8ptr; - char *i8ptr; + int8_t *i8ptr; uint16_t *u16ptr; int16_t *i16ptr; uint32_t *uptr; @@ -72,18 +117,21 @@ typedef struct paramdef uint64_t *u64ptr; int64_t *i64ptr; double *dblptr; + void *voidptr; } ; union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */ - char *defstrval; - char **defstrlistval; - uint32_t defuintval; - int defintval; - uint64_t defint64val; - int *defintarrayval; - double defdblval; + char *defstrval; + char **defstrlistval; + uint32_t defuintval; + int defintval; + uint64_t defint64val; + int *defintarrayval; + double defdblval; } ; char type; /* parameter value type, as listed below as TYPE_XXXX macro */ int numelt; /* number of elements in a list or array parameters or max size of string value */ + checkedparam_t *chkPptr; /* possible pointer to the structure containing the info used to check parameter values */ + int *processedvalue; /* used to store integer values computed from string original value */ } paramdef_t; #define TYPE_INT TYPE_INT32 diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index acee5646cd7aae319f6fccef056a309e306d8fde..c1acc84384a0d91045c8b2e95f66ac98bd16ca68 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -36,6 +36,7 @@ #include <errno.h> #include <dlfcn.h> #include "config_userapi.h" +extern void exit_fun(const char* s); // lte-softmodem clean exit function configmodule_interface_t *config_get_if(void) @@ -59,7 +60,7 @@ char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) *ptr = malloc(length); if ( *ptr != NULL) { memset(*ptr,0,length); - if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) != 0) { + if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { config_get_if()->ptrs[config_get_if()->numptrs] = *ptr; config_get_if()->numptrs++; } @@ -111,7 +112,29 @@ int tmpval=val; break; } } +void config_assign_processedint(paramdef_t *cfgoption, int val) { + cfgoption->processedvalue = malloc(sizeof(int)); + if ( cfgoption->processedvalue != NULL) { + *(cfgoption->processedvalue) = val; + } else { + fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__); + exit(-1); + } +} +int config_get_processedint(paramdef_t *cfgoption) { + int ret; + if ( cfgoption->processedvalue != NULL) { + ret=*(cfgoption->processedvalue); + free( cfgoption->processedvalue); + cfgoption->processedvalue=NULL; + printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret); + } else { + fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname); + ret=0; + } +return ret; +} void config_printhelp(paramdef_t *params,int numparams) { for (int i=0 ; i<numparams ; i++) { @@ -124,11 +147,31 @@ void config_printhelp(paramdef_t *params,int numparams) } } +int config_execcheck(paramdef_t *params,int numparams, char *prefix) +{ +int st=0; + + for (int i=0 ; i<numparams ; i++) { + if ( params[i].chkPptr == NULL) { + continue; + } + if (params[i].chkPptr->s4.f4 != NULL) { + st += params[i].chkPptr->s4.f4(&(params[i])); + } + } + if (st != 0) { + fprintf(stderr,"[CONFIG] config_execcheck: %i parameters with wrong value\n", -st); + if ( CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) == 0) { + exit_fun("exit because configuration failed\n"); + } + } +return st; +} + int config_get(paramdef_t *params,int numparams, char *prefix) { int ret= -1; -printf("numparams:%d prefix:%s\n", numparams, prefix); if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); return ret; @@ -138,6 +181,7 @@ configmodule_interface_t *cfgif = config_get_if(); ret = config_get_if()->get(params, numparams,prefix); if (ret >= 0) { config_process_cmdline(params,numparams,prefix); + config_execcheck(params,numparams,prefix); } return ret; } @@ -153,6 +197,89 @@ int config_isparamset(paramdef_t *params,int paramidx) } } -int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx) { +void print_intvalueerror(paramdef_t *param, char *fname, int *okval, int numokval) { + fprintf(stderr,"[CONFIG] %s: %s: %i invalid value, authorized values:\n ", + fname,param->optname, (int)*(param->uptr)); + for ( int i=0; i<numokval ; i++) { + fprintf(stderr, " %i",okval[i]); + } + fprintf(stderr, " \n"); +} + +int config_check_intval(paramdef_t *param) +{ + if ( param == NULL ){ + fprintf(stderr,"[CONFIG] config_check_intval: NULL param argument\n"); + return -1; + } + for ( int i=0; i<param->chkPptr->s1.num_okintval ; i++) { + if( *(param->uptr) == param->chkPptr->s1.okintval[i] ) { + return 0; + } + } + print_intvalueerror(param,"config_check_intval", param->chkPptr->s1.okintval,param->chkPptr->s1.num_okintval); + return -1; +} + +int config_check_modify_integer(paramdef_t *param) +{ + + for (int i=0; i < param->chkPptr->s1a.num_okintval ; i++) { + if (*(param->uptr) == param->chkPptr->s1a.okintval[i] ) { + printf_params("[CONFIG] %s: read value %i, set to %i\n",param->optname,*(param->uptr),param->chkPptr->s1a.setintval [i]); + *(param->uptr) = param->chkPptr->s1a.setintval [i]; + return 0; + } + } + print_intvalueerror(param,"config_check_modify_integer", param->chkPptr->s1a.okintval,param->chkPptr->s1a.num_okintval); + return -1; +} + +int config_check_intrange(paramdef_t *param) +{ + if( *(param->iptr) >= param->chkPptr->s2.okintrange[0] && *(param->iptr) <= param->chkPptr->s2.okintrange[1] ) { + return 0; + } + fprintf(stderr,"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n", + param->optname, (int)*(param->uptr), param->chkPptr->s2.okintrange[0], param->chkPptr->s2.okintrange[1]); + return -1; +} + +void print_strvalueerror(paramdef_t *param, char *fname, char **okval, int numokval) { + fprintf(stderr,"[CONFIG] %s: %s: %s invalid value, authorized values:\n ", + fname,param->optname, *(param->strptr)); + for ( int i=0; i<numokval ; i++) { + fprintf(stderr, " %s",okval[i]); + } + fprintf(stderr, " \n"); +} + +int config_check_strval(paramdef_t *param) +{ + if ( param == NULL ){ + fprintf(stderr,"[CONFIG] config_check_strval: NULL param argument\n"); + return -1; + } + for ( int i=0; i<param->chkPptr->s3.num_okstrval ; i++) { + if( strcasecmp(*(param->strptr),param->chkPptr->s3.okstrval[i] ) == 0) { + return 0; + } + } + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3.okstrval, param->chkPptr->s3.num_okstrval); + return -1; +} + +int config_checkstr_assign_integer(paramdef_t *param) +{ + + + for (int i=0; i < param->chkPptr->s3a.num_okstrval ; i++) { + if (strcasecmp(*(param->strptr),param->chkPptr->s3a.okstrval[i] ) == 0) { + config_assign_processedint(param, param->chkPptr->s3a.setintval[i]); + return 0; + } + } + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3a.okstrval, param->chkPptr->s3a.num_okstrval); + return -1; } diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 5bbc20a950bfb2150a6bfb0945821a08008dab41..923a690f51986fdd0772e10480440e6cb68892fe 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -38,24 +38,34 @@ extern "C" { #endif -#define DEFAULT_CFGFILENAME "oaisoftmodem.conf" -#define DEFAULT_CFGMODE "libconfig" - #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) #define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] ) #define CONFIG_ISFLAGSET(P) ( (config_get_if()==NULL) ? 0 : !!(config_get_if()->rtflags & P)) - +#define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) +/* utility functions, to be used by configuration module and/or configuration libraries */ extern configmodule_interface_t *config_get_if(void); extern char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; extern void config_printhelp(paramdef_t *,int numparams); extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix); -extern int config_get(paramdef_t *params,int numparams, char *prefix); -extern int config_isparamset(paramdef_t *params,int paramidx); +extern void config_assign_processedint(paramdef_t *cfgoption, int val); extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val); -extern int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix); -extern int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx); + +/* apis to get parameters, to be used by oai modules, at configuration time */ +extern int config_get(paramdef_t *params,int numparams, char *prefix); #define config_getlist config_get_if()->getlist + +/* apis to retrieve parameters info after calling get or getlist functions */ +extern int config_isparamset(paramdef_t *params,int paramidx); +extern int config_get_processedint(paramdef_t *cfgoption); + +/* functions to be used in parameters definition, to check parameters values */ +extern int config_check_intval(paramdef_t *param); +extern int config_check_modify_integer(paramdef_t *param); +extern int config_check_intrange(paramdef_t *param); +extern int config_check_strval(paramdef_t *param); +extern int config_checkstr_assign_integer(paramdef_t *param); + #define CONFIG_GETCONFFILE (config_get_if()->cfgP[0]) #ifdef __cplusplus diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index 00f5f38b8fba60a042b42ebde78f78e6e87c886e..cfb0a214cfac14c337f894d67a5f64427d0f685e 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -1,3 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 common/config/libconfig/config_libconfig.c + * \brief: implementation libconfig configuration library + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ #define _GNU_SOURCE #include <libconfig.h> @@ -21,21 +51,23 @@ int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath { const char *str; int st; +int numelt; - cfgoptions->numelt=config_setting_length(setting); - cfgoptions->strlistptr=malloc(sizeof(char *) * (cfgoptions->numelt)); + numelt=config_setting_length(setting); + config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt); st=0; - for (int i=0; i< cfgoptions->numelt && cfgoptions->strlistptr != NULL; i++) { + for (int i=0; i< numelt ; i++) { str=config_setting_get_string_elem(setting,i); if (str==NULL) { printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i); } else { - cfgoptions->strlistptr[i]=malloc(strlen(str)+1); + config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1); sprintf(cfgoptions->strlistptr[i],"%s",str); st++; printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]); } } + cfgoptions->numelt=numelt; return st; } @@ -98,6 +130,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) { case TYPE_STRING: +printf("call config_lookup_string for '%s' %p\n", cfgpath, &(libconfig_privdata.cfg)); fflush(stdout); if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) { if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) { fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n", @@ -108,10 +141,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1); sprintf( *(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) ); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) ); } else { sprintf( (char *)(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: %s\n", cfgpath,(char *)cfgoptions[i].strptr ); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr ); } } else { if( cfgoptions[i].defstrval != NULL) { @@ -121,10 +154,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1); sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); - printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr)); + printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, *(cfgoptions[i].strptr)); } else { - sprintf((char *)(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); - printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, (char *)cfgoptions[i].strptr); + sprintf((char *)*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); + printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, (char *)*(cfgoptions[i].strptr)); } } else { notfound=1; @@ -374,6 +407,7 @@ void config_libconfig_end(void ) config_destroy(&(libconfig_privdata.cfg)); if ( libconfig_privdata.configfile != NULL ) { free(libconfig_privdata.configfile); + libconfig_privdata.configfile=NULL; } } diff --git a/common/config/libconfig/config_libconfig.h b/common/config/libconfig/config_libconfig.h index 8013d602cf6d1da96ee79ac6e66aede9958c2495..f541584185ec691e00b8f0ad734651152a69e6bc 100644 --- a/common/config/libconfig/config_libconfig.h +++ b/common/config/libconfig/config_libconfig.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/config/libconfig/config_libconfig_private.h b/common/config/libconfig/config_libconfig_private.h index 022e0e6330457aefce694cdc778107a87c8b1873..fb126ff7cb8c6c57c58ce4c42e45ded26a2d89b6 100644 --- a/common/config/libconfig/config_libconfig_private.h +++ b/common/config/libconfig/config_libconfig_private.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/ran_context.h b/common/ran_context.h index 4e25729c86a2377da0fd69b3a23093f8317e92f8..08c05411c98fa36829c39cb5cf04ec35c0f95dfc 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -35,11 +35,12 @@ #include <pthread.h> #include "COMMON/platform_constants.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" #include "PHY/types.h" #include "PHY/impl_defs_top.h" #include "PHY/impl_defs_lte.h" -#include "RRC/LITE/defs.h" +#include "RRC/LTE/rrc_defs.h" +#include "flexran_agent_defs.h" #include "gtpv1u.h" #include "NwGtpv1u.h" @@ -47,6 +48,8 @@ #include "NwGtpv1uPrivate.h" #include "gtpv1u_eNB_defs.h" +#include "PHY/defs_L1_NB_IoT.h" +#include "RRC/LTE/defs_NB_IoT.h" typedef struct { /// RAN context config file name char *config_file_name; @@ -54,22 +57,36 @@ typedef struct { int nb_inst; /// Number of Component Carriers per instance in this node int *nb_CC; + /// Number of NB_IoT instances in this node + int nb_nb_iot_rrc_inst; /// Number of MACRLC instances in this node int nb_macrlc_inst; + /// Number of NB_IoT MACRLC instances in this node + int nb_nb_iot_macrlc_inst; /// Number of component carriers per instance in this node int *nb_mac_CC; /// Number of L1 instances in this node int nb_L1_inst; + /// Number of NB_IoT L1 instances in this node + int nb_nb_iot_L1_inst; /// Number of Component Carriers per instance in this node int *nb_L1_CC; /// Number of RU instances in this node int nb_RU; + /// FlexRAN context variables + flexran_agent_info_t **flexran; /// eNB context variables struct PHY_VARS_eNB_s ***eNB; + /// NB_IoT L1 context variables + struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT; /// RRC context variables struct eNB_RRC_INST_s **rrc; - /// RRC context variables + /// NB_IoT RRC context variables + //struct eNB_RRC_INST_NB_IoT_s **nb_iot_rrc; + /// MAC context variables struct eNB_MAC_INST_s **mac; + /// NB_IoT MAC context variables + struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac; /// GTPu descriptor gtpv1u_data_t *gtpv1u_data_g; /// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces diff --git a/common/utils/T/T.c b/common/utils/T/T.c index f1fce835385a7e524b2b223e2b6de0e043538be9..92e70c221b6fd052e5f5c4804de8bc3f2edc4fff 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -88,7 +88,7 @@ static void new_thread(void *(*f)(void *), void *data) /* defined in local_tracer.c */ void T_local_tracer_main(int remote_port, int wait_for_tracer, - int local_socket); + int local_socket, char *shm_file); /* We monitor the tracee and the local tracer processes. * When one dies we forcefully kill the other. @@ -113,6 +113,9 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) int s; int T_shm_fd; int child1, child2; + char shm_file[128]; + + sprintf(shm_file, "/%s%d", T_SHM_FILENAME, getpid()); if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) { perror("socketpair"); abort(); } @@ -122,7 +125,8 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) child1 = fork(); if (child1 == -1) abort(); if (child1 == 0) { close(socket_pair[1]); - T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]); + T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0], + shm_file); exit(0); } close(socket_pair[0]); @@ -142,13 +146,13 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) T_socket = s; /* setup shared memory */ - T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666); - shm_unlink(T_SHM_FILENAME); - if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); } + T_shm_fd = shm_open(shm_file, O_RDWR /*| O_SYNC*/, 0666); + shm_unlink(shm_file); + if (T_shm_fd == -1) { perror(shm_file); abort(); } T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0); - if (T_cache == NULL) - { perror(T_SHM_FILENAME); abort(); } + if (T_cache == MAP_FAILED) + { perror(shm_file); abort(); } close(T_shm_fd); new_thread(T_receive_thread, NULL); diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 37668a830973dc668530ec685acabd0cf3ea1de5..cab246a6fff78017ab7e62df8c101f53212d8f8b 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -110,6 +110,16 @@ typedef struct { extern volatile int *T_freelist_head; extern T_cache_t *T_cache; +/* When running the basic simulator, we may fill the T cache too fast. + * Let's not crash if it's full, just wait. + */ +#if BASIC_SIMULATOR +# define T_BASIC_SIMULATOR_WAIT \ + while (T_cache[T_LOCAL_slot].busy) usleep(100) +#else +# define T_BASIC_SIMULATOR_WAIT /* */ +#endif + /* used at header of Tn, allocates buffer */ #define T_LOCAL_DATA \ char *T_LOCAL_buf; \ @@ -118,6 +128,7 @@ extern T_cache_t *T_cache; T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \ & (T_CACHE_SIZE - 1); \ (void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \ + T_BASIC_SIMULATOR_WAIT; \ if (T_cache[T_LOCAL_slot].busy) { \ printf("%s:%d:%s: T cache is full - consider increasing its size\n", \ __FILE__, __LINE__, __FUNCTION__); \ diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 6bdda0edacdb8f53ead52a6eea844037de309080..9961c1919e5d29cd40f120a5abedbc5f98363df6 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -8,10 +8,20 @@ #define T_MAX_ARGS 16 /* maximum size of a message - increase if needed */ -#define T_BUFFER_MAX (1024*64) +#if BASIC_SIMULATOR + /* let's have 100 RBs functional for the basic simulator */ +# define T_BUFFER_MAX (1024*64*2) +#else +# define T_BUFFER_MAX (1024*64) +#endif /* size of the local cache for messages (must be pow(2,something)) */ -#define T_CACHE_SIZE (8192 * 2) +#if BASIC_SIMULATOR + /* we don't need much space for the basic simulator */ +# define T_CACHE_SIZE 1024 +#else +# define T_CACHE_SIZE (8192 * 2) +#endif /* maximum number of bytes a message can contain */ #ifdef T_SEND_TIME @@ -32,7 +42,7 @@ typedef struct { #define VCD_NUM_FUNCTIONS 187 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES 128 +#define VCD_NUM_VARIABLES 131 /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 8d531f9067708a301b395cb9ca4e2fb5d3bf1ec2..4d59a8d380f65c6d88efdeea2afa81640e81a7fa 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1442,6 +1442,18 @@ ID = VCD_VARIABLE_UE0_TRX_WRITE_NS_MISSING DESC = VCD variable UE0_TRX_WRITE_NS_MISSING GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value +ID = VCD_VARIABLE_CPUID_ENB_THREAD_RXTX + DESC = VCD variable CPUID_ENB_THREAD_RXTX + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_CPUID_RU_THREAD + DESC = VCD variable CPUID_RU_THREAD + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_CPUID_RU_THREAD_TX + DESC = VCD variable CPUID_RU_THREAD_TX + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value #functions diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index 6d0ecddd45913d1c58a813008091feaf0a2913f9..43680b40998b41ab43334c33d01756e5258c02cf 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -300,6 +300,20 @@ static void forward(void *_forwarder, char *buf, int size) if (f->tail != NULL) f->tail->next = new; f->tail = new; +#if BASIC_SIMULATOR + /* When runnng the basic simulator, the tracer may be too slow. + * Let's not take too much memory in the tracee and + * wait if there is too much data to send. 200MB is + * arbitrary. + */ + while (f->memusage > 200 * 1024 * 1024) { + if (pthread_cond_signal(&f->cond)) abort(); + if (pthread_mutex_unlock(&f->lock)) abort(); + usleep(1000); + if (pthread_mutex_lock(&f->lock)) abort(); + } +#endif /* BASIC_SIMULATOR */ + f->memusage += size+4; /* warn every 100MB */ if (f->memusage > f->last_warning_memusage && @@ -326,17 +340,17 @@ static void wait_message(void) while (T_local_cache[T_busylist_head].busy == 0) usleep(1000); } -static void init_shm(void) +static void init_shm(char *shm_file) { int i; - int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666); - if (s == -1) { perror(T_SHM_FILENAME); abort(); } + int s = shm_open(shm_file, O_RDWR | O_CREAT /*| O_SYNC*/, 0666); + if (s == -1) { perror(shm_file); abort(); } if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t))) - { perror(T_SHM_FILENAME); abort(); } + { perror(shm_file); abort(); } T_local_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), PROT_READ | PROT_WRITE, MAP_SHARED, s, 0); - if (T_local_cache == NULL) - { perror(T_SHM_FILENAME); abort(); } + if (T_local_cache == MAP_FAILED) + { perror(shm_file); abort(); } close(s); /* let's garbage the memory to catch some potential problems @@ -347,7 +361,7 @@ static void init_shm(void) } void T_local_tracer_main(int remote_port, int wait_for_tracer, - int local_socket) + int local_socket, char *shm_file) { int s; int port = remote_port; @@ -357,7 +371,7 @@ void T_local_tracer_main(int remote_port, int wait_for_tracer, /* write on a socket fails if the other end is closed and we get SIGPIPE */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); - init_shm(); + init_shm(shm_file); s = local_socket; if (dont_wait) { diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index f607743d1592f1473ad172ad9684a7ba17730104..a30366faf1eb8e645d5efba1cf664985cc60c255 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -12,7 +12,6 @@ #include "gui/gui.h" #include "filter/filter.h" #include "utils.h" -#include "../T_defs.h" #include "event_selector.h" #include "openair_logo.h" #include "config.h" @@ -875,6 +874,8 @@ int main(int n, char **v) if (pthread_mutex_init(&enb_data.lock, NULL)) abort(); setup_event_selector(g, database, is_on, is_on_changed, &enb_data); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + restart: clear_remote_config(); enb_data.socket = connect_to(ip, port); @@ -884,9 +885,8 @@ restart: /* read messages */ while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(enb_data.socket, v, database); + e = get_event(enb_data.socket, &ebuf, database); if (e.type == -1) goto restart; if (pthread_mutex_lock(&enb_data.lock)) abort(); handle_event(h, e); diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c index 0917c010b3852a95a6e0fa6f56e48315c1d19b2b..f5d12e472c0ee09384ff5a1166421dfae4692dca 100644 --- a/common/utils/T/tracer/event.c +++ b/common/utils/T/tracer/event.c @@ -6,7 +6,7 @@ #include <stdlib.h> #include <string.h> -event get_event(int socket, char *event_buffer, void *database) +event get_event(int socket, OBUF *event_buffer, void *database) { #ifdef T_SEND_TIME struct timespec t; @@ -29,17 +29,23 @@ again: #endif if (fullread(socket, &type, sizeof(int)) == -1) goto read_error; length -= sizeof(int); - if (fullread(socket, event_buffer, length) == -1) goto read_error; + if (event_buffer->omaxsize < length) { + event_buffer->omaxsize = (length + 65535) & ~65535; + event_buffer->obuf = realloc(event_buffer->obuf, event_buffer->omaxsize); + if (event_buffer->obuf == NULL) { printf("out of memory\n"); exit(1); } + } + if (fullread(socket, event_buffer->obuf, length) == -1) goto read_error; + event_buffer->osize = length; - if (type == -1) append_received_config_chunk(event_buffer, length); + if (type == -1) append_received_config_chunk(event_buffer->obuf, length); if (type == -2) verify_config(); if (type == -1 || type == -2) goto again; #ifdef T_SEND_TIME - return new_event(t, type, length, event_buffer, database); + return new_event(t, type, length, event_buffer->obuf, database); #else - return new_event(type, length, event_buffer, database); + return new_event(type, length, event_buffer->obuf, database); #endif read_error: diff --git a/common/utils/T/tracer/event.h b/common/utils/T/tracer/event.h index 6272baf1a8f13216959db18951b606690315d46e..0170ab6680c6aac3c4b656ec803177c8e4ee7b6a 100644 --- a/common/utils/T/tracer/event.h +++ b/common/utils/T/tracer/event.h @@ -1,6 +1,7 @@ #ifndef _EVENT_H_ #define _EVENT_H_ +#include "utils.h" #include "../T_defs.h" #ifdef T_SEND_TIME #include <time.h> @@ -37,7 +38,7 @@ typedef struct { int ecount; } event; -event get_event(int s, char *v, void *d); +event get_event(int s, OBUF *v, void *d); #ifdef T_SEND_TIME event new_event(struct timespec sending_time, int type, diff --git a/common/utils/T/tracer/extract.c b/common/utils/T/tracer/extract.c index b9fca959eddf6a8428aee25b5aabf37cd51419b5..2aec38831fe2c528cd12cbaa3814e75813eb3bfe 100644 --- a/common/utils/T/tracer/extract.c +++ b/common/utils/T/tracer/extract.c @@ -99,10 +99,11 @@ int main(int n, char **v) found = 0; + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(fd, v, database); + e = get_event(fd, &ebuf, database); if (e.type == -1) break; if (e.type != input_event_id) continue; for (i = 0; i < filter_count; i++) diff --git a/common/utils/T/tracer/extract_config.c b/common/utils/T/tracer/extract_config.c index f35d765cec5b3366b88eca9bd9bc85d2697a18e4..a26c52aeda2a8ec31cf4748a0fc07a825d18a477 100644 --- a/common/utils/T/tracer/extract_config.c +++ b/common/utils/T/tracer/extract_config.c @@ -1,6 +1,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "utils.h" #include "../T_defs.h" void usage(void) @@ -35,14 +36,22 @@ int main(int n, char **v) in = fopen(input_filename, "r"); if (in == NULL) { perror(input_filename); abort(); } + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + while (1) { int type; int32_t length; - char v[T_BUFFER_MAX]; + char *v; int vpos = 0; /* read event from file */ if (fread(&length, 4, 1, in) != 1) break; + if (ebuf.omaxsize < length) { + ebuf.omaxsize = (length + 65535) & ~65535; + ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize); + if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); } + } + v = ebuf.obuf; memcpy(v+vpos, &length, 4); vpos += 4; #ifdef T_SEND_TIME diff --git a/common/utils/T/tracer/extract_input_subframe.c b/common/utils/T/tracer/extract_input_subframe.c index 02c5f3d56506d2889dc037918c1ec71ca1086d25..d7423182018df7a9f33a8d7c3202a6d810a3ed9f 100644 --- a/common/utils/T/tracer/extract_input_subframe.c +++ b/common/utils/T/tracer/extract_input_subframe.c @@ -104,11 +104,12 @@ err: fd = open(file, O_RDONLY); if (fd == -1) { perror(file); exit(1); } + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + /* get wanted frame/subframe */ while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(fd, v, database); + e = get_event(fd, &ebuf, database); if (e.type == -1) break; if (e.type != input_event_id) continue; if (verbose) diff --git a/common/utils/T/tracer/extract_output_subframe.c b/common/utils/T/tracer/extract_output_subframe.c index b82ad0e7665d259358e08b27f7c1816659ca3b3b..d24393553cee537e16f25cc600e74780fc808bba 100644 --- a/common/utils/T/tracer/extract_output_subframe.c +++ b/common/utils/T/tracer/extract_output_subframe.c @@ -100,10 +100,12 @@ err: int last_frame = -1; int last_subframe = -1; int subframe_written = 0; + + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(fd, v, database); + e = get_event(fd, &ebuf, database); if (e.type == -1) break; if (e.type != output_event_id) continue; if (verbose) diff --git a/common/utils/T/tracer/hacks/dump_nack_signal.c b/common/utils/T/tracer/hacks/dump_nack_signal.c index 1627bdd14e925ad68797d16614be9e57bc23447e..bb8f1a9477bda7894ba8465a068b2825db5e6737 100644 --- a/common/utils/T/tracer/hacks/dump_nack_signal.c +++ b/common/utils/T/tracer/hacks/dump_nack_signal.c @@ -73,17 +73,22 @@ int main(int n, char **v) socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) abort(); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + char dump[10][T_BUFFER_MAX]; event dump_ev[10]; FILE *z = fopen("/tmp/dd", "w"); if (z == NULL) abort(); while (1) { - char v[T_BUFFER_MAX]; + char *v; event e; - e = get_event(socket, v, database); + e = get_event(socket, &ebuf, database); + v = ebuf.obuf; if (e.type == -1) break; if (e.type == ev_input) { int sf = e.e[2].i; - memcpy(dump[sf], v, T_BUFFER_MAX); + if (ebuf.osize > T_BUFFER_MAX) + { printf("event size too big\n"); exit(1); } + memcpy(dump[sf], ebuf.obuf, ebuf.osize); dump_ev[sf] = e; printf("input %d/%d\n", e.e[1].i, sf); if (fwrite(dump_ev[sf].e[4].b, dump_ev[sf].e[4].bsize, 1, z) != 1) abort(); diff --git a/common/utils/T/tracer/hacks/time_meas.c b/common/utils/T/tracer/hacks/time_meas.c index 04d4fa5acfcd026816c0345bc7513aa5759e0064..6bd29503011fb92e306dd10a7dd6539ebd0ee0f9 100644 --- a/common/utils/T/tracer/hacks/time_meas.c +++ b/common/utils/T/tracer/hacks/time_meas.c @@ -84,11 +84,12 @@ int main(int n, char **v) socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) abort(); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + while (1) { - char v[T_BUFFER_MAX]; event e; int on_off; - e = get_event(socket, v, database); + e = get_event(socket, &ebuf, database); if (e.type == -1) break; if (e.type != ev_fun) { printf("unhandled event %d\n", e.type); continue; } diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index be0bbd382142bf82f171401bac34f91a7e4d4f67..954f668aa420c0cd0070f58757df721727199e2a 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -246,11 +246,12 @@ int main(int n, char **v) new_thread(receiver, &d); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + /* read messages */ while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(in, v, database); + e = get_event(in, &ebuf, database); if (e.type == -1) break; if (!(e.type == ul_id || e.type == dl_id)) continue; handle_event(h, e); diff --git a/common/utils/T/tracer/record.c b/common/utils/T/tracer/record.c index b1a1bc60de8cb8bdd0b69604f414f7d5aa7b0802..a565884e52b071ff9da15974b04fa81427cfa943 100644 --- a/common/utils/T/tracer/record.c +++ b/common/utils/T/tracer/record.c @@ -123,14 +123,22 @@ int main(int n, char **v) if (signal(SIGINT, force_stop) == SIG_ERR) abort(); if (signal(SIGTSTP, force_stop) == SIG_ERR) abort(); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + /* read messages */ while (run) { int type; int32_t length; - char v[T_BUFFER_MAX]; + char *v; int vpos = 0; if (fullread(socket, &length, 4) == -1) goto read_error; + if (ebuf.omaxsize < length) { + ebuf.omaxsize = (length + 65535) & ~65535; + ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize); + if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); } + } + v = ebuf.obuf; memcpy(v+vpos, &length, 4); vpos += 4; #ifdef T_SEND_TIME diff --git a/common/utils/T/tracer/replay.c b/common/utils/T/tracer/replay.c index be7e8d60c69fefcdd562ec79c5dea01c384b92c0..c199a668d58f7dfde3fc07378aaf112267d7afea 100644 --- a/common/utils/T/tracer/replay.c +++ b/common/utils/T/tracer/replay.c @@ -136,14 +136,22 @@ int main(int n, char **v) new_thread(get_message_thread, &socket); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + while (1) { int type; int32_t length; - char v[T_BUFFER_MAX]; + char *v; int vpos = 0; /* read event from file */ if (fread(&length, 4, 1, in) != 1) break; + if (ebuf.omaxsize < length) { + ebuf.omaxsize = (length + 65535) & ~65535; + ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize); + if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); } + } + v = ebuf.obuf; memcpy(v+vpos, &length, 4); vpos += 4; #ifdef T_SEND_TIME diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index 32bf1ed791ce10060fb48b62d7f4b69c94b23ba9..bb773b42150b9fcc15b7378405818a4b14db0e42 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -10,7 +10,6 @@ #include "view/view.h" #include "gui/gui.h" #include "utils.h" -#include "../T_defs.h" #include "event_selector.h" #include "config.h" @@ -182,11 +181,12 @@ int main(int n, char **v) /* send the first message - activate selected traces */ is_on_changed(&textlog_data); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + /* read messages */ while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(textlog_data.socket, v, database); + e = get_event(textlog_data.socket, &ebuf, database); if (e.type == -1) abort(); handle_event(h, e); } diff --git a/common/utils/T/tracer/to_vcd.c b/common/utils/T/tracer/to_vcd.c index 82cd3393d7e9e26e59305cb3928a209d879bfdc4..097fdce93217af2d6b6bc48a204bc120c421775f 100644 --- a/common/utils/T/tracer/to_vcd.c +++ b/common/utils/T/tracer/to_vcd.c @@ -287,11 +287,12 @@ int main(int n, char **v) if (signal(SIGINT, force_stop) == SIG_ERR) abort(); if (signal(SIGTSTP, force_stop) == SIG_ERR) abort(); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + /* read messages */ while (run) { - char v[T_BUFFER_MAX]; event e; - e = get_event(socket, v, database); + e = get_event(socket, &ebuf, database); if (e.type == -1) { printf("disconnected? let's quit gently\n"); break; } handle_event(h, e); } diff --git a/common/utils/T/tracer/ue.c b/common/utils/T/tracer/ue.c index 5709a4e79e06c82f2baa3a90b8cea683c768471c..6a7d03c897357c5e0d2cbbe07239fcb2bf2ebcfc 100644 --- a/common/utils/T/tracer/ue.c +++ b/common/utils/T/tracer/ue.c @@ -12,7 +12,6 @@ #include "gui/gui.h" #include "filter/filter.h" #include "utils.h" -#include "../T_defs.h" #include "event_selector.h" #include "openair_logo.h" #include "config.h" @@ -854,6 +853,8 @@ int main(int n, char **v) if (pthread_mutex_init(&ue_data.lock, NULL)) abort(); setup_event_selector(g, database, is_on, is_on_changed, &ue_data); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + restart: clear_remote_config(); ue_data.socket = connect_to(ip, port); @@ -863,9 +864,8 @@ restart: /* read messages */ while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(ue_data.socket, v, database); + e = get_event(ue_data.socket, &ebuf, database); if (e.type == -1) goto restart; if (pthread_mutex_lock(&ue_data.lock)) abort(); handle_event(h, e); diff --git a/common/utils/T/tracer/vcd.c b/common/utils/T/tracer/vcd.c index 0ad2756c2a49d218314aa4b586ba6a7bac0765ab..d4faa5fd8477d4698fd59721b910fca1dd6d26b6 100644 --- a/common/utils/T/tracer/vcd.c +++ b/common/utils/T/tracer/vcd.c @@ -10,7 +10,6 @@ #include "view/view.h" #include "gui/gui.h" #include "utils.h" -#include "../T_defs.h" #include "event_selector.h" #include "config.h" @@ -188,11 +187,12 @@ int main(int n, char **v) /* send the first message - activate selected traces */ is_on_changed(&vcd_data); + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + /* read messages */ while (1) { - char v[T_BUFFER_MAX]; event e; - e = get_event(vcd_data.socket, v, database); + e = get_event(vcd_data.socket, &ebuf, database); if (e.type == -1) abort(); handle_event(h, e); } diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index f96c9b3bc6d0a9ee7e2f16643432c3a6e86e4aee..05e5e8c3dc224242b09518394acf255c63150bd8 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -54,7 +54,6 @@ #include "signals.h" #include "timer.h" -#include "log.h" /* ITTI DEBUG groups */ #define ITTI_DEBUG_POLL (1<<0) @@ -73,6 +72,9 @@ const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS); /* Global message size */ #define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size) + +extern int emulate_rf; + typedef enum task_state_s { TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX, } task_state_t; @@ -326,8 +328,112 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me /* Increment the global message number */ message_number = itti_increment_message_number (); +#if 0 + /* itti dump is disabled */ + itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name, + sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); +#endif + + if (destination_task_id != TASK_UNKNOWN) { + + if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED) { + ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), ended destination task!\n", + itti_desc.messages_info[message_id].name, + message_number, + priority, + itti_get_task_name(origin_task_id), + destination_task_id, + itti_get_task_name(destination_task_id)); + } else { + if(!emulate_rf){ + /* We cannot send a message if the task is not running */ + AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY, + "Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n", + itti_get_task_name(origin_task_id), + itti_desc.messages_info[message_id].name, + message_id, + destination_thread_id, + itti_desc.threads[destination_thread_id].task_state); + } + + /* Allocate new list element */ + new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s)); + + /* Fill in members */ + new->msg = message; + new->message_number = message_number; + new->message_priority = priority; + + /* Enqueue message in destination task queue */ + if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) { + AssertFatal(0, "Error: lfds611_queue_enqueue returns 0, queue is full, exiting\n"); + } + + { + /* Only use event fd for tasks, subtasks will pool the queue */ + if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) { + ssize_t write_ret; + eventfd_t sem_counter = 1; + + /* Call to write for an event fd must be of 8 bytes */ + write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); + AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n", + destination_thread_id, (int) write_ret, (int) sizeof(sem_counter)); + } + } + + ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n", + itti_desc.messages_info[message_id].name, + message_number, + priority, + itti_get_task_name(origin_task_id), + destination_task_id, + itti_get_task_name(destination_task_id)); + } + } else { + /* This is a debug message to TASK_UNKNOWN, we can release safely release it */ + int result = itti_free(origin_task_id, message); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + + return 0; +} + +/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */ +/* TODO: this is a hack - the whole logic needs a proper rework. */ +/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ +int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) +{ + thread_id_t destination_thread_id; + task_id_t origin_task_id; + message_list_t *new; + uint32_t priority; + message_number_t message_number; + uint32_t message_id; + + AssertFatal (message != NULL, "Message is NULL!\n"); + AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max); + + destination_thread_id = TASK_GET_THREAD_ID(destination_task_id); + message->ittiMsgHeader.destinationTaskId = destination_task_id; + message->ittiMsgHeader.instance = instance; + message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame; + message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot; + message_id = message->ittiMsgHeader.messageId; + AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); + + origin_task_id = ITTI_MSG_ORIGIN_ID(message); + + priority = itti_get_message_priority (message_id); + + /* Increment the global message number */ + message_number = itti_increment_message_number (); + +#if 0 + /* itti dump is disabled */ itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name, sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); +#endif if (destination_task_id != TASK_UNKNOWN) { @@ -359,18 +465,8 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me /* Enqueue message in destination task queue */ if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) { - LOG_I(UDP_, " Assertion Message %s(id:%d), number %lu with priority %d can not be sent from (%u:%s) to queue (%u:%s). discarding...\n", - itti_desc.messages_info[message_id].name, - message_id, - message_number, - priority, - origin_task_id, - itti_get_task_name(origin_task_id), - destination_task_id, - itti_get_task_name(destination_task_id)); - int result = itti_free(origin_task_id, message); - AssertFatal( result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - return 0; + itti_free(origin_task_id, new); + return -1; } { @@ -524,10 +620,7 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) { /* No element in list -> this should not happen */ - LOG_I(UDP_, "Assertion No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret); - /* Mark that the event has been processed */ - itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN; - return; + AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret); } AssertFatal(message != NULL, "Message from message queue is NULL!\n"); @@ -634,8 +727,11 @@ void itti_mark_task_ready(task_id_t task_id) AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max); +#if 0 + /* itti dump is disabled */ /* Register the thread in itti dump */ itti_dump_thread_use_ring_buffer(); +#endif /* Mark the thread as using LFDS queue */ lfds611_queue_use(itti_desc.tasks[task_id].message_queue); @@ -661,6 +757,19 @@ void itti_mark_task_ready(task_id_t task_id) void itti_exit_task(void) { + task_id_t task_id = itti_get_current_task_id(); + thread_id_t thread_id = TASK_GET_THREAD_ID(task_id); + +#if defined(OAI_EMU) || defined(RTAI) + if (task_id > TASK_UNKNOWN) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG, + __sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id))); + } +#endif + + itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED; + itti_desc.created_tasks--; + ITTI_DEBUG(ITTI_DEBUG_EXIT, "Thread for task %s (%d) exits\n", itti_get_task_name(task_id), task_id); pthread_exit (NULL); } @@ -762,7 +871,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i itti_desc.wait_tasks = 0; itti_desc.created_tasks = 0; itti_desc.ready_tasks = 0; +#if 0 + /* itti dump is disabled */ itti_dump_init (messages_definition_xml, dump_file_name); +#endif CHECK_INIT_RETURN(timer_init ()); @@ -829,7 +941,10 @@ void itti_wait_tasks_end(void) exit (0); } +#if 0 + /* itti dump is disabled */ itti_dump_exit(); +#endif } void itti_send_terminate_message(task_id_t task_id) diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h index 606c851d1de02dd6647f68321499a83da3e6fcc3..ada34ce1b722a09722373cc5a650870364891b4e 100644 --- a/common/utils/itti/intertask_interface.h +++ b/common/utils/itti/intertask_interface.h @@ -108,6 +108,18 @@ int itti_send_broadcast_message(MessageDef *message_p); **/ int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); +/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks + * the return value so it has been changed to crash the program in case + * of failure instead of returning -1 as the documentation above says. + * The RLC UM code may receive too much data when doing UDP at a higher + * throughput than the link allows and so for this specific case we need + * a version that actually returns -1 on failure. + * + * This needs to be cleaned at some point. + */ +/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ +int itti_try_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); + /** \brief Add a new fd to monitor. * NOTE: it is up to the user to read data associated with the fd * \param task_id Task ID of the receiving task diff --git a/common/utils/itti/itti_types.h b/common/utils/itti/itti_types.h index d07853133bae343772b1d3b277602923b5fc3761..2607c003b130f1d261923c6ebae21cec657d42b0 100644 --- a/common/utils/itti/itti_types.h +++ b/common/utils/itti/itti_types.h @@ -27,7 +27,18 @@ #ifndef _ITTI_TYPES_H_ #define _ITTI_TYPES_H_ -#include <stdint.h> +/* The current file is included in the ue_ip.ko compilation. + * For it to work we need to include linux/types.h and + * not stdint.h. + * A solution to this problem is to use #ifndef __KERNEL__. + * Maybe a better solution would be to clean things up + * so that ue_ip.ko does not include the current file. + */ +#ifndef __KERNEL__ +# include <stdint.h> +#else +# include <linux/types.h> +#endif #define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1)) diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index b21f39e69dff7b05ba44b23f1d097852681dcd2f..656f6a885224abaf3e6565368bd99d5f95225620 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -34,9 +34,10 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <errno.h> #include <sys/ioctl.h> #include <dlfcn.h> -#include "openair1/PHY/defs.h" +#include "openair1/PHY/defs_common.h" #define LOAD_MODULE_SHLIB_MAIN #include "common/config/config_userapi.h" @@ -44,68 +45,162 @@ void loader_init(void) { paramdef_t LoaderParams[] = LOADER_PARAMS_DESC; - + loader_data.mainexec_buildversion = PACKAGE_VERSION; int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),LOADER_CONFIG_PREFIX); if (ret <0) { - fprintf(stderr,"[LOADER] configuration couldn't be performed"); + printf("[LOADER] configuration couldn't be performed via config module, parameters set to default values\n"); if (loader_data.shlibpath == NULL) { loader_data.shlibpath=DEFAULT_PATH; } - return; - } + loader_data.maxshlibs = DEFAULT_MAXSHLIBS; + } + loader_data.shlibs = malloc(loader_data.maxshlibs * sizeof(loader_shlibdesc_t)); + if(loader_data.shlibs == NULL) { + fprintf(stderr,"[LOADER] %s %d memory allocation error %s\n",__FILE__, __LINE__,strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } + memset(loader_data.shlibs,0,loader_data.maxshlibs * sizeof(loader_shlibdesc_t)); +} + +/* build the full shared lib name from the module name */ +char *loader_format_shlibpath(char *modname) +{ + +char *tmpstr; +char *shlibpath =NULL; +char *shlibversion=NULL; +char *cfgprefix; +paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0}, + {"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0}}; + +int ret; + + + + +/* looks for specific path for this module in the config file */ +/* specific value for a module path and version is located in a modname subsection of the loader section */ +/* shared lib name is formatted as lib<module name><module version>.so */ + cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16); + if (cfgprefix == NULL) { + fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } else { + sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname); + int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix); + if (ret <0) { + fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix); + } + } +/* no specific path, use loader default shared lib path */ + if (shlibpath == NULL) { + shlibpath = loader_data.shlibpath ; + } +/* no specific shared lib version */ + if (shlibversion == NULL) { + shlibversion = "" ; + } +/* alloc memory for full module shared lib file name */ + tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16); + if (tmpstr == NULL) { + fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } + if(shlibpath[0] != 0) { + ret=sprintf(tmpstr,"%s/",shlibpath); + } else { + ret = 0; + } + + sprintf(tmpstr+ret,"lib%s%s.so",modname,shlibversion); + + + return tmpstr; } int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) { void *lib_handle; initfunc_t fpi; - char *tmpstr; + checkverfunc_t fpc; + getfarrayfunc_t fpg; + char *shlib_path; + char *afname=NULL; int ret=0; if (loader_data.shlibpath == NULL) { loader_init(); } - tmpstr = malloc(strlen(loader_data.shlibpath)+strlen(modname)+16); - if (tmpstr == NULL) { - fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); - return -1; - } - if(loader_data.shlibpath[0] != 0) { - ret=sprintf(tmpstr,"%s/",loader_data.shlibpath); - } - if(strstr(modname,".so") == NULL) { - sprintf(tmpstr+ret,"lib%s.so",modname); - } else { - sprintf(tmpstr+ret,"%s",modname); - } + shlib_path = loader_format_shlibpath(modname); + ret = 0; - lib_handle = dlopen(tmpstr, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); + lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); if (!lib_handle) { - fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", tmpstr,dlerror()); + fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); ret = -1; } else { - printf("[LOADER] library %s uccessfully loaded loaded\n", tmpstr); - sprintf(tmpstr,"%s_autoinit",modname); - fpi = dlsym(lib_handle,tmpstr); + printf("[LOADER] library %s successfully loaded\n", shlib_path); + afname=malloc(strlen(modname)+15); + sprintf(afname,"%s_checkbuildver",modname); + fpc = dlsym(lib_handle,afname); + if (fpc != NULL ){ + int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); + if (chkver_ret < 0) { + fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); + exit_fun("[LOADER] unrecoverable error"); + } + } + sprintf(afname,"%s_autoinit",modname); + fpi = dlsym(lib_handle,afname); - if (fpi != NULL ) - { + if (fpi != NULL ) { fpi(); - } + } if (farray != NULL) { + loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t)); + loader_data.shlibs[loader_data.numshlibs].numfunc=0; for (int i=0; i<numf; i++) { farray[i].fptr = dlsym(lib_handle,farray[i].fname); if (farray[i].fptr == NULL ) { fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname); - ret= -1; - } + ret= -1; + } else { /* farray[i].fptr == NULL */ + loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname); + loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr; + loader_data.shlibs[loader_data.numshlibs].numfunc++; + }/* farray[i].fptr != NULL */ } /* for int i... */ - } /* farray ! NULL */ - } + } else { /* farray ! NULL */ + sprintf(afname,"%s_getfarray",modname); + fpg = dlsym(lib_handle,afname); + if (fpg != NULL ) { + loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray)); + } + } /* farray ! NULL */ + loader_data.shlibs[loader_data.numshlibs].name=strdup(modname); + loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path); + + (loader_data.numshlibs)++; + } /* lib_handle != NULL */ - if (tmpstr != NULL) free(tmpstr); + if ( shlib_path!= NULL) free(shlib_path); + if ( afname!= NULL) free(afname); if (lib_handle != NULL) dlclose(lib_handle); return ret; } + +void * get_shlibmodule_fptr(char *modname, char *fname) +{ + for (int i=0; i<loader_data.numshlibs && loader_data.shlibs[i].name != NULL; i++) { + if ( strcmp(loader_data.shlibs[i].name, modname) == 0) { + for (int j =0; j<loader_data.shlibs[i].numfunc ; j++) { + if (strcmp(loader_data.shlibs[i].funcarray[j].fname, fname) == 0) { + return loader_data.shlibs[i].funcarray[j].fptr; + } + } /* for j loop on module functions*/ + } + } /* for i loop on modules */ + return NULL; +} diff --git a/common/utils/load_module_shlib.h b/common/utils/load_module_shlib.h index 1f991dddd2ca96c7215b4227cedf0bbb9fc8d0e4..ffbad665708ef0ffe1f890d14e6f04039b5afb80 100644 --- a/common/utils/load_module_shlib.h +++ b/common/utils/load_module_shlib.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -33,33 +33,60 @@ #define LOAD_SHLIB_H -typedef int(*initfunc_t)(void); -typedef struct { - char *shlibpath; -}loader_data_t; typedef struct { char *fname; int (*fptr)(void); }loader_shlibfunc_t; + +typedef struct { + char *name; + char *shlib_version; // + char *shlib_buildversion; + char *thisshlib_path; + uint32_t numfunc; + loader_shlibfunc_t *funcarray; +}loader_shlibdesc_t; + +typedef struct { + char *mainexec_buildversion; + char *shlibpath; + uint32_t maxshlibs; + uint32_t numshlibs; + loader_shlibdesc_t *shlibs; +}loader_data_t; + +/* function type of functions which may be implemented by a module */ +/* 1: init function, called when loading, if found in the shared lib */ +typedef int(*initfunc_t)(void); +/* 2: version checking function, called when loading, if it returns -1, trigger main exec abort */ +typedef int(*checkverfunc_t)(char * mainexec_version, char ** shlib_version); +/* 3: get function array function, called when loading when a module doesn't provide */ +/* the function array when calling load_module_shlib (farray param NULL) */ +typedef int(*getfarrayfunc_t)(loader_shlibfunc_t **funcarray); + #ifdef LOAD_MODULE_SHLIB_MAIN #define LOADER_CONFIG_PREFIX "loader" -#define DEFAULT_PATH "" +#define DEFAULT_PATH "" +#define DEFAULT_MAXSHLIBS 10 loader_data_t loader_data; -/*--------------------------------------------------------------------------------------------------------------------------------------*/ -/* LOADER parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*--------------------------------------------------------------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* LOADER parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOADER_PARAMS_DESC { \ -{"shlibpath", NULL, 0, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0} \ +{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0}, \ +{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0}, \ } /*-------------------------------------------------------------------------------------------------------------*/ -#else +#else /* LOAD_MODULE_SHLIB_MAIN */ extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf); -#endif +extern void * get_shlibmodule_fptr(char *modname, char *fname); +extern loader_data_t loader_data; +#endif /* LOAD_MODULE_SHLIB_MAIN */ #endif diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c index 307eeb30a51c8a1216d57f87f4c89a327a93d166..bb88b9b4b6a4441eba3b65ee40b31198efb8b5b0 100644 --- a/common/utils/msc/msc.c +++ b/common/utils/msc/msc.c @@ -99,6 +99,7 @@ void *msc_task(void *args_p) break; case TERMINATE_MESSAGE: { + fprintf(stderr, " *** Exiting MSC thread\n"); timer_remove(timer_id); msc_end(); itti_exit_task(); diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt deleted file mode 100644 index bc4a550742291e2c9a67cbf4e923ca79d00eb8e0..0000000000000000000000000000000000000000 --- a/common/utils/telnetsrv/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -cmake_minimum_required(VERSION 2.8 FATAL_ERROR) -IF(DEFINED ENV{OPENAIR_DIR}) - message("...using oai source files in $ENV{OPENAIR_DIR}") -ELSE() - message("OPENAIR_DIR is not defined. You must run \"source oaienv\" from the oai root dir") - # exit early - return() -ENDIF() - - - -set(OPENAIR_DIR $ENV{OPENAIR_DIR}) -set(APPROOT ${OPENAIR_DIR}/common/utils/telnetsrv ) -set(OPENAIR_BUILD_DIR $ENV{OPENAIR_DIR}/cmake_targets) -set(OPENAIR1_DIR $ENV{OPENAIR1_DIR}) -set(OPENAIR2_DIR $ENV{OPENAIR2_DIR}) -set(OPENAIR3_DIR $ENV{OPENAIR3_DIR}) -set(OPENAIR_PHY_DIR $ENV{OPENAIR1_DIR}/PHY) -set(OPENAIR_TARGET_DIR $ENV{OPENAIR_DIR}/targets) -set(OPENAIR_COMMONUTILS_DIR $ENV{OPENAIR_DIR}/common/utils) -set(OPENAIR2_COMMON_DIR $ENV{OPENAIR_DIR}/openair2/COMMON) -set(OPENAIR_ASN1INC ${OPENAIR_BUILD_DIR}/lte_build_oai/build/CMakeFiles/Rel14) -set(OPENAIR_NFAPIINC $ENV{NFAPI_DIR} ) - -set(CMAKE_INSTALL_PREFIX $ENV{OPENAIR_TARGETS}) - -add_definitions (-DRel14 -DCMAKER -DENABLE_ITTI -DENABLE_NAS_UE_LOGGING -DENABLE_SECURITY -DENABLE_USE_CPU_EXECUTION_TIME -DENABLE_USE_MME -DENABLE_VCD -DENB_AGENT -DENB_MODE -DETHERNET=1 -DEXMIMO_IOT -DJUMBO_FRAME -DLINK_ENB_PDCP_TO_GTPV1U -DLOG_NO_THREAD -DMAC_CONTEXT -DMAX_NUM_CCs=1 -DNAS_BUILT_IN_UE -DNAS_UE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK -DOPENAIR2 -DOPENAIR_LTE -DPHYSIM -DPHY_CONTEXT -DRel10=1 -DS1AP_VERSION=R10 -DTRACE_RLC_MUTEX -DX2AP_VERSION=R11 -DXFORMS -mavx2 -msse4.1 -mssse3) -add_compile_options( -fPIC -march=native -Ofast) - -include_directories( ./ ${OPENAIR_COMMON_DIR} ${OPENAIR_DIR} ${OPENAIR1_DIR} ${OPENAIR2_DIR} ${OPENAIR2_COMMON_DIR} ${OPENAIR2_DIR}/UTIL/LOG - ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC} - ${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0 ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC} - ${OPENAIR2_DIR}/LAYER2/RLC ${OPENAIR2_DIR}/UTIL/LISTS ${OPENAIR2_DIR}/UTIL/MEM ${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0 - ${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0 ${OPENAIR2_DIR}/RRC/LITE ${OPENAIR_TARGET_DIR}/COMMON ${OPENAIR_TARGET_DIR}/ARCH/COMMON - ${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK ${OPENAIR3_DIR}/NAS/COMMON/EMM/MSG/ ${OPENAIR3_DIR}/NAS/COMMON/IES/ ${OPENAIR3_DIR}/NAS/COMMON/UTIL - ${OPENAIR3_DIR}/NAS/COMMON/ESM/MSG/ ${OPENAIR3_DIR}/GTPV1-U ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/shared ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/include - ${OPENAIR3_DIR}/UTILS ${OPENAIR_NFAPIINC}) - -set(TELNETSRV_SOURCE - ${APPROOT}/telnetsrv.c - ${APPROOT}/telnetsrv_phycmd.c - ${APPROOT}/telnetsrv_proccmd.c - ) - -#set(TELNETSRV_ETHDEVCMD_SOURCE -# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c -# ) - - - -add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} ) -#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} ) - - -install(TARGETS telnetsrv DESTINATION bin) - -if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") - install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build) -endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index f99a83f3218c78226a052a2dd65bf5d910e6860a..a49311d0994a16420abf3edf10bf92dac36f35ba 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -43,7 +43,7 @@ #include <string.h> #include <signal.h> #include <pthread.h> -#include <telnetsrv.h> +#include "telnetsrv.h" #include <string.h> #include <stdarg.h> #include <unistd.h> @@ -51,20 +51,27 @@ #include <dlfcn.h> #include <sys/time.h> #include <sys/resource.h> - +#include "common/utils/load_module_shlib.h" #include "common/config/config_userapi.h" +#include <readline/history.h> #include "telnetsrv_phycmd.h" #include "telnetsrv_proccmd.h" -static char* telnet_defstatmod[] = {"softmodem","phy"}; +static char* telnet_defstatmod[] = {"softmodem","phy","loader"}; static telnetsrv_params_t telnetparams; #define TELNETSRV_LISTENADDR 0 #define TELNETSRV_LISTENPORT 1 #define TELNETSRV_PRIORITY 2 #define TELNETSRV_DEBUG 3 -#define TELNETSRV_STATICMOD 7 -#define TELNETSRV_SHRMOD 8 +#define TELNETSRV_LOOPC 4 +#define TELNETSRV_LOOPD 5 +#define TELNETSRV_HISFILE 6 +#define TELNETSRV_HISSIZE 7 +#define TELNETSRV_PHYBSIZE 8 +#define TELNETSRV_STATICMOD 9 +#define TELNETSRV_SHRMOD 10 + paramdef_t telnetoptions[] = { /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* configuration parameters for telnet utility */ @@ -72,19 +79,22 @@ paramdef_t telnetoptions[] = { /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ {"listenaddr", "<listen ip address>", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 }, {"listenport", "<local port>", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 }, - {"priority", "<scheduling policy (0-99)", 0, uptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 }, + {"priority", "<scheduling policy (0-99)", 0, iptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 }, {"debug", "<debug level>", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 }, {"loopcount", "<loop command iterations>", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 }, {"loopdelay", "<loop command delay (ms)>", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 }, + {"histfile", "<history file name>", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 }, + {"histsize", "<history sizes>", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 }, {"phypbsize", "<phy dump buff size (bytes)>",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 }, - {"staticmod", "<static modules selection>", 0, NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,1}, - {"shrmod", "<static modules selection>", 0, NULL, NULL,TYPE_STRINGLIST,0 }, + {"staticmod", "<static modules selection>", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))}, + {"shrmod", "<dynamic modules selection>", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 } }; -int get_phybsize() {return telnetparams.phyprntbuff_size; }; +int get_phybsize(void) {return telnetparams.phyprntbuff_size; }; int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd ); int setoutput(char *buff, int debug, telnet_printfunc_t prnt); int setparam(char *buff, int debug, telnet_printfunc_t prnt); +int history_cmd(char *buff, int debug, telnet_printfunc_t prnt); telnetshell_vardef_t telnet_vardef[] = { {"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg}, @@ -92,12 +102,15 @@ telnetshell_vardef_t telnet_vardef[] = { {"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount}, {"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay}, {"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size}, +{"hsize",TELNET_VARTYPE_INT32,&telnetparams.histsize}, +{"hfile",TELNET_VARTYPE_STRING,&telnetparams.histfile}, {"",0,NULL} }; telnetshell_cmddef_t telnet_cmdarray[] = { {"redirlog","[here,file,off]",setoutput}, {"param","[prio]",setparam}, + {"history","[list,reset]",history_cmd}, {"","",NULL}, }; @@ -131,41 +144,54 @@ char strpolicy[10]; //sched_get_priority_max(SCHED_FIFO) -if (priority < NICE_MIN) - { +if (priority < NICE_MIN) { policy=SCHED_FIFO; sprintf(strpolicy,"%s","fifo"); - schedp.sched_priority= NICE_MIN - priority ; + schedp.sched_priority= NICE_MIN - priority ; + if ( (schedp.sched_priority < sched_get_priority_min(SCHED_FIFO)) || + (schedp.sched_priority > sched_get_priority_max(SCHED_FIFO)) ) { + client_printf("Error: %i invalid prio, should be %i to %i, \n", + priority, NICE_MIN -sched_get_priority_min(SCHED_FIFO), + NICE_MIN - sched_get_priority_max(SCHED_FIFO) ); } -else if (priority > NICE_MAX) - { +} else if (priority > NICE_MAX) { policy=SCHED_IDLE; sprintf(strpolicy,"%s","idle"); schedp.sched_priority=0; - } -else - { +} else { policy=SCHED_OTHER; sprintf(strpolicy,"%s","other"); schedp.sched_priority=0; - } -if( tid != 0) - { +} + +if( tid != 0) { rt = pthread_setschedparam(tid, policy, &schedp); - } -else if(pid > 0) - { +} else if(pid > 0) { rt = sched_setscheduler( pid, policy,&schedp); - } -if (rt != 0) - { +} else { + rt= -1; + client_printf("Error: no pid or tid specified\n"); +} + +if (rt != 0) { client_printf("Error %i: %s modifying sched param to %s:%i, \n", errno,strerror(errno),strpolicy,schedp.sched_priority); - } -else - { +} else { client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority); + if ( policy==SCHED_OTHER) { + rt = getpriority(PRIO_PROCESS,tid); + if (rt != -1) { + rt = setpriority(PRIO_PROCESS,tid,priority); + if (rt < 0) { + client_printf("Error %i: %s trying to set nice value of thread %u to %i\n", + errno,strerror(errno),tid,priority); + } + } else { + client_printf("Error %i: %s trying to get nice value of thread %u \n", + errno,strerror(errno),tid); + } } +} @@ -198,14 +224,13 @@ int rt; CPU_ZERO(&cpuset); CPU_SET(coreid, &cpuset); - if (tid > 0) - { + if (tid > 0) { rt = pthread_setaffinity_np((pthread_t)tid, sizeof(cpu_set_t), &cpuset); - } - else if (pid > 0) - { + } else if (pid > 0){ rt = sched_setaffinity((pid_t)pid, sizeof(cpu_set_t), &cpuset); - } + } else { + rt= -1; + } if (rt != 0) { client_printf("Error %i: %s calling , xxx_setaffinity...\n",errno,strerror(errno)); @@ -284,7 +309,6 @@ memset(cmds,0,sizeof(cmds)); sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] ); if (strncasecmp(cmds[0],"prio",4) == 0) { - pthread_attr_t attr; int prio; prio=(int)strtol(cmds[1],NULL,0); if (errno == ERANGE) @@ -305,6 +329,35 @@ if (strncasecmp(cmds[0],"aff",3) == 0) return CMDSTATUS_NOTFOUND; } /* setparam */ + +int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ +char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE]; + + +memset(cmds,0,sizeof(cmds)); +sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] ); +if (cmds[0] == NULL) + return CMDSTATUS_VARNOTFOUND; +if (strncasecmp(cmds[0],"list",4) == 0) + { + HIST_ENTRY **hist = history_list(); + if (hist) { + for (int i = 0; hist[i]; i++) { + prnt ("%d: %s\n", i + history_base, hist[i]->line); + } + } + return CMDSTATUS_FOUND; + } +if (strncasecmp(cmds[0],"reset",5) == 0) + { + clear_history(); + write_history(telnetparams.histfile); + return CMDSTATUS_FOUND; + } + +return CMDSTATUS_NOTFOUND; +} /* history_cmd */ /*-------------------------------------------------------------------------------------------------------*/ /* generic commands available for all modules loaded by the server @@ -314,11 +367,11 @@ int setgetvar(int moduleindex,char getorset,char *params) { int n,i; char varname[TELNET_CMD_MAXSIZE]; -char varval[TELNET_CMD_MAXSIZE]; +char *varval=NULL; memset(varname,0,sizeof(varname)); - memset(varval,0,sizeof(varval)); - n = sscanf(params,"%s %s",varname,varval); + + n = sscanf(params,"%s %ms",varname,&varval); for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) { if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) @@ -330,7 +383,10 @@ char varval[TELNET_CMD_MAXSIZE]; switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) { case TELNET_VARTYPE_INT32: - client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + client_printf("%i\n",*(int32_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_INT64: + client_printf("%lli\n",*(int64_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; case TELNET_VARTYPE_INT16: client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); @@ -338,8 +394,8 @@ char varval[TELNET_CMD_MAXSIZE]; case TELNET_VARTYPE_DOUBLE: client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; - case TELNET_VARTYPE_PTR: - client_printf("0x%08x\n",*((unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr))); + case TELNET_VARTYPE_STRING: + client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; default: client_printf("unknown type\n"); @@ -364,6 +420,10 @@ char varval[TELNET_CMD_MAXSIZE]; case TELNET_VARTYPE_DOUBLE: *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL); client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_STRING: + sprintf(*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr),"%s", varval); + client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; default: client_printf("unknown type\n"); @@ -372,6 +432,9 @@ char varval[TELNET_CMD_MAXSIZE]; } } } +if (n>1 && varval != NULL) { + free(varval); +} return CMDSTATUS_VARNOTFOUND; } /*----------------------------------------------------------------------------------------------------*/ @@ -515,13 +578,14 @@ if(listen(sock, 1) == -1) fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno)); +using_history(); printf("\nInitializing telnet server...\n"); while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) { printf("[TELNETSRV] Telnet client connected....\n"); - - + read_history(telnetparams.histfile); + stifle_history(telnetparams.histsize); if(telnetparams.new_socket < 0) fprintf(stderr,"[TELNETSRV] Error %s on accept call\n",strerror(errno)); @@ -548,31 +612,43 @@ while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) break; } if (telnetparams.telnetdbg > 0) - printf("[TELNETSRV] Command received: readc %i filled %i %s\n", readc, filled ,buf); - if (strlen(buf) >= 2 ) + printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf); + if (buf[0] == '!') { + if (buf[1] == '!') { + sprintf(buf,"%s","telnet history list"); + } else { + HIST_ENTRY *hisentry = history_get(strtol(buf+1,NULL,0)); + if (hisentry) { + char msg[TELNET_MAX_MSGLENGTH + sizeof(TELNET_PROMPT) +10]; + sprintf(buf,"%s",hisentry->line); + sprintf(msg,"%s %s\n",TELNET_PROMPT, hisentry->line); + send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL); + } + } + } + if (strlen(buf) > 2 ) { status=process_command(buf); } else status=CMDSTATUS_NOCMD; - if (status != CMDSTATUS_EXIT) - { - if (status == CMDSTATUS_NOTFOUND) - { + if (status != CMDSTATUS_EXIT) { + if (status == CMDSTATUS_NOTFOUND) { char msg[TELNET_MAX_MSGLENGTH + 50]; sprintf(msg,"Error: \n %s\n is not a softmodem command\n",buf); send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL); - } + } else if (status == CMDSTATUS_FOUND) { + add_history(buf); + } send(telnetparams.new_socket, TELNET_PROMPT, sizeof(TELNET_PROMPT), MSG_NOSIGNAL); - } - else - { + } else { printf ("[TELNETSRV] Closing telnet connection...\n"); break; - } + } } - + write_history(telnetparams.histfile); + clear_history(); close(telnetparams.new_socket); printf ("[TELNETSRV] Telnet server waitting for connection...\n"); } @@ -588,7 +664,7 @@ return; */ void exec_moduleinit(char *modname) { -void (*fptr)(); +void (*fptr)(void); char initfunc[TELNET_CMD_MAXSIZE+9]; if (strlen(modname) > TELNET_CMD_MAXSIZE) @@ -609,23 +685,26 @@ char initfunc[TELNET_CMD_MAXSIZE+9]; } } -int add_embeddedmodules() +int add_embeddedmodules(void) { - +int ret=0; for(int i=0; i<telnetoptions[TELNETSRV_STATICMOD].numelt;i++) { + ret++; exec_moduleinit(telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]); } +return ret; + } -int add_sharedmodules() +int add_sharedmodules(void) { char initfunc[TELNET_CMD_MAXSIZE+9]; -void (*fptr)(); - +void (*fptr)(void); +int ret=0; for(int i=0; i<telnetoptions[TELNETSRV_SHRMOD].numelt;i++) { @@ -634,22 +713,23 @@ void (*fptr)(); if ( fptr != NULL) { fptr(); + ret++; } else { fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]); } } + return ret; } -int init_telnetsrv(char *cfgfile) +int telnetsrv_autoinit(void) { - void *lib_handle; - char** moduleslist; + memset(&telnetparams,0,sizeof(telnetparams)); - config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),NULL); + config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),"telnetsrv"); if(pthread_create(&telnetparams.telnet_pthread,NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0) @@ -691,6 +771,26 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde } +/* function which will be called by the shared lib loader, to check shared lib version + against main exec version. version mismatch no considered as fatal (interfaces not supposed to change) +*/ +int telnetsrv_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion) +{ +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__ +#endif + *shlib_buildversion = PACKAGE_VERSION; + if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) { + fprintf(stderr,"[TELNETSRV] shared lib version %s, doesn't match main version %s, compatibility should be checked\n", + mainexec_buildversion,*shlib_buildversion); + } + return 0; +} - - +int telnetsrv_getfarray(loader_shlibfunc_t **farray) + { + *farray=malloc(sizeof(loader_shlibfunc_t)); + (*farray)[0].fname=TELNET_ADDCMD_FNAME; + (*farray)[0].fptr=(int (*)(void) )add_telnetcmd; + return 1; + } diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index c8cad58784df9381f1040b0200d3597b838df3df..2d3ef531aee8494ad080f00f42c9b42c1934eb50 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -18,7 +18,6 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - /*! \file common/utils/telnetsrv/telnetsrv.h * \brief: include file for telnet server implementation * \author Francois TABURET @@ -38,7 +37,7 @@ #define TELNET_MAX_MSGLENGTH 2048 #define TELNET_PROMPT "softmodem> " #define TELNET_MAXCMD 20 -#define TELNET_CMD_MAXSIZE 10 +#define TELNET_CMD_MAXSIZE 20 #define TELNET_HELPSTR_SIZE 80 /* status return by the command parser after it analysed user input */ @@ -70,7 +69,7 @@ typedef struct cmddef { #define TELNET_VARTYPE_INT64 3 #define TELNET_VARTYPE_STRING 4 #define TELNET_VARTYPE_DOUBLE 5 -#define TELNET_VARTYPE_PTR 6 +//#define TELNET_VARTYPE_PTR 6 typedef struct variabledef { char varname[TELNET_CMD_MAXSIZE]; char vartype; @@ -96,6 +95,8 @@ typedef struct { pthread_t telnet_pthread; // thread id of the telnet server int telnetdbg; // debug level of the server int priority; // server running priority + char *histfile; // command history + int histsize; // command history length int new_socket; // socket of the client connection int logfilefd; // file id of the log file when log output is redirected to a file int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout @@ -130,10 +131,12 @@ VT escape sequence definition, for smarter display.... #define STDFMT "\x1b[0m" /*---------------------------------------------------------------------------------------------*/ +#define TELNET_ADDCMD_FNAME "add_telnetcmd" +typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); #ifdef TELNETSERVERCODE int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); void set_sched(pthread_t tid, int pid,int priority); void set_affinity(pthread_t tid, int pid, int coreid); -extern int get_phybsize(); +extern int get_phybsize(void); #endif #endif diff --git a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5dee7db4c41fef1d5c3f96b18eb770d64e044054 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt @@ -0,0 +1,28 @@ + + +set(TELNETROOT ${OPENAIR_DIR}/common/utils/telnetsrv ) + + + +set(TELNETSRV_SOURCE + ${TELNETROOT}/telnetsrv.c + ${TELNETROOT}/telnetsrv_phycmd.c + ${TELNETROOT}/telnetsrv_proccmd.c + ${TELNETROOT}/telnetsrv_loader.c + ) + +#set(TELNETSRV_ETHDEVCMD_SOURCE +# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c +# ) + + + +add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} ) +#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} ) +target_link_libraries(telnetsrv PRIVATE history) + +install(TARGETS telnetsrv DESTINATION bin) + +if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") + install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build) +endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") diff --git a/common/utils/telnetsrv/telnetsrv_loader.c b/common/utils/telnetsrv/telnetsrv_loader.c new file mode 100644 index 0000000000000000000000000000000000000000..a23e25eb835fbd3a728424a7afb4a8991a179caa --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_loader.c @@ -0,0 +1,84 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 common/utils/telnetsrv/telnetsrv_loader.c + * \brief: implementation of telnet commands related to softmodem linux process + * \author Francois TABURET + * \date 2018 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include <string.h> +#include <pthread.h> + + +#define TELNETSERVERCODE +#include "telnetsrv.h" +#define TELNETSRV_LOADER_MAIN +#include "telnetsrv_loader.h" + + +int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); +telnetshell_cmddef_t loader_cmdarray[] = { + {"show","[params,modules]",loader_show_cmd}, + {"","",NULL}, +}; + + +/*-------------------------------------------------------------------------------------*/ +int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ + if (debug > 0) + prnt( "loader_show_cmd received %s\n",buff); + + if (strcasestr(buff,"params") != NULL) { + prnt( "loader parameters:\n"); + prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion); + prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath); + prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs); + } + else if (strcasestr(buff,"modules") != NULL) { + prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs); + for (int i=0 ; i<loader_data.numshlibs ; i++) { + prnt( " Module %i: %s\n", i,loader_data.shlibs[i].name); + prnt( " Shared library build version: \"%s\"\n",((loader_data.shlibs[i].shlib_buildversion == NULL )?"":loader_data.shlibs[i].shlib_buildversion)); + prnt( " Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path); + prnt( " %i function pointers registered:\n", loader_data.shlibs[i].numfunc); + for(int j=0 ; j<loader_data.shlibs[i].numfunc;j++) { + prnt( " function %i %s at %p\n",j, + loader_data.shlibs[i].funcarray[j].fname, loader_data.shlibs[i].funcarray[j].fptr); + } + } + } else { + prnt("%s: wrong loader command...\n",buff); + } + return 0; +} + +void add_loader_cmds(void) +{ + + add_telnetcmd("loader", loader_globalvardef, loader_cmdarray); +} diff --git a/common/utils/telnetsrv/telnetsrv_loader.h b/common/utils/telnetsrv/telnetsrv_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..404aabfc7019b2ccf82f718e145696bb63584ca3 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_loader.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 common/utils/telnetsrv_proccmd.h + * \brief: Include file defining telnet commands related to softmodem linux process + * \author Francois TABURET + * \date 2018 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + +#ifdef TELNETSRV_LOADER_MAIN + +#include "UTIL/LOG/log.h" + + +#include "common/utils/load_module_shlib.h" + + +telnetshell_vardef_t loader_globalvardef[] = { +{"mainversion",TELNET_VARTYPE_STRING,&(loader_data.mainexec_buildversion)}, +{"defpath",TELNET_VARTYPE_STRING,&(loader_data.shlibpath)}, +{"maxshlibs",TELNET_VARTYPE_INT32,&(loader_data.maxshlibs)}, +{"numshlibs",TELNET_VARTYPE_INT32,&(loader_data.numshlibs)}, +{"",0,NULL} +}; +telnetshell_vardef_t *loader_modulesvardef; + +extern void add_loader_cmds(void); + +#endif + +/*-------------------------------------------------------------------------------------*/ + diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c index 6867d5deeef8fde9baa5880ca5f3bc28f043525c..c60126f1c741e4d9d93323e761862d0f7458e561 100644 --- a/common/utils/telnetsrv/telnetsrv_phycmd.c +++ b/common/utils/telnetsrv/telnetsrv_phycmd.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -41,7 +41,7 @@ char *prnbuff; extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length); -void init_phytelnet() +void init_phytelnet(void) { prnbuff=malloc(get_phybsize() ); if (prnbuff == NULL) @@ -134,7 +134,7 @@ telnetshell_cmddef_t phy_cmdarray[] = { /*-------------------------------------------------------------------------------------*/ -void add_phy_cmds() +void add_phy_cmds(void) { init_phytelnet(); diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.h b/common/utils/telnetsrv/telnetsrv_phycmd.h index 3922bda727c0e140d3e4529c81dd167cbb21df29..6e2b0ecacff74813b6635436dfea3fc6078995e9 100644 --- a/common/utils/telnetsrv/telnetsrv_phycmd.h +++ b/common/utils/telnetsrv/telnetsrv_phycmd.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -42,8 +42,6 @@ #define TELNETVAR_PHYCC1 1 telnetshell_vardef_t phy_vardef[] = { -{"phycc1",TELNET_VARTYPE_PTR,NULL}, -{"phycc2",TELNET_VARTYPE_PTR,NULL}, //{"iqmax",TELNET_VARTYPE_INT16,NULL}, //{"iqmin",TELNET_VARTYPE_INT16,NULL}, //{"loglvl",TELNET_VARTYPE_INT32,NULL}, @@ -57,7 +55,7 @@ telnetshell_vardef_t phy_vardef[] = { #else -extern void add_phy_cmds(); +extern void add_phy_cmds(void); #endif diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index 82c4549faeab7b7eaf79ec00f5a145fdfb7717d7..91f0e9c93a591f04bb85ddd991c8cf9d2e1142cd 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -54,6 +54,8 @@ #define TELNETSRV_PROCCMD_MAIN #include "log.h" #include "log_extern.h" +#include "common/config/config_userapi.h" +#include "openair1/PHY/extern.h" #include "telnetsrv_proccmd.h" void decode_procstat(char *record, int debug, telnet_printfunc_t prnt) @@ -70,14 +72,13 @@ char toksep[2]; lptr= prntline; /*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */ - while( procfile_fiels != NULL && fieldcnt < 42) - { + while( procfile_fiels != NULL && fieldcnt < 42) { + long int policy; if (strlen(procfile_fiels) == 0) continue; fieldcnt++; sprintf(toksep," "); - switch(fieldcnt) - { + switch(fieldcnt) { case 1: /* id */ lptr+=sprintf(lptr,"%9.9s ",procfile_fiels); sprintf(toksep,")"); @@ -104,12 +105,36 @@ char toksep[2]; break; case 41: //policy lptr+=sprintf(lptr,"%3.3s ",procfile_fiels); + policy=strtol(procfile_fiels,NULL,0); + switch(policy) { + case SCHED_FIFO: + lptr+=sprintf(lptr,"%s ","rt: fifo"); + break; + case SCHED_OTHER: + lptr+=sprintf(lptr,"%s ","other"); + break; + case SCHED_IDLE: + lptr+=sprintf(lptr,"%s ","idle"); + break; + case SCHED_BATCH: + lptr+=sprintf(lptr,"%s ","batch"); + break; + case SCHED_RR: + lptr+=sprintf(lptr,"%s ","rt: rr"); + break; + case SCHED_DEADLINE: + lptr+=sprintf(lptr,"%s ","rt: deadline"); + break; + default: + lptr+=sprintf(lptr,"%s ","????"); + break; + } break; default: break; - }/* switch on fieldcnr */ + }/* switch on fieldcnr */ procfile_fiels =strtok_r(NULL,toksep,&strtokptr); - } /* while on proc_fields != NULL */ + } /* while on proc_fields != NULL */ prnt("%s\n",prntline); } /*decode_procstat */ @@ -141,7 +166,7 @@ char aname[256]; DIR *proc_dir; struct dirent *entry; -int rt; + prnt(" id name state USRmod KRNmod prio nice vsize proc pol \n\n"); snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid()); @@ -172,14 +197,51 @@ extern log_t *g_log; if (debug > 0) prnt(" proccmd_show received %s\n",buf); - if (strcasestr(buf,"thread") != NULL) - { + if (strcasestr(buf,"thread") != NULL) { print_threads(buf,debug,prnt); - } + } if (strcasestr(buf,"loglvl") != NULL) { - for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++){ - prnt("\t%s:\t%s\t%s\n",g_log->log_component[i].name, map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), - map_int_to_str(log_level_names,g_log->log_component[i].level)); + prnt("component verbosity level enabled\n"); + for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + prnt("%02i %17.17s:%10.10s%10.10s %s\n",i ,g_log->log_component[i].name, + map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), + map_int_to_str(log_level_names,g_log->log_component[i].level), + ((g_log->log_component[i].interval>0)?"Y":"N") ); + } + } + if (strcasestr(buf,"config") != NULL) { + prnt("Command line arguments:\n"); + for (int i=0; i < config_get_if()->argc; i++) { + prnt(" %02i %s\n",i ,config_get_if()->argv[i]); + } + prnt("Config module flags ( -O <cfg source>:<xxx>:dbgl<flags>): 0x%08x\n", config_get_if()->rtflags); + + prnt(" Print config debug msg, params values (flag %u): %s\n",CONFIG_PRINTPARAMS, + ((config_get_if()->rtflags & CONFIG_PRINTPARAMS) ? "Y" : "N") ); + prnt(" Print config debug msg, memory management(flag %u): %s\n",CONFIG_DEBUGPTR, + ((config_get_if()->rtflags & CONFIG_DEBUGPTR) ? "Y" : "N") ); + prnt(" Print config debug msg, command line processing (flag %u): %s\n",CONFIG_DEBUGCMDLINE, + ((config_get_if()->rtflags & CONFIG_DEBUGCMDLINE) ? "Y" : "N") ); + prnt(" Don't exit if param check fails (flag %u): %s\n",CONFIG_NOABORTONCHKF, + ((config_get_if()->rtflags & CONFIG_NOABORTONCHKF) ? "Y" : "N") ); + prnt("Config source: %s, parameters:\n",CONFIG_GETSOURCE ); + for (int i=0; i < config_get_if()->num_cfgP; i++) { + prnt(" %02i %s\n",i ,config_get_if()->cfgP[i]); + } + prnt("Softmodem components:\n"); + prnt(" %02i Ru(s)\n", RC.nb_RU); + prnt(" %02i lte RRc(s), %02i NbIoT RRC(s)\n", RC.nb_inst, RC.nb_nb_iot_rrc_inst); + prnt(" %02i lte MACRLC(s), %02i NbIoT MACRLC(s)\n", RC.nb_macrlc_inst, RC.nb_nb_iot_macrlc_inst); + prnt(" %02i lte L1, %02i NbIoT L1\n", RC.nb_L1_inst, RC.nb_nb_iot_L1_inst); + + for(int i=0; i<RC.nb_inst; i++) { + prnt(" lte RRC %i: %02i CC(s) \n",i,((RC.nb_CC == NULL)?0:RC.nb_CC[i])); + } + for(int i=0; i<RC.nb_L1_inst; i++) { + prnt(" lte L1 %i: %02i CC(s)\n",i,((RC.nb_L1_CC == NULL)?0:RC.nb_L1_CC[i])); + } + for(int i=0; i<RC.nb_macrlc_inst; i++) { + prnt(" lte macrlc %i: %02i CC(s)\n",i,((RC.nb_mac_CC == NULL)?0:RC.nb_mac_CC[i])); } } return 0; @@ -190,12 +252,16 @@ int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt) int bv1,bv2; int res; char sv1[64]; -char tname[32]; + bv1=0; bv2=0; sv1[0]=0; if (debug > 0) prnt("proccmd_thread received %s\n",buf); + if (strcasestr(buf,"help") != NULL) { + prnt(PROCCMD_THREAD_HELP_STRING); + return 0; + } res=sscanf(buf,"%i %9s %i",&bv1,sv1,&bv2); if (debug > 0) prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2); @@ -231,32 +297,95 @@ extern void exit_fun(const char* s); return 0; } + int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt) { int idx1=0; int idx2=NUM_LOG_LEVEL-1; -int s = sscanf(buf,"%*s %i-%i",&idx1,&idx2); +char *logsubcmd=NULL; + +int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); if (debug > 0) - prnt("process module received %s\n",buf); + prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd)); + + if (s == 1 && logsubcmd != NULL) { + if (strcasestr(logsubcmd,"online") != NULL) { + if (strcasestr(buf,"noonline") != NULL) { + set_glog_onlinelog(0); + prnt("online logging disabled\n",buf); + } else { + set_glog_onlinelog(1); + prnt("online logging enabled\n",buf); + } + } + else if (strcasestr(logsubcmd,"show") != NULL) { + prnt("Available log levels: \n "); + for (int i=0; log_level_names[i].name != NULL; i++) + prnt("%s ",log_level_names[i].name); + prnt("\nAvailable verbosity: \n "); + for (int i=0; log_verbosity_names[i].name != NULL; i++) + prnt("%s ",log_verbosity_names[i].name); + prnt("\n"); + proccmd_show("loglvl",debug,prnt); + } + else if (strcasestr(logsubcmd,"help") != NULL) { + prnt(PROCCMD_LOG_HELP_STRING); + } else { + prnt("%s: wrong log command...\n",logsubcmd); + } + } else if ( s == 3 && logsubcmd != NULL) { + int level, verbosity, interval; + char *tmpstr=NULL; + char *logparam=NULL; + int l; + + level = verbosity = interval = -1; + l=sscanf(logsubcmd,"%m[^'_']_%m[^'_']",&logparam,&tmpstr); + if (debug > 0) + prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr)); + if (l ==2 ) { + if (strcmp(logparam,"level") == 0) { + level=map_str_to_int(log_level_names,tmpstr); + if (level < 0) prnt("level %s unknown\n",tmpstr); + } else if (strcmp(logparam,"verbos") == 0) { + verbosity=map_str_to_int(log_verbosity_names,tmpstr); + if (verbosity < 0) prnt("verbosity %s unknown\n",tmpstr); + } else { + prnt("%s%s unknown log sub command \n",logparam, tmpstr); + } + } else if (l ==1 ) { + if (strcmp(logparam,"enable") == 0) { + interval = 1; + } else if (strcmp(logparam,"disable") == 0) { + interval = 0; + } else { + prnt("%s%s unknown log sub command \n",logparam, tmpstr); + } + } else { + prnt("%s unknown log sub command \n",logsubcmd); + } + if (logparam != NULL) free(logparam); + if (tmpstr != NULL) free(tmpstr); + for (int i=idx1; i<=idx2 ; i++) { + set_comp_log(i, level, verbosity, interval); + prnt("log level/verbosity comp %i %s set to %s / %s (%s)\n", + i,((g_log->log_component[i].name==NULL)?"":g_log->log_component[i].name), + map_int_to_str(log_level_names,g_log->log_component[i].level), + map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), + ((g_log->log_component[i].interval>0)?"enabled":"disabled")); + + + } + } else { + prnt("%s: wrong log command...\n",buf); + } - if (strcasestr(buf,"enable") != NULL) - { - set_glog_onlinelog(1); - } - if (strcasestr(buf,"disable") != NULL) - { - set_glog_onlinelog(0); - } - if (strcasestr(buf,"show") != NULL) - { - proccmd_show("loglvl",debug,prnt); - } return 0; } /*-------------------------------------------------------------------------------------*/ -void add_softmodem_cmds() +void add_softmodem_cmds(void) { add_telnetcmd("softmodem",proc_vardef,proc_cmdarray); } diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.h b/common/utils/telnetsrv/telnetsrv_proccmd.h index d7fd0a6e2497df81bca617989ad142e5356997bd..b2c05315d8a46e2e1a989beefe775d5c53d8b21d 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.h +++ b/common/utils/telnetsrv/telnetsrv_proccmd.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -19,6 +19,7 @@ * contact@openairinterface.org */ + /*! \file common/utils/telnetsrv/telnetsrv_proccmd.h * \brief: Include file defining telnet commands related to this linux process * \author Francois TABURET @@ -43,15 +44,33 @@ extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt); telnetshell_vardef_t proc_vardef[] = { {"",0,NULL} }; +#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\ + show: display current log configuration \n\ + online, noonline: enable or disable console logs \n\ + enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\ + level_<level> id1-id2: set log level to <level> for components index id1 to id2 \n\ + level_<verbosity> id1-id2: set log verbosity to <verbosity> for components index id1 to id2 \n\ +use the show command to get the values for <level>, <verbosity> and the list of component indexes \ +that can be used for id1 and id2 \n" + +#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\ + <thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\ + <thread id> prio <prio> : set scheduling parameters for thread <thread id> \n\ + if prio < -20: linux scheduling policy set to FIFO, \n\ + with priority = -20 - prio \n\ + if prio > 19: linux scheduling policy set to OTHER, \n\ + with priority (nice value) = prio \n\ + use \"softmodem show thread\" to get <thread id> \n" + telnetshell_cmddef_t proc_cmdarray[] = { - {"show","loglvl|thread", proccmd_show}, - {"log","[enable,disable]", proccmd_log}, - {"thread","<id> aff|prio <aff|prio>", proccmd_thread}, + {"show","loglvl|thread|config", proccmd_show}, + {"log","(enter help for details)", proccmd_log}, + {"thread","(enter help for details)", proccmd_thread}, {"exit","", proccmd_exit}, {"","",NULL}, }; #else -extern void add_proccmd_cmds(); +extern void add_proccmd_cmds(void); #endif /* TELNETSRV_PROCCMD_MAIN */ diff --git a/d2d_emulator_setup.txt b/d2d_emulator_setup.txt new file mode 100644 index 0000000000000000000000000000000000000000..ef904066bc28d55eb345f9957e8751498c31e95e --- /dev/null +++ b/d2d_emulator_setup.txt @@ -0,0 +1,107 @@ +Scenario 1 : Off-network UE2UE link +SynchREF UE (UE1) + +UE1(eth0 - 10.10.10.1)--------UE2(eno1 - 10.10.10.2) + +Here's an example of /etc/network/interfaces configuration for UE1 +auto eth0 + iface eth0 inet static + address 10.10.10.1 + netmask 255.255.255.0 + gateway 10.10.10.1 + +Prepare the environment: + - git clone https://gitlab.eurecom.fr/matzakos/LTE-D2D.git #branch: master +This branch contains all the current development for DDPS + - UE MAC<-> UE MAC for Scenario 1 + - eNB MAC<->UE MAC (NFAPI Transport) + - RRC Extensions for “on-network†cases + +NFAPI configuration (required even for Scenario 1 target) + - git clone https://github.com/cisco/open-nFAPI.git + - cd open-nfapi + - patch -p1 --dry-run < $OPENAIR_HOME/open-nfapi.oai.patch +Validate that there are no errors + - patch -p1 < $OPENAIR_HOME/open-nfapi.oai.patch + +OAI build/execute + - export NFAPI_DIR=XXX (place where NFAPI was installed) + - cd cmake_targets + - ./build_oai --UE + (if necessary, use ./build_oai -I --UE to install required packages) + - cd lte_build_oai/build/ + - cp ../../../targets/bin/.ue* . + - cp ../../../targets/bin/.usim* . + - sudo insmod ../../../targets/bin/ue_ip.ko + +UE1: + - sudo ifconfig oip0 10.0.0.1 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3 + - (if necessary) sudo route add default gw 10.10.10.1 eth0 +UE2: + - sudo ifconfig oip0 10.0.0.2 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3 + - (if necessary) sudo route add default gw 10.10.10.1 eno1 + +UE1 and UE2: Get and build vencore_app from d2d-l3-stub (branch: l3_stub) + - gcc -I . vencore_app.c -o vencore_app -lpthread + +-------------------------------- +TEST ONE-TO-MANY +Run UE1 then UE2, for example: +UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0 +UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1 + +Test with Ping +- Sender - UE1: ping -I oip0 224.0.0.3 +- Receiver - UE2: using wireshark + +Test with Iperf +- Sender - UE1: iperf -c 224.0.0.3 -u -b 0.1M --bind 10.0.0.1 -t 100 +- Receiver - UE2: sudo ./mcreceive 224.0.0.3 5001 + +Filter the incomming packets according to GroupL2Id: receiver (one-to-many) can discard the packets if it doesn't belong to this group. +For the moment, both sender and receiver use the same set of Ids (hardcoded) + +UE1 (sender) + - sudo ./lte-softmodem-stub -U --emul-iface eth0 + - ./vencore_app #send the sourceL2Id, groupL2Id to OAI + - ping -I oip0 224.0.0.3 + UE2(receiver) + - sudo ./lte-softmodem-stub -U --emul-iface eno1 + #we can see the incomming packets from OAI log, however, cannot see from Wireshark -> they are discarded at MAC layer + - ./vencore_app #we can see the packets appearing in Wireshark + + -------------------------------------- +TEST PC5-S (UE1 -sender, UE2 - receiver) and PC5-U for ONE-TO-ONE scenario +Configure UE1/UE2 +UE1: + - sudo ifconfig oip0 10.0.0.1 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.2 -j MARK --set-mark 3 + - sudo route add default gw 10.10.10.1 eth0 +UE2: + - sudo ifconfig oip0 10.0.0.2 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.1 -j MARK --set-mark 3 + - sudo route add default gw 10.10.10.1 eno1 + +step 1: +- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0 +step 2: +- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1 +- UE2: ./vencore_app -r #listen to incomming message from PC5-S +step 3: +- UE1: ./vencore_app -s #send a message via PC5-S (e.g., DirectCommunicationRequest) + +Generate unicast traffic +UE1: ping -I oip0 10.0.0.2 + + + -------------------------------------- +TEST PC5-D +step 1: +- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0 +- UE1: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D +step 2: +- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1 +- UE2: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D + diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 9d75407cb94d6cbfc5e21e6192ecd73d096110a9..09f37b994567f4664134cb99cf314f41819cd606 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -32,6 +32,7 @@ #include "nfapi.h" #include "nfapi_pnf.h" #include "common/ran_context.h" +#include "openair2/PHY_INTERFACE/phy_stub_UE.h" //#include "openair1/PHY/vars.h" extern RAN_CONTEXT_t RC; @@ -47,7 +48,10 @@ extern RAN_CONTEXT_t RC; #include "fapi_stub.h" //#include "fapi_l1.h" #include "UTIL/LOG/log.h" -#include "openair2/LAYER2/MAC/proto.h" +#include "openair2/LAYER2/MAC/mac_proto.h" + +#include "PHY/INIT/phy_init.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" #define NUM_P5_PHY 2 @@ -61,8 +65,10 @@ extern pthread_mutex_t nfapi_sync_mutex; extern int nfapi_sync_var; extern int sync_var; +char uecap_xer_in; extern void init_eNB_afterRU(void); +extern void init_UE_stub(int nb_inst,int,int); extern void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu); extern void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present); extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu); @@ -508,9 +514,31 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap pnf_info* pnf = (pnf_info*)(config->user_data); uint8_t num_tlv = 0; - struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + + // Panos: In the case of nfapi_mode = 3 (UE = PNF) we should not have dependency on any eNB var. So we aim + // to keep only the necessary just to keep the nfapi FSM rolling by sending a dummy response. + LTE_DL_FRAME_PARMS *fp; + if (nfapi_mode!=3) { + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + fp = &eNB->frame_parms; + } + else{ + fp = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); + } + + +#if 0 + //DJP + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.id == req->header.phy_id; }); + if(found != pnf->phys.end()) + { + phy_info& phy_info = (*found); + } +#endif + //DJP phy_info* phy_info = pnf->phys; if(req->nfapi_config.timing_window.tl.tag == NFAPI_NFAPI_TIMING_WINDOW_TAG) { @@ -667,6 +695,7 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap num_tlv++; } + if(nfapi_mode!=3) { printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv); printf("[PNF] Simulating PHY CONFIG - DJP\n"); @@ -678,6 +707,7 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap phy_config_request(&phy_config); dump_frame_parms(fp); + } phy_info->remote_port = req->nfapi_config.p7_vnf_port.value; @@ -695,6 +725,8 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap nfapi_resp.error_code = 0; // DJP - some value resp->error_code; nfapi_pnf_config_resp(config, &nfapi_resp); printf("[PNF] Sent NFAPI_CONFIG_RESPONSE phy_id:%d\n", phy_info->id); + if(nfapi_mode ==3) + free(fp); return 0; } @@ -1085,6 +1117,7 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi } if(phy_info->timing_info_mode & 0x2) { + //printf("Panos-D: start_request () Enabling timing_info_mode_aperiodic \n"); p7_config->timing_info_mode_aperiodic = 1; } @@ -1094,77 +1127,110 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi p7_config->tx_req = &pnf_phy_tx_req; p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; - memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req)); - dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1; - dummy_dl_config_req.dl_config_request_body.number_dci=0; - dummy_dl_config_req.dl_config_request_body.number_pdu=0; - dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0; - dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000; - dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0; + if (nfapi_mode==3) { + p7_config->dl_config_req = &memcpy_dl_config_req; + p7_config->ul_config_req = &memcpy_ul_config_req; + p7_config->hi_dci0_req = &memcpy_hi_dci0_req; + p7_config->tx_req = &memcpy_tx_req; + } + else { + p7_config->dl_config_req = &pnf_phy_dl_config_req; + p7_config->ul_config_req = &pnf_phy_ul_config_req; + p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; + p7_config->tx_req = &pnf_phy_tx_req; + } + p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; - memset(&dummy_tx_req, 0, sizeof(dummy_tx_req)); - dummy_tx_req.tx_request_body.number_of_pdus=0; - dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG; + memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req)); + dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1; + dummy_dl_config_req.dl_config_request_body.number_dci=0; + dummy_dl_config_req.dl_config_request_body.number_pdu=0; + dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0; + dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000; + dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0; - dummy_subframe.dl_config_req = &dummy_dl_config_req; - dummy_subframe.tx_req = 0;//&dummy_tx_req; + memset(&dummy_tx_req, 0, sizeof(dummy_tx_req)); + dummy_tx_req.tx_request_body.number_of_pdus=0; + dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG; - dummy_subframe.ul_config_req=0; - dummy_subframe.hi_dci0_req=0; - dummy_subframe.lbt_dl_config_req=0; + dummy_subframe.dl_config_req = &dummy_dl_config_req; + dummy_subframe.tx_req = 0;//&dummy_tx_req; - p7_config->dummy_subframe = dummy_subframe; + dummy_subframe.ul_config_req=0; + dummy_subframe.hi_dci0_req=0; + dummy_subframe.lbt_dl_config_req=0; - p7_config->vendor_ext = &pnf_phy_vendor_ext; + p7_config->dummy_subframe = dummy_subframe; - p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext; - p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext; + p7_config->vendor_ext = &pnf_phy_vendor_ext; - p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension; - p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension; - p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv; - p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv; + p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext; + p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__); - pthread_t p7_thread; - pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config); + p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension; + p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension; + p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv; + p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv; - //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__); + pthread_t p7_thread; + pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config); - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__); - l1_north_init_eNB(); + //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__); - p7_config_g = p7_config; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__); + l1_north_init_eNB(); - // Need to wait for main thread to create RU structures - while(config_sync_var<0) { - usleep(5000000); - printf("[PNF] waiting for OAI to be configured (eNB/RU)\n"); - } - printf("[PNF] OAI eNB/RU configured\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__); + p7_config_g = p7_config; - printf("[PNF] About to call init_eNB_afterRU()\n"); - init_eNB_afterRU(); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Panos-D: start_request, BUFFER SIZE: %d", p7_config_g->subframe_buffer_size); + //printf("Panos-D: start_request, bUFFER SIZE: %d", p7_config_g->subframe_buffer_size); - // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised - pthread_mutex_lock(&nfapi_sync_mutex); - nfapi_sync_var=0; - pthread_cond_broadcast(&nfapi_sync_cond); - pthread_mutex_unlock(&nfapi_sync_mutex); + // Need to wait for main thread to create RU structures + while(config_sync_var<0) + { + usleep(5000000); + printf("[PNF] waiting for OAI to be configured (eNB/RU)\n"); + } + printf("[PNF] OAI eNB/RU configured\n"); - while(sync_var<0) { - usleep(5000000); - printf("[PNF] waiting for OAI to be started\n"); - } + //printf("[PNF] About to call phy_init_RU() for RC.ru[0]:%p\n", RC.ru[0]); + //phy_init_RU(RC.ru[0]); - printf("[PNF] Sending PNF_START_RESP\n"); - nfapi_send_pnf_start_resp(config, p7_config->phy_id); + printf("[PNF] About to call init_eNB_afterRU()\n"); - printf("[PNF] Sending first P7 subframe ind\n"); - nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? - printf("[PNF] Sent first P7 subframe ind\n"); + // Panos: Instead + /*if (nfapi_mode == 3) { + init_UE_stub(1,0,uecap_xer_in); + }*/ + //else{ + if (nfapi_mode != 3) { + // Panos + init_eNB_afterRU(); + } + + // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised + { + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var=0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + } + + while(sync_var<0) + { + usleep(5000000); + printf("[PNF] waiting for OAI to be started\n"); + } + + printf("[PNF] Sending PNF_START_RESP\n"); + nfapi_send_pnf_start_resp(config, p7_config->phy_id); + + printf("[PNF] Sending first P7 subframe ind\n"); + nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? + printf("[PNF] Sent first P7 subframe ind\n"); return 0; } @@ -1468,7 +1534,9 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__); + if(nfapi_mode!=3) { nfapi_mode = 1; // PNF! + } nfapi_pnf_config_t* config = nfapi_pnf_config_create(); diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h index 592d4877af1ac87a95c67f9d4d2365b0c586e36d..e213d785f14ef1c94a41cb61a058d25e7982b6e4 100644 --- a/nfapi/oai_integration/nfapi_pnf.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -21,7 +21,7 @@ #if !defined(NFAPI_PNF_H__) #define NFAPI_PNF_H__ - +int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); #endif diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 07c3f1aa91fda58261b36dd8c90df3cbaf12d781..74e999528c51fc7d40f4eea48d56cd069a7ced04 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -37,7 +37,8 @@ #include "vendor_ext.h" #include "nfapi_vnf.h" - +#include "PHY/defs_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" #include "common/ran_context.h" extern RAN_CONTEXT_t RC; @@ -201,8 +202,8 @@ void oai_create_enb(void) { eNB->CC_id = bodge_counter; eNB->abstraction_flag = 0; eNB->single_thread_flag = 0;//single_thread_flag; - eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + eNB->td = ulsch_decoding_data_all;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding_all;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; RC.nb_CC[bodge_counter] = 1; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index 13041767522935fb74a90cfe9748517d303588dd..3c469c942bc028c81f8cbbf1492850891be06604 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -1247,9 +1247,14 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf); //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta); - if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) + + // Panos: Careful here!!! + //if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) + if (vnf_pnf_sfnsf_delta>0 || vnf_pnf_sfnsf_delta < 0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf)); + // Panos: Careful here!!! + vnf_p7->p7_connections[0].sfn_sf = ind.last_sfn_sf; } } } diff --git a/openair1/PHY/CODING/3gpplte.c b/openair1/PHY/CODING/3gpplte.c index ca63857d7205cc4b37c7da5d89ff4988127f0b5e..ae476a118f0ab99f777e7ad2270fedfcb467a815 100644 --- a/openair1/PHY/CODING/3gpplte.c +++ b/openair1/PHY/CODING/3gpplte.c @@ -27,7 +27,9 @@ #ifndef TC_MAIN //#include "defs.h" #endif - +#include <stdint.h> +#include <stdio.h> +#include "PHY/CODING/coding_defs.h" #include "extern_3GPPinterleaver.h" //#define DEBUG_TURBO_ENCODER 1 @@ -35,7 +37,7 @@ uint32_t threegpplte_interleaver_output; uint32_t threegpplte_interleaver_tmp; -inline void threegpplte_interleaver_reset() +inline void threegpplte_interleaver_reset(void) { threegpplte_interleaver_output = 0; threegpplte_interleaver_tmp = 0; @@ -82,7 +84,7 @@ uint8_t output_lut[16],state_lut[16]; inline uint8_t threegpplte_rsc_lut(uint8_t input,uint8_t *state) { - uint8_t output; + uint8_t off; off = (*state<<1)|input; @@ -146,7 +148,7 @@ void threegpplte_turbo_encoder(uint8_t *input, for (i=0; f1f2mat[i].nb_bits!= input_length_bits && i <188; i++); if ( i == 188 ) { - msg("Illegal frame length!\n"); + printf("Illegal frame length!\n"); return; } else { base_interleaver=il_tb+f1f2mat[i].beg_index; diff --git a/openair1/PHY/CODING/3gpplte_sse.c b/openair1/PHY/CODING/3gpplte_sse.c index 5d87a60477db22600da14707604db1745ddc304c..e2eb7eb52af2897cfcbf02a5b3407e492cc681d6 100644 --- a/openair1/PHY/CODING/3gpplte_sse.c +++ b/openair1/PHY/CODING/3gpplte_sse.c @@ -26,10 +26,10 @@ date: 09.2012 */ #ifndef TC_MAIN -#include "defs.h" +#include "coding_defs.h" #include "extern_3GPPinterleaver.h" #else -#include "vars.h" +#include "coding_vars.h" #include <stdint.h> #endif #include <stdio.h> @@ -96,7 +96,7 @@ static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z *state = (*state)>>1; } -void treillis_table_init(void) +static void treillis_table_init(void) { //struct treillis t[][]=all_treillis; //t=memalign(16,sizeof(struct treillis)*8*256); @@ -536,12 +536,12 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns } */ -void threegpplte_turbo_encoder(unsigned char *input, - unsigned short input_length_bytes, - unsigned char *output, - unsigned char F, - unsigned short interleaver_f1, - unsigned short interleaver_f2) +void threegpplte_turbo_encoder_sse(unsigned char *input, + unsigned short input_length_bytes, + unsigned char *output, + unsigned char F, + unsigned short interleaver_f1, + unsigned short interleaver_f2) { int i; @@ -641,7 +641,24 @@ void threegpplte_turbo_encoder(unsigned char *input, #endif } - +void init_encoder_sse (void) { + treillis_table_init(); +} +/* function which will be called by the shared lib loader, to check shared lib version + against main exec version. version mismatch no considered as fatal (interfaces not supposed to change) +*/ +int coding_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion) +{ +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__ +#endif + *shlib_buildversion = PACKAGE_VERSION; + if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) { + fprintf(stderr,"[CODING] shared lib version %s, doesn't match main version %s, compatibility should be checked\n", + mainexec_buildversion,*shlib_buildversion); + } + return 0; +} #ifdef TC_MAIN #define INPUT_LENGTH 20 @@ -679,7 +696,7 @@ int main(int argc,char **argv) printf("Input %d : %d\n",i,input[i]); } - threegpplte_turbo_encoder(&input[0], + threegpplte_turbo_encoder_sse(&input[0], INPUT_LENGTH, &output[0], 0, diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder.c b/openair1/PHY/CODING/3gpplte_turbo_decoder.c index 4470ecca05ba426e30113e6a71eacf76e87a0465..572127a5e0bd4118a4082d94e51c402743a33689 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder.c @@ -27,8 +27,8 @@ */ -#include "PHY/defs.h" -#include "PHY/CODING/defs.h" +#include "PHY/defs_common.h" +#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/sse_intrin.h" @@ -550,7 +550,7 @@ void compute_alpha_s(llr_t* alpha,llr_t* m_11,llr_t* m_10,unsigned short frame_l void compute_beta_s(llr_t* beta,llr_t *m_11,llr_t* m_10,llr_t* alpha,unsigned short frame_length,unsigned char F) { - int k,i; + int k; llr_t old0, old1, old2, old3, old4, old5, old6, old7; llr_t new0, new1, new2, new3, new4, new5, new6, new7; llr_t m_b0, m_b1, m_b2, m_b3, m_b4,m_b5, m_b6, m_b7; @@ -874,14 +874,22 @@ void compute_ext_s(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, + llr_t *y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, unsigned char max_iterations, unsigned char crc_type, unsigned char F, - unsigned char inst) + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) { /* y is a pointer to the input @@ -897,7 +905,7 @@ unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, unsigned char crc_len,temp; if (crc_type > 3) { - msg("Illegal crc length!\n"); + fprintf(stderr,"Illegal crc length!\n"); return 255; } diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c index 616eed7446df4d611a4addba06cec2e90b1a32aa..a541c223934e00d2d3cf31eaf01d10a748b3dd3a 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c @@ -37,13 +37,14 @@ /// /// -#ifdef __AVX2__ -#include "PHY/sse_intrin.h" + + #ifndef TEST_DEBUG -#include "PHY/defs.h" -#include "PHY/CODING/defs.h" +#include "PHY/impl_defs_top.h" +#include "PHY/defs_common.h" +#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "extern_3GPPinterleaver.h" #else @@ -58,6 +59,8 @@ #include "mex.h" #endif +#ifdef __AVX2__ +#include "PHY/sse_intrin.h" //#define DEBUG_LOGMAP @@ -830,14 +833,14 @@ void free_td16avx2(void) int ind; for (ind=0; ind<188; ind++) { - free(pi2tab16avx2[ind]); - free(pi5tab16avx2[ind]); - free(pi4tab16avx2[ind]); - free(pi6tab16avx2[ind]); + free_and_zero(pi2tab16avx2[ind]); + free_and_zero(pi5tab16avx2[ind]); + free_and_zero(pi4tab16avx2[ind]); + free_and_zero(pi6tab16avx2[ind]); } } -void init_td16avx2() +void init_td16avx2(void) { int ind,i,i2,i3,j,n,pi,pi2_i,pi2_pi; @@ -1408,6 +1411,36 @@ unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y, #endif return(iteration_cnt); } +#else //__AVX2__ +unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y, + int16_t *y2, + uint8_t *decoded_bytes, + uint8_t *decoded_bytes2, + uint16_t n, + uint16_t f1, + uint16_t f2, + uint8_t max_iterations, + uint8_t crc_type, + uint8_t F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) +{ + return 0; +} +void free_td16avx2(void) +{ + +} + +void init_td16avx2(void) +{ + +} #endif //__AVX2__ diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c index 9ec25367d9c435af597c124a13f74af80d35f577..f628bff55b7c08223ad13efff2807c8a9a4fb658 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c @@ -1907,6 +1907,18 @@ void compute_ext(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, ll //int pi2[n],pi3[n+8],pi5[n+8],pi4[n+8],pi6[n+8], int *pi2tab[188],*pi5tab[188],*pi4tab[188],*pi6tab[188]; +void free_td() +{ + int ind; + + for (ind = 0; ind < 188; ind++) { + free_and_zero(pi2tab[ind]); + free_and_zero(pi5tab[ind]); + free_and_zero(pi4tab[ind]); + free_and_zero(pi6tab[ind]); + } +} + void init_td() { diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c index cb4a4e1f84124553c09391c6649b67921b2bafb7..7daa86b8bb296218b17955532c96267c2688c24d 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c @@ -41,8 +41,9 @@ #include "PHY/sse_intrin.h" #ifndef TEST_DEBUG -#include "PHY/defs.h" -#include "PHY/CODING/defs.h" +#include "PHY/impl_defs_top.h" +#include "PHY/defs_common.h" +#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "extern_3GPPinterleaver.h" #else @@ -1117,14 +1118,14 @@ void free_td16(void) int ind; for (ind=0; ind<188; ind++) { - free(pi2tab16[ind]); - free(pi5tab16[ind]); - free(pi4tab16[ind]); - free(pi6tab16[ind]); + free_and_zero(pi2tab16[ind]); + free_and_zero(pi5tab16[ind]); + free_and_zero(pi4tab16[ind]); + free_and_zero(pi6tab16[ind]); } } -void init_td16() +void init_td16(void) { int ind,i,i2,i3,j,n,pi,pi3; @@ -1172,7 +1173,9 @@ void init_td16() } unsigned char phy_threegpplte_turbo_decoder16(short *y, + short *y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index d6ef84b218388dcdf0ad9e24e4391c85fe9bc82a..f22ec21ff0ac25bfb876a8bac56c22b02129ca2c 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -39,8 +39,8 @@ #include "PHY/sse_intrin.h" #ifndef TEST_DEBUG -#include "PHY/defs.h" -#include "PHY/CODING/defs.h" +#include "PHY/defs_common.h" +#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "extern_3GPPinterleaver.h" #else @@ -838,10 +838,10 @@ void free_td8(void) int ind; for (ind=0; ind<188; ind++) { - free(pi2tab8[ind]); - free(pi5tab8[ind]); - free(pi4tab8[ind]); - free(pi6tab8[ind]); + free_and_zero(pi2tab8[ind]); + free_and_zero(pi5tab8[ind]); + free_and_zero(pi4tab8[ind]); + free_and_zero(pi6tab8[ind]); } } @@ -849,7 +849,7 @@ void free_td8(void) extern RAN_CONTEXT_t RC; -void init_td8() +void init_td8(void) { int ind,i,j,n,n2,pi,pi3; @@ -898,7 +898,9 @@ void init_td8() } unsigned char phy_threegpplte_turbo_decoder8(short *y, + short y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, diff --git a/openair1/PHY/CODING/ccoding_byte.c b/openair1/PHY/CODING/ccoding_byte.c index 8511a5ea0f7103cfcf252a9ededf4103ab8e4977..db91e68dc8f020c63b1d610cfbfb6d1f93ebaa3a 100644 --- a/openair1/PHY/CODING/ccoding_byte.c +++ b/openair1/PHY/CODING/ccoding_byte.c @@ -24,7 +24,7 @@ author: raymond.knopp@eurecom.fr, based on similar code for 3GPP convolutional code (UMTS) by P. Humblet (2000) date: 10.2004 */ -#include "defs.h" +#include "coding_defs.h" unsigned short gdot11[] = { 0133, 0171 }; // {A,B} diff --git a/openair1/PHY/CODING/ccoding_byte_lte.c b/openair1/PHY/CODING/ccoding_byte_lte.c index 6eb654827bc874c9d27a405d2975b014a572a32d..870e9ba4700c15e16c42d4b18e3a975ef757e51e 100644 --- a/openair1/PHY/CODING/ccoding_byte_lte.c +++ b/openair1/PHY/CODING/ccoding_byte_lte.c @@ -24,7 +24,7 @@ author: raymond.knopp@eurecom.fr date: 21.10.2009 */ -#include "defs.h" +#include "coding_defs.h" //#define DEBUG_CCODE 1 diff --git a/openair1/PHY/CODING/defs.h b/openair1/PHY/CODING/coding_defs.h similarity index 74% rename from openair1/PHY/CODING/defs.h rename to openair1/PHY/CODING/coding_defs.h index 80e28b15867e79244181cfe8c02fc28000f22a56..d2975f3f9360dc09a55eb7329e625694895dfb5d 100644 --- a/openair1/PHY/CODING/defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -29,7 +29,7 @@ #include <stdint.h> -#include "PHY/defs.h" +#include "PHY/defs_common.h" #define CRC24_A 0 #define CRC24_B 1 @@ -37,7 +37,7 @@ #define CRC8 3 #define MAX_TURBO_ITERATIONS_MBSFN 8 -#define MAX_TURBO_ITERATIONS 4 +#define MAX_TURBO_ITERATIONS max_turbo_iterations #define LTE_NULL 2 @@ -75,20 +75,7 @@ int32_t lte_segmentation(uint8_t *input_buffer, uint32_t *Kminus, uint32_t *F); -/** \fn int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs) - \brief this functions calculates the delta MCS in dB based on the lte_segmentation function -\param tbs transport block size -\param nb_rb number of required rb -\param control_only a flag for the type of data -\param ncp cyclic prefix -\param use_srs a flag indicating the use of srs in the current SF -\returns ue_tx_power estimated ue tx power = delat_ mcs + bw_factor -*/ -int16_t estimate_ue_tx_power(uint32_t tbs, - uint32_t nb_rb, - uint8_t control_only, - lte_prefix_type_t ncp, - uint8_t use_srs); + /** \fn uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w) \brief This is the subblock interleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16. @@ -292,25 +279,9 @@ void ccodedot11_init(void); \brief This function initializes the trellis structure for decoding an 802.11 convolutional code.*/ void ccodedot11_init_inv(void); -/*!\fn void teillis_table_init(void) -\brief This function initializes the trellis structure for 3GPP LTE Turbo code.*/ -void treillis_table_init(void); - -/*\fn void threegpplte_turbo_encoder(uint8_t *input,uint16_t input_length_bytes,uint8_t *output,uint8_t F,uint16_t interleaver_f1,uint16_t interleaver_f2) -\brief This function implements a rate 1/3 8-state parralel concatenated turbo code (3GPP-LTE). -@param input Pointer to input buffer -@param input_length_bytes Number of bytes to encode -@param output Pointer to output buffer -@param F Number of filler bits at input -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -*/ -void threegpplte_turbo_encoder(uint8_t *input, - uint16_t input_length_bytes, - uint8_t *output, - uint8_t F, - uint16_t interleaver_f1, - uint16_t interleaver_f2); + + + /** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti) @@ -352,25 +323,7 @@ void ccodedab_init_inv(void); \brief This function initializes the different crc tables.*/ void crcTableInit (void); -/*!\fn void init_td8(void) -\brief This function initializes the tables for 8-bit LLR Turbo decoder.*/ -void init_td8 (void); - - -/*!\fn void init_td16(void) -\brief This function initializes the tables for 16-bit LLR Turbo decoder.*/ -void init_td16 (void); -#ifdef __AVX2__ -/*!\fn void init_td8(void) -\brief This function initializes the tables for 8-bit LLR Turbo decoder (AVX2).*/ -void init_td8avx2 (void); - - -/*!\fn void init_td16(void) -\brief This function initializes the tables for 16-bit LLR Turbo decoder (AVX2).*/ -void init_td16avx2 (void); -#endif /*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen) \brief This computes a 24-bit crc ('a' variant for overall transport block) @@ -460,95 +413,7 @@ int32_t rate_matching_lte(uint32_t N_coded, uint32_t off); -/*! -\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 16-bit -LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU) -@param y LLR input (16-bit precision) -@param decoded_bytes Pointer to decoded output -@param n number of coded bits (including tail bits) -@param max_iterations The maximum number of iterations to perform -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8) -@param F Number of filler bits at start of packet -@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0) -*/ -uint8_t phy_threegpplte_turbo_decoder16(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -uint8_t phy_threegpplte_turbo_decoder16avx2(int16_t *y, - int16_t *y2, - uint8_t *decoded_bytes, - uint8_t *decoded_bytes2, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -/*! -\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 8-bit -LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU) -@param y LLR input (16-bit precision) -@param decoded_bytes Pointer to decoded output -@param n number of coded bits (including tail bits) -@param max_iterations The maximum number of iterations to perform -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8) -@param F Number of filler bits at start of packet -@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0) -*/ -uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -uint8_t phy_threegpplte_turbo_decoder_scalar(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - uint8_t inst); - - - -/** @} */ + uint32_t crcbit (uint8_t * , int32_t, diff --git a/openair1/PHY/CODING/extern.h b/openair1/PHY/CODING/coding_extern.h similarity index 86% rename from openair1/PHY/CODING/extern.h rename to openair1/PHY/CODING/coding_extern.h index 9c58920a10d003db6e73768638cbdf594146dd24..0d3e2ccb02e3b050243443603bc0946f414f9745 100644 --- a/openair1/PHY/CODING/extern.h +++ b/openair1/PHY/CODING/coding_extern.h @@ -20,5 +20,9 @@ */ extern unsigned short f1f2mat_old[2*188]; - - +extern double cpuf; +extern decoder_if_t decoder16; +extern decoder_if_t decoder8; +extern encoder_if_t encoder; +extern int load_codinglib(void); +extern int free_codinglib(void); diff --git a/openair1/PHY/CODING/coding_load.c b/openair1/PHY/CODING/coding_load.c new file mode 100644 index 0000000000000000000000000000000000000000..76ab04f2207734355d209e71e5338567303a92f8 --- /dev/null +++ b/openair1/PHY/CODING/coding_load.c @@ -0,0 +1,183 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 openair1/PHY/CODING + * \brief: load library implementing coding/decoding algorithms + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include <sys/types.h> + + +#include "PHY/defs_common.h" +#include "PHY/phy_extern.h" +#include "common/utils/load_module_shlib.h" +#include "common/utils/telnetsrv/telnetsrv.h" + +static int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static telnetshell_cmddef_t coding_cmdarray[] = { + {"mode","[sse,avx2,stdc,none]",coding_setmod_cmd}, + {"","",NULL}, +}; +telnetshell_vardef_t coding_vardef[] = { +{"maxiter",TELNET_VARTYPE_INT32,&max_turbo_iterations}, +{"",0,NULL} +}; +/* PHY/defs.h contains MODE_DECODE_XXX macros, following table must match */ +static char *modedesc[] = {"none","sse","C","avx2"}; +static int curmode; +/* function description array, to be used when loading the encoding/decoding shared lib */ +loader_shlibfunc_t shlib_fdesc[DECODE_NUM_FPTR]; + +/* encoding decoding functions pointers, filled here and used when encoding/decoding */ +/*defined as extern in PHY?CODING/extern.h */ +decoder_if_t decoder16; +decoder_if_t decoder8; +encoder_if_t encoder; + +extern int _may_i_use_cpu_feature(unsigned __int64); +uint8_t nodecod(short *y, + short *y2, + unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, + unsigned short n, + unsigned short f1, + unsigned short f2, + unsigned char max_iterations, + unsigned char crc_type, + unsigned char F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) +{ + return max_iterations+1; +}; + +void decoding_setmode (int mode) { + switch (mode) { + case MODE_DECODE_NONE: + decoder8=nodecod; + decoder16=nodecod; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; + break; + case MODE_DECODE_C: + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; + break; + case MODE_DECODE_AVX2: + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fptr; + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; + break; + default: + mode=MODE_DECODE_SSE; + case MODE_DECODE_SSE: + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; + break; + } + curmode=mode; +} + + +int load_codinglib(void) { + int ret; + + memset(shlib_fdesc,0,sizeof(shlib_fdesc)); + shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fname = "init_td8"; + shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fname= "init_td16"; + shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fname="init_td16avx2"; + + shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder8"; + shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16"; + shlib_fdesc[DECODE_TD_C_FPTRIDX].fname= "phy_threegpplte_turbo_decoder_scalar"; + shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16avx2"; + + + shlib_fdesc[DECODE_FREETD8_FPTRIDX].fname = "free_td8"; + shlib_fdesc[DECODE_FREETD16_FPTRIDX].fname= "free_td16"; + shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fname= "free_td16avx2"; + + shlib_fdesc[ENCODE_SSE_FPTRIDX].fname= "threegpplte_turbo_encoder_sse"; + shlib_fdesc[ENCODE_C_FPTRIDX].fname= "threegpplte_turbo_encoder"; + shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fname= "init_encoder_sse"; + ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR); + if (ret < 0) exit_fun("Error loading coding library"); + +/* execute encoder/decoder init functions */ + shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fptr(); + shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fptr(); + if(shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr != NULL) { + shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr(); + } + if(shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr != NULL) { + shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr(); + } + decoding_setmode(MODE_DECODE_SSE); +/* look for telnet server, if it is loaded, add the coding commands to it */ + add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); + if (addcmd != NULL) { + addcmd("coding",coding_vardef,coding_cmdarray); + } +return 0; +} + +void free_codinglib(void) { + + shlib_fdesc[DECODE_FREETD8_FPTRIDX].fptr(); + shlib_fdesc[DECODE_FREETD16_FPTRIDX].fptr(); + shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fptr(); + + +} + +/* functions for telnet support, when telnet server is loaded */ +int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ + if (debug > 0) + prnt( "coding_setmod_cmd received %s\n",buff); + + if (strcasestr(buff,"sse") != NULL) { + decoding_setmode(MODE_DECODE_SSE); + } else if (strcasestr(buff,"avx2") != NULL) { + decoding_setmode(MODE_DECODE_AVX2); + } else if (strcasestr(buff,"stdc") != NULL) { + decoding_setmode(MODE_DECODE_C); + } else if (strcasestr(buff,"none") != NULL) { + decoding_setmode(MODE_DECODE_NONE); + } else { + prnt("%s: wrong setmod parameter...\n",buff); + } + prnt("Coding and decoding current mode: %s\n",modedesc[curmode]); + return 0; +} diff --git a/openair1/PHY/CODING/vars.h b/openair1/PHY/CODING/coding_vars.h similarity index 100% rename from openair1/PHY/CODING/vars.h rename to openair1/PHY/CODING/coding_vars.h diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 5ec4fcaaa4bc73f8a26aec421159a4c0286c9ecf..0e1f0e065f36b8ade81d103fb2ccc70915a09751 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -31,7 +31,7 @@ */ -#include "defs.h" +#include "coding_defs.h" /*ref 36-212 v8.6.0 , pp 8-9 */ @@ -109,7 +109,7 @@ crc24a (unsigned char * inptr, int bitlen) resbit = (bitlen % 8); while (octetlen-- > 0) { - // printf("in %x => crc %x\n",crc,*inptr); + // printf("crc24a: in %x => crc %x\n",crc,*inptr); crc = (crc << 8) ^ crc24aTable[(*inptr++) ^ (crc >> 24)]; } @@ -128,6 +128,7 @@ unsigned int crc24b (unsigned char * inptr, int bitlen) resbit = (bitlen % 8); while (octetlen-- > 0) { + // printf("crc24b: in %x => crc %x (%x)\n",crc,*inptr,crc24bTable[(*inptr) ^ (crc >> 24)]); crc = (crc << 8) ^ crc24bTable[(*inptr++) ^ (crc >> 24)]; } diff --git a/openair1/PHY/CODING/defs_NB_IoT.h b/openair1/PHY/CODING/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..2a6bee792412ae4f73d38f741b6ef5b615065418 --- /dev/null +++ b/openair1/PHY/CODING/defs_NB_IoT.h @@ -0,0 +1,275 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/CODING/defs_NB_IoT.h + purpose: Top-level definitions, data types and function prototypes for openairinterface coding blocks for NB-IoT + author: matthieu.kanj@b-com.com, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it + date: 29.06.2017 +*/ + +#ifndef OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ +#define OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ + +#include <stdint.h> // for uint8/16/32_t + +/* check if this ifndef is required for NB-IoT ?! +//#ifndef NO_OPENAIR1 +//#include "PHY/defs_NB_IoT.h" +//#else +//#include "PHY/TOOLS/time_meas.h" +//#endif +*/ + +#define CRC24_A_NB_IoT 0 +#define CRC24_B_NB_IoT 1 +#define CRC16_NB_IoT 2 +#define CRC8_NB_IoT 3 + +//#define MAX_TURBO_ITERATIONS_MBSFN 8 // no MBSFN +#define MAX_TURBO_ITERATIONS_NB_IoT 4 + +#define LTE_NULL_NB_IoT 2 // defined also in PHY/LTE_TRANSPORT/defs_NB_IoT.h + +/** \fn uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w) +\brief This is the subblock interleaving algorithm for convolutionally coded blocks from 36-212 (Release 13.4, 2017). +This function takes the d-sequence and generates the w-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of input bits +\param d Pointer to input (d-sequence, convolutional code output) +\param w Pointer to output (w-sequence, interleaver output) +\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212) +*/ +uint32_t sub_block_interleaving_cc_NB_IoT(uint32_t D, uint8_t *d,uint8_t *w); + +/** +\brief This is the NB-IoT rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) for up to 8 segments +\param E Number of coded channel bits +\param w This is a pointer to the w-sequence (second interleaver output) +\param e This is a pointer to the e-sequence (rate matching output, channel input/output bits) +\returns \f$E\f$, the number of coded bits per segment */ + +uint32_t lte_rate_matching_cc_NB_IoT(uint32_t RCC, // RRC = 2 + uint16_t E, // E = 1600 + uint8_t *w, // length + uint8_t *e); // length 1600 + +/** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti) +\brief This function implements the LTE convolutional code of rate 1/3 + with a constraint length of 7 bits. The inputs are bit packed in octets +(from MSB to LSB). Trellis tail-biting is included here. +@param numbits Number of bits to encode +@param add_crc crc to be appended (8 bits) if add_crc = 1 +@param inPtr Pointer to input buffer +@param outPtr Pointer to output buffer +@param rnti RNTI for CRC scrambling +*/ + +void ccode_encode_NB_IoT (int32_t numbits, + uint8_t add_crc, + uint8_t *inPtr, + uint8_t *outPtr, + uint16_t rnti); + +/*!\fn void ccodelte_init(void) +\brief This function initializes the generator polynomials for an LTE convolutional code.*/ +void ccodelte_init_NB_IoT(void); + +/*!\fn void crcTableInit(void) +\brief This function initializes the different crc tables.*/ +void crcTableInit_NB_IoT (void); + + +/*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 24-bit crc ('a' variant for overall transport block) +based on 3GPP UMTS/LTE specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits +*/ +uint32_t crc24a_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc24b(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 24-bit crc ('b' variant for transport-block segments) +based on 3GPP UMTS/LTE specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits +*/ +uint32_t crc24b_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 16-bit crc based on 3GPP UMTS specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits*/ +uint32_t crc16_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 8-bit crc based on 3GPP UMTS specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits*/ +uint32_t crc8_NB_IoT (uint8_t *inPtr, int32_t bitlen); + + + + + + +uint32_t crcbit_NB_IoT (uint8_t * , + int32_t, + uint32_t); + + +/*!\fn void phy_viterbi_lte_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n) +\brief This routine performs a SIMD optmized Viterbi decoder for the LTE 64-state tail-biting convolutional code. +@param y Pointer to soft input (coded on 8-bits but should be limited to 4-bit precision to avoid overflow) +@param decoded_bytes Pointer to decoded output +@param n Length of input/trellis depth in bits*/ +//void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n); +void phy_viterbi_lte_sse2_NB_IoT(int8_t *y,uint8_t *decoded_bytes,uint16_t n); + +/** \fn void sub_block_deinterleaving_cc(uint32_t D, int8_t *d,int8_t *w) +\brief This is the subblock deinterleaving algorithm for convolutionally-coded data from 36-212 (Release 8, 8.6 2009-03), pages 15-16. +This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of input bits +\param d Pointer to output (d-sequence, turbo code output) +\param w Pointer to input (w-sequence, interleaver output) +*/ +void sub_block_deinterleaving_cc_NB_IoT(uint32_t D,int8_t *d,int8_t *w); + + +/* +\brief This is the LTE rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) +\param E This the number of coded bits allocated for channel +\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds +\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions +\param soft_input This is a pointer to the soft channel output +\returns \f$E\f$, the number of coded bits per segment +*/ +void lte_rate_matching_cc_rx_NB_IoT(uint32_t RCC, + uint16_t E, + int8_t *w, + uint8_t *dummy_w, + int8_t *soft_input); + +/** \fn generate_dummy_w_cc(uint32_t D, uint8_t *w) +\brief This function generates a dummy interleaved sequence (first row) for receiver (convolutionally-coded data), in order to identify the NULL positions used to make the matrix complete. +\param D Number of systematic bits plus 4 (plus 4 for termination) +\param w This is the dummy sequence (first row), it will contain zeros and at most 31 "LTE_NULL" values +\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212) +*/ +uint32_t generate_dummy_w_cc_NB_IoT(uint32_t D, uint8_t *w); + +/** \fn lte_segmentation(uint8_t *input_buffer, + uint8_t **output_buffers, + uint32_t B, + uint32_t *C, + uint32_t *Cplus, + uint32_t *Cminus, + uint32_t *Kplus, + uint32_t *Kminus, + uint32_t *F) +\brief This function implements the LTE transport block segmentation algorithm from 36-212, V8.6 2009-03. +@param input_buffer +@param output_buffers +@param B +@param C +@param Cplus +@param Cminus +@param Kplus +@param Kminus +@param F +*/ +int32_t lte_segmentation_NB_IoT(uint8_t *input_buffer, + uint8_t **output_buffers, + uint32_t B, + uint32_t *C, + uint32_t *Cplus, + uint32_t *Cminus, + uint32_t *Kplus, + uint32_t *Kminus, + uint32_t *F); + +/** \fn void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w) +\brief This is the subblock deinterleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16. +This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of systematic bits plus 4 (plus 4 for termination) +\param d Pointer to output (d-sequence, turbo code output) +\param w Pointer to input (w-sequence, interleaver output) +*/ +//*****************void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w); + +/** +\brief This is the LTE rate matching algorithm for Turbo-coded channels (e.g. DLSCH,ULSCH). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RTC R^TC_subblock from subblock interleaver (number of rows in interleaving matrix) +\param G This the number of coded transport bits allocated in sub-frame +\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds +\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions +\param soft_input This is a pointer to the soft channel output +\param C Number of segments (codewords) in the sub-frame +\param Nsoft Total number of soft bits (from UE capabilities in 36-306) +\param Mdlharq Number of HARQ rounds +\param Kmimo MIMO capability for this DLSCH (0 = no MIMO) +\param rvidx round index (0-3) +\param clear 1 means clear soft buffer (start of HARQ round) +\param Qm modulation order (2,4,6) +\param Nl number of layers (1,2) +\param r segment number +\param E_out the number of coded bits per segment +\returns 0 on success, -1 on failure +*/ + +// int lte_rate_matching_turbo_rx(uint32_t RTC, +// uint32_t G, +// int16_t *w, +// uint8_t *dummy_w, +// int16_t *soft_input, +// uint8_t C, +// uint32_t Nsoft, +// uint8_t Mdlharq, +// uint8_t Kmimo, +// uint8_t rvidx, +// uint8_t clear, +// uint8_t Qm, +// uint8_t Nl, +// uint8_t r, +// uint32_t *E_out); + +// uint32_t lte_rate_matching_turbo_rx_abs(uint32_t RTC, +// uint32_t G, +// double *w, +// uint8_t *dummy_w, +// double *soft_input, +// uint8_t C, +// uint32_t Nsoft, +// uint8_t Mdlharq, +// uint8_t Kmimo, +// uint8_t rvidx, +// uint8_t clear, +// uint8_t Qm, +// uint8_t Nl, +// uint8_t r, +// uint32_t *E_out); + +void ccode_encode_npdsch_NB_IoT (int32_t numbits, + uint8_t *inPtr, + uint8_t *outPtr, + uint32_t crc); + +#endif /* OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ */ diff --git a/openair1/PHY/CODING/lte_rate_matching.c b/openair1/PHY/CODING/lte_rate_matching.c index 13870e3303ccf17f117a97df225dc06a5f72c83b..af5d1a169e950fa0a35b7237c47ad5390a195288 100644 --- a/openair1/PHY/CODING/lte_rate_matching.c +++ b/openair1/PHY/CODING/lte_rate_matching.c @@ -28,8 +28,8 @@ #include <stdio.h> #include <stdlib.h> #endif -#include "PHY/defs.h" -#include "assertions.h" +#include "PHY/defs_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_common.h" //#define cmin(a,b) ((a)<(b) ? (a) : (b)) @@ -463,7 +463,7 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, uint8_t Qm, uint8_t Nl, uint8_t r, - uint8_t nb_rb) + uint8_t nb_rb) // uint8_t m) { @@ -513,7 +513,7 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, // counter_buffer[rvidx][cnt]=0; if (Ncb>(3*(RTC<<5))) AssertFatal(1==0,"Exiting, RM condition (Ncb %d, RTC %d, Nir/C %d, Nsoft %d, Kw %d)\n",Ncb,RTC,Nir/C,Nsoft,3*(RTC<<5)); - + AssertFatal(Nl>0,"Nl is 0\n"); AssertFatal(Qm>0,"Qm is 0\n"); Gp = G/Nl/Qm; @@ -749,6 +749,10 @@ int lte_rate_matching_turbo_rx(uint32_t RTC, for (; (ind<Ncb)&&(k<E); ind++) { if (dummy_w[ind] != LTE_NULL) { + /* + if ((w[ind]>0 && soft_input2[k]<0) || + (w[ind]<0 && soft_input2[k]>0)) + printf("ind %d: w %d => soft_in %d\n",ind,w[ind],soft_input2[k]);*/ w[ind] += soft_input2[k++]; #ifdef RM_DEBUG printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]); diff --git a/openair1/PHY/CODING/lte_segmentation.c b/openair1/PHY/CODING/lte_segmentation.c index 3ae65e20900e95323efee6563cbc9d7dd705b856..ba79b0171e4e31dac4d411e07b4ab22b66263cbf 100644 --- a/openair1/PHY/CODING/lte_segmentation.c +++ b/openair1/PHY/CODING/lte_segmentation.c @@ -24,8 +24,9 @@ author: raymond.knopp@eurecom.fr date: 21.10.2009 */ -#include "PHY/defs.h" -#include "SCHED/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_common.h" +#include "PHY/CODING/coding_defs.h" //#define DEBUG_SEGMENTATION diff --git a/openair1/PHY/CODING/viterbi_lte.c b/openair1/PHY/CODING/viterbi_lte.c index 5e11cb3453ab9dd2f425a175389acfd0edcca432..553192a4a8ee723ff3afb12292f53cb10c4463ac 100644 --- a/openair1/PHY/CODING/viterbi_lte.c +++ b/openair1/PHY/CODING/viterbi_lte.c @@ -29,8 +29,8 @@ */ #ifndef TEST_DEBUG -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_common.h" +#include "PHY/phy_extern.h" #else #include <stdio.h> #include <stdlib.h> diff --git a/openair1/PHY/INIT/defs_NB_IoT.h b/openair1/PHY/INIT/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..b49936770f2411068e60729d838c61f09f62539a --- /dev/null +++ b/openair1/PHY/INIT/defs_NB_IoT.h @@ -0,0 +1,77 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#ifndef __INIT_DEFS_NB_IOT__H__ +#define __INIT_DEFS_NB_IOT__H__ + +//#include "PHY/defs_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "nfapi_interface.h" + +//#include "SystemInformationBlockType2.h" +//#include "RadioResourceConfigCommonSIB.h" +//#include "RadioResourceConfigDedicated.h" +//#include "TDD-Config.h" +//#include "MBSFN-SubframeConfigList.h" +//#include "MobilityControlInfo.h" +//#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +//#include "SCellToAddMod-r10.h" +//#endif + +/*brief Configure LTE_DL_FRAME_PARMS with components derived after initial synchronization (MIB-NB decoding + primary/secondary synch).*/ +void phy_config_mib_eNB_NB_IoT(int Mod_id, + int eutra_band, + int Nid_cell, + int Ncp, + int Ncp_UL, + int p_eNB, + uint16_t EARFCN, + uint16_t prb_index, // NB_IoT_RB_ID, + uint16_t operating_mode, + uint16_t control_region_size, + uint16_t eutra_NumCRS_ports); + +/*NB_phy_config_sib1_eNB is not needed since NB-IoT use only FDD mode*/ + +/*brief Configure LTE_DL_FRAME_PARMS with components of SIB2-NB (at eNB).*/ + +//void NB_phy_config_sib2_eNB(module_id_t Mod_id, +// int CC_id, +// RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon +// ); + +void phy_config_sib2_eNB_NB_IoT(uint8_t Mod_id, + nfapi_nb_iot_config_t *config, + nfapi_rf_config_t *rf_config, + nfapi_uplink_reference_signal_config_t* ul_nrs_config, + extra_phyConfig_t* extra_phy_parms); + +void phy_config_dedicated_eNB_NB_IoT(module_id_t Mod_id, + rnti_t rnti, + extra_phyConfig_t* extra_phy_parms); + +// void phy_init_lte_top_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); +void phy_init_nb_iot_eNB(PHY_VARS_eNB_NB_IoT *phyvar); +int l1_north_init_NB_IoT(void); + +#endif + diff --git a/openair1/PHY/INIT/extern.h b/openair1/PHY/INIT/init_extern.h similarity index 100% rename from openair1/PHY/INIT/extern.h rename to openair1/PHY/INIT/init_extern.h diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 218beb4faf825c9a024c24155b9abdb342a7a19b..f033a7e5c17d3db534b91d2008fe49913c2c0c07 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -20,21 +20,90 @@ */ /*!\brief Initilization and reconfiguration routines for LTE PHY */ -#include "defs.h" -#include "PHY/extern.h" -#include "MAC_INTERFACE/extern.h" -//#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" +#include "phy_init.h" +#include "PHY/phy_extern.h" +#include "PHY/CODING/coding_extern.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" -/*! -* @addtogroup _PHY_STRUCTURES_ -* Memory Initializaion and Cleanup for LTE MODEM. -* @{ -\section _Memory_init_ Memory Initialization for LTE MODEM +void generate_64qam_table(void) +{ -*/ + int a,b,c,index; -//#define DEBUG_PHY -t + + for (a=-1; a<=1; a+=2) + for (b=-1; b<=1; b+=2) + for (c=-1; c<=1; c+=2) { + index = (1+a)*2 + (1+b) + (1+c)/2; + qam64_table[index] = -a*(QAM64_n1 + b*(QAM64_n2 + (c*QAM64_n3))); // 0 1 2 + } +} + +void generate_16qam_table(void) +{ + + int a,b,index; + + for (a=-1; a<=1; a+=2) + for (b=-1; b<=1; b+=2) { + index = (1+a) + (1+b)/2; + qam16_table[index] = -a*(QAM16_n1 + (b*QAM16_n2)); + } +} + +void generate_qpsk_table(void) +{ + + int a,index; + + for (a=-1; a<=1; a+=2) { + index = (1+a)/2; + qpsk_table[index] = -a*QPSK; + } +} + +void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) +{ + + crcTableInit(); + + ccodedot11_init(); + ccodedot11_init_inv(); + + ccodelte_init(); + ccodelte_init_inv(); + + + + phy_generate_viterbi_tables(); + phy_generate_viterbi_tables_lte(); + + load_codinglib(); + lte_sync_time_init(frame_parms); + + generate_ul_ref_sigs(); + generate_ul_ref_sigs_rx(); + + generate_64qam_table(); + generate_16qam_table(); + generate_RIV_tables(); + + init_unscrambling_lut(); + init_scrambling_lut(); + //set_taus_seed(1328); + + +} + +void free_lte_top(void) +{ + free_codinglib(); + lte_sync_time_free(); + + /* free_ul_ref_sigs() is called in phy_free_lte_eNB() */ +} /* diff --git a/openair1/PHY/INIT/vars.h b/openair1/PHY/INIT/init_vars.h similarity index 100% rename from openair1/PHY/INIT/vars.h rename to openair1/PHY/INIT/init_vars.h diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index d5a1262e8d932ec2f34f6879ca221189bd110e6c..b9522e050ce34b570f507598d28c20aa8bcb790e 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -19,14 +19,17 @@ * contact@openairinterface.org */ -#include "defs.h" -#include "SCHED/defs.h" -#include "PHY/extern.h" -#include "SIMULATION/TOOLS/defs.h" +#include "PHY/defs_eNB.h" +#include "phy_init.h" +#include "SCHED/sched_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "SIMULATION/TOOLS/sim.h" #include "RadioResourceConfigCommonSIB.h" #include "RadioResourceConfigDedicated.h" #include "TDD-Config.h" -#include "LAYER2/MAC/extern.h" #include "MBSFN-SubframeConfigList.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "assertions.h" @@ -179,7 +182,7 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->frame_type, RC.eNB[Mod_id][CC_id]->X_u); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) fp->prach_emtc_config_common.prach_Config_enabled=1; fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; @@ -325,24 +328,6 @@ void phy_config_request(PHY_Config_t *phy_config) { LOG_I(PHY,"eNB %d/%d configured\n",Mod_id,CC_id); } -void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, - uint8_t eNB_id, - TDD_Config_t *tdd_Config, - uint8_t SIwindowsize, - uint16_t SIperiod) -{ - - LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; - - if (tdd_Config) { - fp->tdd_config = tdd_Config->subframeAssignment; - fp->tdd_config_S = tdd_Config->specialSubframePatterns; - } - - fp->SIwindowsize = SIwindowsize; - fp->SIPeriod = SIperiod; -} - /* void phy_config_sib2_eNB(uint8_t Mod_id, int CC_id, @@ -486,149 +471,6 @@ void phy_config_sib2_eNB(uint8_t Mod_id, } */ -void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, - uint8_t eNB_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CarrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) -{ - - PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; - LTE_DL_FRAME_PARMS *fp = &ue->frame_parms; - int i; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_IN); - - LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,eNB_id); - - fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; - - fp->prach_config_common.prach_Config_enabled=1; - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag; - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; - fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset; - - compute_prach_seq(fp->prach_config_common.rootSequenceIndex, - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type,ue->X_u); - - - - fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift; - fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI; - fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon.nCS_AN; - fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN; - - - - fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon.referenceSignalPower; - fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon.p_b; - - - fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; - fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; - fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; - fp->pusch_config_common.enable64QAM = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = dmrs1_tab[radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift]; - - - init_ul_hopping(fp); - fp->soundingrs_ul_config_common.enabled_flag = 0; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { - fp->soundingrs_ul_config_common.enabled_flag = 1; - fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; - fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; - fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) - fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; - else - fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; - } - - - - fp->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUSCH; - fp->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon.alpha; - fp->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH; - fp->ul_power_control_config_common.deltaPreambleMsg3 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaPreambleMsg3; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1b = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b; - - fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx; - - // Now configure some of the Physical Channels - - // PUCCH - init_ncs_cell(fp,ue->ncs_cell); - - init_ul_hopping(fp); - - // PCH - init_ue_paging_info(ue,radioResourceConfigCommon->pcch_Config.defaultPagingCycle,radioResourceConfigCommon->pcch_Config.nB); - - // MBSFN - - if (mbsfn_SubframeConfigList != NULL) { - fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; - - for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { - fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; - fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; - - if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { - fp->MBSFN_config[i].fourFrames_flag = 0; - fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration - fp->MBSFN_config[i].fourFrames_flag = 1; - fp->MBSFN_config[i].mbsfn_SubframeConfig = - mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); - - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_OUT); - -} - -void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx, - long mbsfn_AreaId_r9) -{ - - LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; - - - LOG_I(PHY,"[UE%d] Applying MBSFN_Area_id %ld for index %d\n",Mod_id,mbsfn_AreaId_r9,mbsfn_Area_idx); - - if (mbsfn_Area_idx == 0) { - fp->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9; - LOG_N(PHY,"Fix me: only called when mbsfn_Area_idx == 0)\n"); - } - - lte_gold_mbsfn(fp,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_mbsfn_table,fp->Nid_cell_mbsfn); - -} - - void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx, long mbsfn_AreaId_r9) { @@ -766,150 +608,6 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB) } } -/* - * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover - */ -void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed) -{ - - if(mobilityControlInfo!=NULL) { - RadioResourceConfigCommon_t *radioResourceConfigCommon = &mobilityControlInfo->radioResourceConfigCommon; - LOG_I(PHY,"radioResourceConfigCommon %p\n", radioResourceConfigCommon); - memcpy((void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms_before_ho, - (void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms, - sizeof(LTE_DL_FRAME_PARMS)); - PHY_vars_UE_g[Mod_id][CC_id]->ho_triggered = 1; - //PHY_vars_UE_g[UE_id]->UE_mode[0] = PRACH; - - LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; - // int N_ZC; - // uint8_t prach_fmt; - // int u; - - LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n", - Mod_id,eNB_id); - - fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; - fp->prach_config_common.prach_Config_enabled=1; - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex; - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag; - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig; - fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset; - - // prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,fp->frame_type); - // N_ZC = (prach_fmt <4)?839:139; - // u = (prach_fmt < 4) ? prach_root_sequence_map0_3[fp->prach_config_common.rootSequenceIndex] : - // prach_root_sequence_map4[fp->prach_config_common.rootSequenceIndex]; - - //compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u); - compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - PHY_vars_UE_g[Mod_id][CC_id]->X_u); - - - fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift; - fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon->nRB_CQI; - fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon->nCS_AN; - fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon->n1PUCCH_AN; - fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon->referenceSignalPower; - fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon->p_b; - - - fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; - fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; - fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; - fp->pusch_config_common.enable64QAM = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; - - init_ul_hopping(fp); - fp->soundingrs_ul_config_common.enabled_flag = 0; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->present==SoundingRS_UL_ConfigCommon_PR_setup) { - fp->soundingrs_ul_config_common.enabled_flag = 1; - fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_BandwidthConfig; - fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; - fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.ackNackSRS_SimultaneousTransmission; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_MaxUpPts) - fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; - else - fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; - } - - fp->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUSCH; - fp->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon->alpha; - fp->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUCCH; - fp->ul_power_control_config_common.deltaPreambleMsg3 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaPreambleMsg3; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1b; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2a; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2b; - - fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon->maxHARQ_Msg3Tx; - - // Now configure some of the Physical Channels - if (radioResourceConfigCommon->antennaInfoCommon) - fp->nb_antennas_tx = (1<<radioResourceConfigCommon->antennaInfoCommon->antennaPortsCount); - else - fp->nb_antennas_tx = 1; - - //PHICH - if (radioResourceConfigCommon->antennaInfoCommon) { - fp->phich_config_common.phich_resource = radioResourceConfigCommon->phich_Config->phich_Resource; - fp->phich_config_common.phich_duration = radioResourceConfigCommon->phich_Config->phich_Duration; - } - - //Target CellId - fp->Nid_cell = mobilityControlInfo->targetPhysCellId; - fp->nushift = fp->Nid_cell%6; - - // PUCCH - init_ncs_cell(fp,PHY_vars_UE_g[Mod_id][CC_id]->ncs_cell); - - init_ul_hopping(fp); - - // RNTI - - - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); - - LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); - } - - if(ho_failed) { - LOG_D(PHY,"[UE%d] Handover failed, triggering RACH procedure\n",Mod_id); - memcpy((void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms,(void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms_before_ho, sizeof(LTE_DL_FRAME_PARMS)); - PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_id] = PRACH; - } -} - -void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id) -{ - - PHY_MEASUREMENTS *phy_meas = &PHY_vars_UE_g[Mod_id][CC_id]->measurements; - int i; - - LOG_I(PHY,"Configuring inter-cell measurements for %d cells, ids: \n",n_adj_cells); - - for (i=0; i<n_adj_cells; i++) { - LOG_I(PHY,"%d\n",adj_cell_id[i]); - lte_gold(&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_table[i+1],adj_cell_id[i]); - } - - phy_meas->n_adj_cells = n_adj_cells; - memcpy((void*)phy_meas->adj_cell_id,(void *)adj_cell_id,n_adj_cells*sizeof(unsigned int)); - -} - /* void phy_config_dedicated_eNB(uint8_t Mod_id, int CC_id, @@ -974,14 +672,6 @@ void phy_config_dedicated_eNB(uint8_t Mod_id, } */ -#if defined(Rel10) || defined(Rel14) -void phy_config_dedicated_scell_ue(uint8_t Mod_id, - uint8_t eNB_index, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id) -{ - -} /* void phy_config_dedicated_scell_eNB(uint8_t Mod_id, uint16_t rnti, @@ -1031,789 +721,8 @@ void phy_config_dedicated_scell_eNB(uint8_t Mod_id, } */ -#endif - - -void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, - uint16_t max_harq_tx ) -{ - - PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx; -} - -extern uint16_t beta_cqi[16]; - -void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, - struct PhysicalConfigDedicated *physicalConfigDedicated ) -{ - static uint8_t first_dedicated_configuration = 0; - PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - phy_vars_ue->total_TBS[eNB_id]=0; - phy_vars_ue->total_TBS_last[eNB_id]=0; - phy_vars_ue->bitrate[eNB_id]=0; - phy_vars_ue->total_received_bits[eNB_id]=0; - phy_vars_ue->dlsch_errors[eNB_id]=0; - phy_vars_ue->dlsch_errors_last[eNB_id]=0; - phy_vars_ue->dlsch_received[eNB_id]=0; - phy_vars_ue->dlsch_received_last[eNB_id]=0; - phy_vars_ue->dlsch_fer[eNB_id]=0; - - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - - if (physicalConfigDedicated) { - LOG_D(PHY,"[UE %d] Received physicalConfigDedicated from eNB %d\n",Mod_id, eNB_id); - LOG_D(PHY,"------------------------------------------------------------------------\n"); - - if (physicalConfigDedicated->pdsch_ConfigDedicated) { - phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a=physicalConfigDedicated->pdsch_ConfigDedicated->p_a; - LOG_D(PHY,"pdsch_config_dedicated.p_a %d\n",phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a); - LOG_D(PHY,"\n"); - } - - if (physicalConfigDedicated->pucch_ConfigDedicated) { - if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==PUCCH_ConfigDedicated__ackNackRepetition_PR_release) - phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=0; - else { - phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=1; - } - - if (physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) - phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = *physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; - else - phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = bundling; - - if ( phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode == multiplexing) - LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = multiplexing\n"); - else - LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = bundling\n"); - } - - if (physicalConfigDedicated->pusch_ConfigDedicated) { - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - - - LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index,beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]); - LOG_D(PHY,"\n"); - - - } - - if (physicalConfigDedicated->uplinkPowerControlDedicated) { - - phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH = physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUSCH; - phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled= physicalConfigDedicated->uplinkPowerControlDedicated->deltaMCS_Enabled; - phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled= physicalConfigDedicated->uplinkPowerControlDedicated->accumulationEnabled; - phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH= physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUCCH; - phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset= physicalConfigDedicated->uplinkPowerControlDedicated->pSRS_Offset; - phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient= *physicalConfigDedicated->uplinkPowerControlDedicated->filterCoefficient; - LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUSCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH); - LOG_D(PHY,"ul_power_control_dedicated.deltaMCS_Enabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled); - LOG_D(PHY,"ul_power_control_dedicated.accumulationEnabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled); - LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUCCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH); - LOG_D(PHY,"ul_power_control_dedicated.pSRS_Offset %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset); - LOG_D(PHY,"ul_power_control_dedicated.filterCoefficient %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient); - LOG_D(PHY,"\n"); - } - - if (physicalConfigDedicated->antennaInfo) { - phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); - LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); - switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case AntennaInfoDedicated__transmissionMode_tm1: - phy_vars_ue->transmission_mode[eNB_id] = 1; - break; - case AntennaInfoDedicated__transmissionMode_tm2: - phy_vars_ue->transmission_mode[eNB_id] = 2; - break; - case AntennaInfoDedicated__transmissionMode_tm3: - phy_vars_ue->transmission_mode[eNB_id] = 3; - break; - case AntennaInfoDedicated__transmissionMode_tm4: - phy_vars_ue->transmission_mode[eNB_id] = 4; - break; - case AntennaInfoDedicated__transmissionMode_tm5: - phy_vars_ue->transmission_mode[eNB_id] = 5; - break; - case AntennaInfoDedicated__transmissionMode_tm6: - phy_vars_ue->transmission_mode[eNB_id] = 6; - break; - case AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); - phy_vars_ue->transmission_mode[eNB_id] = 7; - break; - default: - LOG_E(PHY,"Unknown transmission mode!\n"); - break; - } - } else { - LOG_D(PHY,"[UE %d] Received NULL physicalConfigDedicated->antennaInfo from eNB %d\n",Mod_id, eNB_id); - } - - if (physicalConfigDedicated->schedulingRequestConfig) { - if (physicalConfigDedicated->schedulingRequestConfig->present == SchedulingRequestConfig_PR_setup) { - phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; - phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex; - phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax; - - LOG_D(PHY,"scheduling_request_config.sr_PUCCH_ResourceIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); - LOG_D(PHY,"scheduling_request_config.sr_ConfigIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex); - LOG_D(PHY,"scheduling_request_config.dsr_TransMax %d\n",phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax); - } - - LOG_D(PHY,"------------------------------------------------------------\n"); - - } - - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { - - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0; - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; - - - LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex); - } - - LOG_D(PHY,"------------------------------------------------------------\n"); - - } - - - if (physicalConfigDedicated->cqi_ReportConfig) { - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) { - // configure PUSCH CQI reporting - phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; - if ((phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm12) && - (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm30) && - (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm31)) - LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic); - } - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { - // configure PUCCH CQI reporting - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex; - } - else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_release) { - // handle release - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - } - } - } - -#ifdef CBA - - if (physicalConfigDedicated->pusch_CBAConfigDedicated_vlola) { - phy_vars_ue->pusch_ca_config_dedicated[eNB_id].betaOffset_CA_Index = (uint16_t) *physicalConfigDedicated->pusch_CBAConfigDedicated_vlola->betaOffset_CBA_Index; - phy_vars_ue->pusch_ca_config_dedicated[eNB_id].cShift = (uint16_t) *physicalConfigDedicated->pusch_CBAConfigDedicated_vlola->cShift_CBA; - LOG_D(PHY,"[UE %d ] physicalConfigDedicated pusch CBA config dedicated: beta offset %d cshift %d \n",Mod_id, - phy_vars_ue->pusch_ca_config_dedicated[eNB_id].betaOffset_CA_Index, - phy_vars_ue->pusch_ca_config_dedicated[eNB_id].cShift); - } - -#endif - } else { - LOG_D(PHY,"[PHY][UE %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id,eNB_id); - return; - } - - // fill cqi parameters for periodic CQI reporting - get_cqipmiri_params(phy_vars_ue,eNB_id); - - // disable MIB SIB decoding once we are on connected mode - first_dedicated_configuration ++; - if(first_dedicated_configuration > 1) - { - LOG_I(PHY,"Disable SIB MIB decoding \n"); - phy_vars_ue->decode_SIB = 0; - phy_vars_ue->decode_MIB = 0; - } - //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; - if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) - phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; - else - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; - - LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); - -} - -void phy_config_cba_rnti (module_id_t Mod_id,int CC_id,eNB_flag_t eNB_flag, uint8_t index, rnti_t cba_rnti, uint8_t cba_group_id, uint8_t num_active_cba_groups) -{ - // uint8_t i; - - if (eNB_flag == 0 ) { - //LOG_D(PHY,"[UE %d] configure cba group %d with rnti %x, num active cba grp %d\n", index, index, cba_rnti, num_active_cba_groups); - PHY_vars_UE_g[Mod_id][CC_id]->ulsch[index]->num_active_cba_groups=num_active_cba_groups; - PHY_vars_UE_g[Mod_id][CC_id]->ulsch[index]->cba_rnti[cba_group_id]=cba_rnti; - } else { - //for (i=index; i < NUMBER_OF_UE_MAX; i+=num_active_cba_groups){ - // LOG_D(PHY,"[eNB %d] configure cba group %d with rnti %x for UE %d, num active cba grp %d\n",Mod_id, i%num_active_cba_groups, cba_rnti, i, num_active_cba_groups); - RC.eNB[Mod_id][CC_id]->ulsch[index]->num_active_cba_groups=num_active_cba_groups; - RC.eNB[Mod_id][CC_id]->ulsch[index]->cba_rnti[cba_group_id] = cba_rnti; - //} - } -} - -void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) -{ - - crcTableInit(); - - ccodedot11_init(); - ccodedot11_init_inv(); - - ccodelte_init(); - ccodelte_init_inv(); - - treillis_table_init(); - - phy_generate_viterbi_tables(); - phy_generate_viterbi_tables_lte(); - init_td8(); - init_td16(); -#ifdef __AVX2__ - init_td16avx2(); -#endif - lte_sync_time_init(frame_parms); - - generate_ul_ref_sigs(); - generate_ul_ref_sigs_rx(); - - generate_64qam_table(); - generate_16qam_table(); - generate_RIV_tables(); - - init_unscrambling_lut(); - init_scrambling_lut(); - //set_taus_seed(1328); - - -} - -/*! \brief Helper function to allocate memory for DLSCH data structures. - * \param[out] pdsch Pointer to the LTE_UE_PDSCH structure to initialize. - * \param[in] frame_parms LTE_DL_FRAME_PARMS structure. - * \note This function is optimistic in that it expects malloc() to succeed. - */ -void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS* const fp ) -{ - AssertFatal( pdsch, "pdsch==0" ); - - pdsch->pmi_ext = (uint8_t*)malloc16_clear( fp->N_RB_DL ); - pdsch->llr[0] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); - pdsch->llr128 = (int16_t**)malloc16_clear( sizeof(int16_t*) ); - // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV - // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there - - - pdsch->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->rxdataF_uespec_pilots = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->rxdataF_comp0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); - pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_bf_ch_estimates = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_bf_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - //pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - //pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_mag0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_magb0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - - - // the allocated memory size is fixed: - AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); - - for (int i=0; i<fp->nb_antennas_rx; i++) { - pdsch->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); - - for (int j=0; j<4; j++) { //fp->nb_antennas_tx; j++) - const int idx = (j<<1)+i; - const size_t num = 7*2*fp->N_RB_DL*12; - pdsch->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->rxdataF_uespec_pilots[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); - pdsch->rxdataF_comp0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_bf_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); - pdsch->dl_bf_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - //pdsch->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - //pdsch->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_mag0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_magb0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } - } -} - -int init_lte_ue_signal(PHY_VARS_UE *ue, - int nb_connected_eNB, - uint8_t abstraction_flag) -{ - - // create shortcuts - LTE_DL_FRAME_PARMS* const fp = &ue->frame_parms; - LTE_UE_COMMON* const common_vars = &ue->common_vars; - LTE_UE_PDSCH** const pdsch_vars_SI = ue->pdsch_vars_SI; - LTE_UE_PDSCH** const pdsch_vars_ra = ue->pdsch_vars_ra; - LTE_UE_PDSCH** const pdsch_vars_p = ue->pdsch_vars_p; - LTE_UE_PDSCH** const pdsch_vars_mch = ue->pdsch_vars_MCH; - LTE_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars; - LTE_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdcch_vars; - LTE_UE_PBCH** const pbch_vars = ue->pbch_vars; - LTE_UE_PRACH** const prach_vars = ue->prach_vars; - - - - int i,j,k,l; - int eNB_id; - int th_id; - - LOG_D(PHY,"Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx); - LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST); - - - - init_frame_parms(&ue->frame_parms,1); - init_lte_top(&ue->frame_parms); - init_ul_hopping(&ue->frame_parms); - - - // many memory allocation sizes are hard coded - AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" ); - AssertFatal( ue->n_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" ); - // init phy_vars_ue - - for (i=0; i<4; i++) { - ue->rx_gain_max[i] = 135; - ue->rx_gain_med[i] = 128; - ue->rx_gain_byp[i] = 120; - } - - ue->n_connected_eNB = nb_connected_eNB; - - for(eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { - ue->total_TBS[eNB_id] = 0; - ue->total_TBS_last[eNB_id] = 0; - ue->bitrate[eNB_id] = 0; - ue->total_received_bits[eNB_id] = 0; - } - - for (i=0;i<10;i++) - ue->tx_power_dBm[i]=-127; - - - - // init TX buffers - - common_vars->txdata = (int32_t**)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) ); - common_vars->txdataF = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) ); - - for (i=0; i<fp->nb_antennas_tx; i++) { - - common_vars->txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); - common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); - } - - // init RX buffers - - common_vars->rxdata = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - common_vars->common_vars_rx_data_per_thread[0].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - common_vars->common_vars_rx_data_per_thread[1].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - - for (i=0; i<fp->nb_antennas_rx; i++) { - common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_tti*10+2048)*sizeof(int32_t) ); - common_vars->common_vars_rx_data_per_thread[0].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); - common_vars->common_vars_rx_data_per_thread[1].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); - } - - - // Channel estimates - for (eNB_id=0; eNB_id<7; eNB_id++) { - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*)); - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*)); - } - - for (i=0; i<fp->nb_antennas_rx; i++) - for (j=0; j<4; j++) { - int idx = (j<<1) + i; - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) ); - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 ); - } - } - } - - // DLSCH - for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) { - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); - } - - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH)); - } - - pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); - pdsch_vars_ra[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); - pdsch_vars_p[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); - pdsch_vars_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); - prach_vars[eNB_id] = (LTE_UE_PRACH *)malloc16_clear(sizeof(LTE_UE_PRACH)); - pbch_vars[eNB_id] = (LTE_UE_PBCH *)malloc16_clear(sizeof(LTE_UE_PBCH)); - - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp ); - } - - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12); - (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts_p = (*pdsch_vars_th)[0][eNB_id]->llr_shifts; - (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); - (*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); - } - - for (int i=0; i<fp->nb_antennas_rx; i++){ - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - } - - } - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - } - - for (i=0; i<fp->nb_antennas_rx; i++) - for (j=0; j<4; j++) { - const int idx = (j<<1)+i; - const size_t num = 7*2*fp->N_RB_DL*12+4; - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } - - } - - //const size_t num = 7*2*fp->N_RB_DL*12+4; - for (k=0;k<8;k++) { //harq_pid - for (l=0;l<8;l++) { //round - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - } - - - for (int i=0; i<fp->nb_antennas_rx; i++) - for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) - const int idx = (j<<1)+i; - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - } - - } - } - } - phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); - phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); - phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); - phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); - - // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); - - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - } - - for (i=0; i<fp->nb_antennas_rx; i++) { - //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); - } - - for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++) - int idx = (j<<1)+i; - // size_t num = 7*2*fp->N_RB_DL*12; - size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } - } - } - phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); - phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); - phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); - phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); - - // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); - - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - } - - for (i=0; i<fp->nb_antennas_rx; i++) { - //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); - - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); - } - - for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++) - int idx = (j<<1)+i; - // size_t num = 7*2*fp->N_RB_DL*12; - size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } - } - } - - // PBCH - pbch_vars[eNB_id]->rxdataF_ext = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - pbch_vars[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pbch_vars[eNB_id]->llr = (int8_t*)malloc16_clear( 1920 ); - prach_vars[eNB_id]->prachF = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); - prach_vars[eNB_id]->prach = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); - - for (i=0; i<fp->nb_antennas_rx; i++) { - pbch_vars[eNB_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); - - for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) { - int idx = (j<<1)+i; - pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); - pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); - } - } - - - pbch_vars[eNB_id]->decoded_output = (uint8_t*)malloc16_clear( 64 ); - } - - // initialization for the last instance of pdsch_vars (used for MU-MIMO) - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); - } - - pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); - pdsch_vars_ra[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); - pdsch_vars_p[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); - - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp ); - (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); - } - - - ue->sinr_CQI_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) ); - - ue->init_averaging = 1; - // default value until overwritten by RRCConnectionReconfiguration - if (fp->nb_antenna_ports_eNB==2) - ue->pdsch_config_dedicated->p_a = dBm3; - else - ue->pdsch_config_dedicated->p_a = dB0; - - // set channel estimation to do linear interpolation in time - ue->high_speed_flag = 1; - ue->ch_est_alpha = 24576; - - // enable MIB/SIB decoding by default - ue->decode_MIB = 1; - ue->decode_SIB = 1; - - init_prach_tables(839); - - - return 0; -} - -void init_lte_ue_transport(PHY_VARS_UE *ue,int abstraction_flag) { - - int i,j,k; - - for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { - for (j=0; j<2; j++) { - for (k=0; k<2; k++) { - AssertFatal((ue->dlsch[k][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); - - LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[i][j]); - } - } - - AssertFatal((ue->ulsch[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n"); - - ue->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); - ue->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); - - ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_eNB==1 ? 1 : 2; - } - - ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; - - ue->dlsch_MCH[0] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0); - -} - -int phy_init_RU(RU_t *ru) { - - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; - int i,j; - int p; - int re; - - LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); - - if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals - // Time-domain signals - ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*)); - ru->common.rxdata = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); - - - for (i=0; i<ru->nb_tx; i++) { - // Allocate 10 subframes of I/Q TX signal data (time) if not - ru->common.txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); - - LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i], - fp->samples_per_tti*10*sizeof(int32_t)); - - } - for (i=0;i<ru->nb_rx;i++) { - ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); - } - } // IF5 or local RF - else { - LOG_I(PHY,"No rxdata/txdata for RU\n"); - ru->common.txdata = (int32_t**)NULL; - ru->common.rxdata = (int32_t**)NULL; - - } - if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing - LOG_I(PHY,"nb_tx %d\n",ru->nb_tx); - ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); - for (i=0;i<ru->nb_rx;i++) { - ru->common.rxdata_7_5kHz[i] = (int32_t*)malloc16_clear( 2*fp->samples_per_tti*2*sizeof(int32_t) ); - LOG_I(PHY,"rxdata_7_5kHz[%d] %p for RU %d\n",i,ru->common.rxdata_7_5kHz[i],ru->idx); - } - - - // allocate IFFT input buffers (TX) - ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); - LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF, - ru->nb_tx*sizeof(int32_t*)); - for (i=0; i<ru->nb_tx; i++) { - ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->symbols_per_tti*fp->ofdm_symbol_size*sizeof(int32_t) ); - LOG_I(PHY,"txdataF_BF[%d] %p for RU %d\n",i,ru->common.txdataF_BF[i],ru->idx); - } - // allocate FFT output buffers (RX) - ru->common.rxdataF = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); - for (i=0; i<ru->nb_rx; i++) { - // allocate 2 subframes of I/Q signal data (frequency) - ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) ); - LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx); - } - - /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ - AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), - "nb_antennas_rx too large"); - ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); - for (j=0;j<4;j++) ru->prach_rxsigF_br[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); - - for (i=0; i<ru->nb_rx; i++) { - ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); - LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]); -#ifdef Rel14 - for (j=0;j<4;j++) { - ru->prach_rxsigF_br[j][i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); - LOG_D(PHY,"[INIT] prach_vars_br->rxsigF[%d] = %p\n",i,ru->prach_rxsigF_br[j][i]); - } -#endif - } - - AssertFatal(RC.nb_L1_inst <= NUMBER_OF_eNB_MAX,"eNB instances %d > %d\n", - RC.nb_L1_inst,NUMBER_OF_eNB_MAX); - - LOG_D(PHY,"[INIT] %s() RC.nb_L1_inst:%d \n", __FUNCTION__, RC.nb_L1_inst); - - for (i=0; i<RC.nb_L1_inst; i++) { - for (p=0;p<15;p++) { - LOG_D(PHY,"[INIT] %s() nb_antenna_ports_eNB:%d \n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB); - if (p<ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p==5) { - LOG_D(PHY,"[INIT] %s() DO BEAM WEIGHTS nb_antenna_ports_eNB:%d nb_tx:%d\n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB, ru->nb_tx); - ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); - for (j=0; j<ru->nb_tx; j++) { - ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); - // antenna ports 0-3 are mapped on antennas 0-3 - // antenna port 4 is mapped on antenna 0 - // antenna ports 5-14 are mapped on all antennas - if (((p<4) && (p==j)) || ((p==4) && (j==0))) { - for (re=0; re<fp->ofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff; - - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - else if (p>4) { - for (re=0; re<fp->ofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); - } - } - } - } - } - ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_tti ); - - return(0); -} - int phy_init_lte_eNB(PHY_VARS_eNB *eNB, unsigned char is_secondary_eNB, unsigned char abstraction_flag) @@ -1825,7 +734,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, LTE_eNB_PUSCH** const pusch_vars = eNB->pusch_vars; LTE_eNB_SRS* const srs_vars = eNB->srs_vars; LTE_eNB_PRACH* const prach_vars = &eNB->prach_vars; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LTE_eNB_PRACH* const prach_vars_br = &eNB->prach_vars_br; #endif int i, UE_id; @@ -1921,7 +830,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, prach_vars->rxsigF[0] = (int16_t**)malloc16_clear(64*sizeof(int16_t*)); // PRACH BR -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) prach_vars_br->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int32_t) ); // assume maximum of 64 RX antennas for PRACH receiver @@ -1959,10 +868,10 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, for (i=0; i<2; i++) { // RK 2 times because of output format of FFT! // FIXME We should get rid of this - pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); + pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); - pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*2*sizeof(int32_t)*fp->ofdm_symbol_size ); + pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); @@ -1982,6 +891,80 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, } +void phy_free_lte_eNB(PHY_VARS_eNB *eNB) +{ + LTE_DL_FRAME_PARMS* const fp = &eNB->frame_parms; + LTE_eNB_COMMON* const common_vars = &eNB->common_vars; + LTE_eNB_PUSCH** const pusch_vars = eNB->pusch_vars; + LTE_eNB_SRS* const srs_vars = eNB->srs_vars; + LTE_eNB_PRACH* const prach_vars = &eNB->prach_vars; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_eNB_PRACH* const prach_vars_br = &eNB->prach_vars_br; +#endif + int i, UE_id; + + for (i = 0; i < NB_ANTENNA_PORTS_ENB; i++) { + if (i < fp->nb_antenna_ports_eNB || i == 5) { + free_and_zero(common_vars->txdataF[i]); + /* rxdataF[i] is not allocated -> don't free */ + } + } + free_and_zero(common_vars->txdataF); + free_and_zero(common_vars->rxdataF); + + // Channel estimates for SRS + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + for (i=0; i<64; i++) { + free_and_zero(srs_vars[UE_id].srs_ch_estimates[i]); + free_and_zero(srs_vars[UE_id].srs_ch_estimates_time[i]); + } + free_and_zero(srs_vars[UE_id].srs_ch_estimates); + free_and_zero(srs_vars[UE_id].srs_ch_estimates_time); + } //UE_id + + free_ul_ref_sigs(); + + for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) free_and_zero(srs_vars[UE_id].srs); + + free_and_zero(prach_vars->prachF); + + for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]); + free_and_zero(prach_vars->prach_ifft[0]); + +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + for (int ce_level = 0; ce_level < 4; ce_level++) { + for (i = 0; i < 64; i++) free_and_zero(prach_vars_br->prach_ifft[ce_level][i]); + free_and_zero(prach_vars_br->prach_ifft[ce_level]); + free_and_zero(prach_vars->rxsigF[ce_level]); + } + free_and_zero(prach_vars_br->prachF); +#endif + free_and_zero(prach_vars->rxsigF[0]); + + for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { + for (i = 0; i < 2; i++) { + free_and_zero(pusch_vars[UE_id]->rxdataF_ext[i]); + free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates[i]); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time[i]); + free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]); + free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]); + free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]); + } + free_and_zero(pusch_vars[UE_id]->rxdataF_ext); + free_and_zero(pusch_vars[UE_id]->rxdataF_ext2); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time); + free_and_zero(pusch_vars[UE_id]->rxdataF_comp); + free_and_zero(pusch_vars[UE_id]->ul_ch_mag); + free_and_zero(pusch_vars[UE_id]->ul_ch_magb); + free_and_zero(pusch_vars[UE_id]->llr); + free_and_zero(pusch_vars[UE_id]); + } //UE_id + + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) eNB->UE_stats_ptr[UE_id] = NULL; +} + void install_schedule_handlers(IF_Module_t *if_inst) { if_inst->PHY_config_req = phy_config_request; diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c new file mode 100644 index 0000000000000000000000000000000000000000..c6ac0819cd615fbe9f3ab22ed0f0d57c88bbab53 --- /dev/null +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -0,0 +1,197 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "phy_init.h" +#include "SCHED/sched_eNB.h" +#include "PHY/phy_extern.h" +#include "SIMULATION/TOOLS/sim.h" +#include "RadioResourceConfigCommonSIB.h" +#include "RadioResourceConfigDedicated.h" +#include "TDD-Config.h" +#include "MBSFN-SubframeConfigList.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "assertions.h" +#include <math.h> + +int phy_init_RU(RU_t *ru) { + + LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; + int i,j; + int p; + int re; + + LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); + + if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals + // Time-domain signals + ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*)); + ru->common.rxdata = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); + + + for (i=0; i<ru->nb_tx; i++) { + // Allocate 10 subframes of I/Q TX signal data (time) if not + ru->common.txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); + + LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i], + fp->samples_per_tti*10*sizeof(int32_t)); + + } + for (i=0;i<ru->nb_rx;i++) { + ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); + } + } // IF5 or local RF + else { + // LOG_I(PHY,"No rxdata/txdata for RU\n"); + ru->common.txdata = (int32_t**)NULL; + ru->common.rxdata = (int32_t**)NULL; + + } + if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing + LOG_I(PHY,"nb_tx %d\n",ru->nb_tx); + ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); + for (i=0;i<ru->nb_rx;i++) { + ru->common.rxdata_7_5kHz[i] = (int32_t*)malloc16_clear( 2*fp->samples_per_tti*2*sizeof(int32_t) ); + LOG_I(PHY,"rxdata_7_5kHz[%d] %p for RU %d\n",i,ru->common.rxdata_7_5kHz[i],ru->idx); + } + + + // allocate IFFT input buffers (TX) + ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); + LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF, + ru->nb_tx*sizeof(int32_t*)); + for (i=0; i<ru->nb_tx; i++) { + ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->symbols_per_tti*fp->ofdm_symbol_size*sizeof(int32_t) ); + LOG_I(PHY,"txdataF_BF[%d] %p for RU %d\n",i,ru->common.txdataF_BF[i],ru->idx); + } + // allocate FFT output buffers (RX) + ru->common.rxdataF = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); + for (i=0; i<ru->nb_rx; i++) { + // allocate 2 subframes of I/Q signal data (frequency) + ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) ); + LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx); + } + + /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ + // AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), + // "nb_antennas_rx too large"); + ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); + for (j=0;j<4;j++) ru->prach_rxsigF_br[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); + + for (i=0; i<ru->nb_rx; i++) { + ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); + LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]); +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + for (j=0;j<4;j++) { + ru->prach_rxsigF_br[j][i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); + LOG_D(PHY,"[INIT] prach_vars_br->rxsigF[%d] = %p\n",i,ru->prach_rxsigF_br[j][i]); + } +#endif + } + + AssertFatal(RC.nb_L1_inst <= NUMBER_OF_eNB_MAX,"eNB instances %d > %d\n", + RC.nb_L1_inst,NUMBER_OF_eNB_MAX); + + LOG_D(PHY,"[INIT] %s() RC.nb_L1_inst:%d \n", __FUNCTION__, RC.nb_L1_inst); + + for (i=0; i<RC.nb_L1_inst; i++) { + for (p=0;p<15;p++) { + LOG_D(PHY,"[INIT] %s() nb_antenna_ports_eNB:%d \n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB); + if (p<ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p==5) { + LOG_D(PHY,"[INIT] %s() DO BEAM WEIGHTS nb_antenna_ports_eNB:%d nb_tx:%d\n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB, ru->nb_tx); + ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); + for (j=0; j<ru->nb_tx; j++) { + ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); + // antenna ports 0-3 are mapped on antennas 0-3 + // antenna port 4 is mapped on antenna 0 + // antenna ports 5-14 are mapped on all antennas + if (((p<4) && (p==j)) || ((p==4) && (j==0))) { + for (re=0; re<fp->ofdm_symbol_size; re++) + { + ru->beam_weights[i][p][j][re] = 0x00007fff; + + //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); + } + } + else if (p>4) { + for (re=0; re<fp->ofdm_symbol_size; re++) + { + ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; + //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); + } + } + //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); + } // for (j=0 + } // if (p<ru + } // for p + } //for i + } // !=IF5 + ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_tti ); + + return(0); +} + +void phy_free_RU(RU_t *ru) +{ + int i,j; + int p; + + LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx); + + if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals + for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]); + for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata[i]); + free_and_zero(ru->common.txdata); + free_and_zero(ru->common.rxdata); + } // else: IF5 or local RF -> nothing to free() + + if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing + for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]); + free_and_zero(ru->common.rxdata_7_5kHz); + + // free IFFT input buffers (TX) + for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]); + free_and_zero(ru->common.txdataF_BF); + + // free FFT output buffers (RX) + for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]); + free_and_zero(ru->common.rxdataF); + + for (i = 0; i < ru->nb_rx; i++) { + free_and_zero(ru->prach_rxsigF[i]); +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]); +#endif + } + for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]); + free_and_zero(ru->prach_rxsigF); + /* ru->prach_rxsigF_br is not allocated -> don't free */ + + for (i = 0; i < RC.nb_L1_inst; i++) { + for (p = 0; p < 15; p++) { + if (p < ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p == 5) { + for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); + free_and_zero(ru->beam_weights[i][p]); + } + } + } + } + free_and_zero(ru->common.sync_corr); +} diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..8b6acc65f0ed15145a1b782cbe537bf8165190a4 --- /dev/null +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -0,0 +1,971 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "phy_init.h" +#include "SCHED_UE/sched_UE.h" +#include "PHY/phy_extern_ue.h" +#include "SIMULATION/TOOLS/sim.h" +#include "RadioResourceConfigCommonSIB.h" +#include "RadioResourceConfigDedicated.h" +#include "TDD-Config.h" +#include "MBSFN-SubframeConfigList.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "assertions.h" +#include <math.h> +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" + +uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10}; +extern uint8_t nfapi_mode; + +void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, + uint8_t eNB_id, + TDD_Config_t *tdd_Config, + uint8_t SIwindowsize, + uint16_t SIperiod) +{ + + LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; + + if (tdd_Config) { + fp->tdd_config = tdd_Config->subframeAssignment; + fp->tdd_config_S = tdd_Config->specialSubframePatterns; + } + + fp->SIwindowsize = SIwindowsize; + fp->SIPeriod = SIperiod; +} + +void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, + uint8_t eNB_id, + RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + ARFCN_ValueEUTRA_t *ul_CarrierFreq, + long *ul_Bandwidth, + AdditionalSpectrumEmission_t *additionalSpectrumEmission, + struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) +{ + + PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + LTE_DL_FRAME_PARMS *fp = &ue->frame_parms; + int i; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_IN); + + LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,eNB_id); + + fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; + + fp->prach_config_common.prach_Config_enabled=1; + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag; + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; + fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset; + + compute_prach_seq(fp->prach_config_common.rootSequenceIndex, + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type,ue->X_u); + + + + fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift; + fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI; + fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon.nCS_AN; + fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN; + + + + fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon.referenceSignalPower; + fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon.p_b; + + + fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; + fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; + fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; + fp->pusch_config_common.enable64QAM = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = dmrs1_tab_ue[radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift]; + + + init_ul_hopping(fp); + fp->soundingrs_ul_config_common.enabled_flag = 0; + + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { + fp->soundingrs_ul_config_common.enabled_flag = 1; + fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; + fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; + fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) + fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; + else + fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; + } + + + + fp->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUSCH; + fp->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon.alpha; + fp->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH; + fp->ul_power_control_config_common.deltaPreambleMsg3 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaPreambleMsg3; + fp->ul_power_control_config_common.deltaF_PUCCH_Format1 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1; + fp->ul_power_control_config_common.deltaF_PUCCH_Format1b = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b; + fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2; + fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a; + fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b; + + fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx; + + // Now configure some of the Physical Channels + + // PUCCH + init_ncs_cell(fp,ue->ncs_cell); + + init_ul_hopping(fp); + + // PCH + init_ue_paging_info(ue,radioResourceConfigCommon->pcch_Config.defaultPagingCycle,radioResourceConfigCommon->pcch_Config.nB); + + // MBSFN + + if (mbsfn_SubframeConfigList != NULL) { + fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; + + for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { + fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; + fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; + + if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + fp->MBSFN_config[i].fourFrames_flag = 0; + fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + fp->MBSFN_config[i].fourFrames_flag = 1; + fp->MBSFN_config[i].mbsfn_SubframeConfig = + mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); + + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_OUT); + +} + +void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx, + long mbsfn_AreaId_r9) +{ + + LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; + + + LOG_I(PHY,"[UE%d] Applying MBSFN_Area_id %ld for index %d\n",Mod_id,mbsfn_AreaId_r9,mbsfn_Area_idx); + + if (mbsfn_Area_idx == 0) { + fp->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9; + LOG_N(PHY,"Fix me: only called when mbsfn_Area_idx == 0)\n"); + } + + lte_gold_mbsfn(fp,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_mbsfn_table,fp->Nid_cell_mbsfn); + +} + + +/* + * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover + */ +void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed) +{ + + if(mobilityControlInfo!=NULL) { + RadioResourceConfigCommon_t *radioResourceConfigCommon = &mobilityControlInfo->radioResourceConfigCommon; + LOG_I(PHY,"radioResourceConfigCommon %p\n", radioResourceConfigCommon); + memcpy((void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms_before_ho, + (void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms, + sizeof(LTE_DL_FRAME_PARMS)); + PHY_vars_UE_g[Mod_id][CC_id]->ho_triggered = 1; + //PHY_vars_UE_g[UE_id]->UE_mode[0] = PRACH; + + LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; + // int N_ZC; + // uint8_t prach_fmt; + // int u; + + LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n", + Mod_id,eNB_id); + + fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; + fp->prach_config_common.prach_Config_enabled=1; + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex; + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag; + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig; + fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset; + + // prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,fp->frame_type); + // N_ZC = (prach_fmt <4)?839:139; + // u = (prach_fmt < 4) ? prach_root_sequence_map0_3[fp->prach_config_common.rootSequenceIndex] : + // prach_root_sequence_map4[fp->prach_config_common.rootSequenceIndex]; + + //compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u); + compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex, + PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + PHY_vars_UE_g[Mod_id][CC_id]->X_u); + + + fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift; + fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon->nRB_CQI; + fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon->nCS_AN; + fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon->n1PUCCH_AN; + fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon->referenceSignalPower; + fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon->p_b; + + + fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; + fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; + fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; + fp->pusch_config_common.enable64QAM = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; + + init_ul_hopping(fp); + fp->soundingrs_ul_config_common.enabled_flag = 0; + + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->present==SoundingRS_UL_ConfigCommon_PR_setup) { + fp->soundingrs_ul_config_common.enabled_flag = 1; + fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_BandwidthConfig; + fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; + fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.ackNackSRS_SimultaneousTransmission; + + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_MaxUpPts) + fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; + else + fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; + } + + fp->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUSCH; + fp->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon->alpha; + fp->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUCCH; + fp->ul_power_control_config_common.deltaPreambleMsg3 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaPreambleMsg3; + fp->ul_power_control_config_common.deltaF_PUCCH_Format1 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1; + fp->ul_power_control_config_common.deltaF_PUCCH_Format1b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1b; + fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2; + fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2a; + fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2b; + + fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon->maxHARQ_Msg3Tx; + + // Now configure some of the Physical Channels + if (radioResourceConfigCommon->antennaInfoCommon) + fp->nb_antennas_tx = (1<<radioResourceConfigCommon->antennaInfoCommon->antennaPortsCount); + else + fp->nb_antennas_tx = 1; + + //PHICH + if (radioResourceConfigCommon->antennaInfoCommon) { + fp->phich_config_common.phich_resource = radioResourceConfigCommon->phich_Config->phich_Resource; + fp->phich_config_common.phich_duration = radioResourceConfigCommon->phich_Config->phich_Duration; + } + + //Target CellId + fp->Nid_cell = mobilityControlInfo->targetPhysCellId; + fp->nushift = fp->Nid_cell%6; + + // PUCCH + init_ncs_cell(fp,PHY_vars_UE_g[Mod_id][CC_id]->ncs_cell); + + init_ul_hopping(fp); + + // RNTI + + + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); + + LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); + } + + if(ho_failed) { + LOG_D(PHY,"[UE%d] Handover failed, triggering RACH procedure\n",Mod_id); + memcpy((void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms,(void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms_before_ho, sizeof(LTE_DL_FRAME_PARMS)); + PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_id] = PRACH; + } +} + +void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id) +{ + + PHY_MEASUREMENTS *phy_meas = &PHY_vars_UE_g[Mod_id][CC_id]->measurements; + int i; + + LOG_I(PHY,"Configuring inter-cell measurements for %d cells, ids: \n",n_adj_cells); + + for (i=0; i<n_adj_cells; i++) { + LOG_I(PHY,"%d\n",adj_cell_id[i]); + lte_gold(&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_table[i+1],adj_cell_id[i]); + } + + phy_meas->n_adj_cells = n_adj_cells; + memcpy((void*)phy_meas->adj_cell_id,(void *)adj_cell_id,n_adj_cells*sizeof(unsigned int)); + +} + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +void phy_config_dedicated_scell_ue(uint8_t Mod_id, + uint8_t eNB_index, + SCellToAddMod_r10_t *sCellToAddMod_r10, + int CC_id) +{ + +} +#endif + + +void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, + uint16_t max_harq_tx ) +{ + + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; + phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx; +} + +extern uint16_t beta_cqi[16]; + +void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, + struct PhysicalConfigDedicated *physicalConfigDedicated ) +{ + + static uint8_t first_dedicated_configuration = 0; + PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; + + phy_vars_ue->total_TBS[eNB_id]=0; + phy_vars_ue->total_TBS_last[eNB_id]=0; + phy_vars_ue->bitrate[eNB_id]=0; + phy_vars_ue->total_received_bits[eNB_id]=0; + phy_vars_ue->dlsch_errors[eNB_id]=0; + phy_vars_ue->dlsch_errors_last[eNB_id]=0; + phy_vars_ue->dlsch_received[eNB_id]=0; + phy_vars_ue->dlsch_received_last[eNB_id]=0; + phy_vars_ue->dlsch_fer[eNB_id]=0; + + phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; + phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; + + if (physicalConfigDedicated) { + LOG_D(PHY,"[UE %d] Received physicalConfigDedicated from eNB %d\n",Mod_id, eNB_id); + LOG_D(PHY,"------------------------------------------------------------------------\n"); + + if (physicalConfigDedicated->pdsch_ConfigDedicated) { + phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a=physicalConfigDedicated->pdsch_ConfigDedicated->p_a; + LOG_D(PHY,"pdsch_config_dedicated.p_a %d\n",phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a); + LOG_D(PHY,"\n"); + } + + if (physicalConfigDedicated->pucch_ConfigDedicated) { + if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==PUCCH_ConfigDedicated__ackNackRepetition_PR_release) + phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=0; + else { + phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=1; + } + + if (physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) + phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = *physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; + else + phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = bundling; + + if ( phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode == multiplexing) + LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = multiplexing\n"); + else + LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = bundling\n"); + } + + if (physicalConfigDedicated->pusch_ConfigDedicated) { + phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; + phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; + phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; + + + LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index); + LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index); + LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index,beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]); + LOG_D(PHY,"\n"); + + + } + + if (physicalConfigDedicated->uplinkPowerControlDedicated) { + + phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH = physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUSCH; + phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled= physicalConfigDedicated->uplinkPowerControlDedicated->deltaMCS_Enabled; + phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled= physicalConfigDedicated->uplinkPowerControlDedicated->accumulationEnabled; + phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH= physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUCCH; + phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset= physicalConfigDedicated->uplinkPowerControlDedicated->pSRS_Offset; + phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient= *physicalConfigDedicated->uplinkPowerControlDedicated->filterCoefficient; + LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUSCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH); + LOG_D(PHY,"ul_power_control_dedicated.deltaMCS_Enabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled); + LOG_D(PHY,"ul_power_control_dedicated.accumulationEnabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled); + LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUCCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH); + LOG_D(PHY,"ul_power_control_dedicated.pSRS_Offset %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset); + LOG_D(PHY,"ul_power_control_dedicated.filterCoefficient %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient); + LOG_D(PHY,"\n"); + } + + if (physicalConfigDedicated->antennaInfo) { + phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); + LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); + switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { + case AntennaInfoDedicated__transmissionMode_tm1: + phy_vars_ue->transmission_mode[eNB_id] = 1; + break; + case AntennaInfoDedicated__transmissionMode_tm2: + phy_vars_ue->transmission_mode[eNB_id] = 2; + break; + case AntennaInfoDedicated__transmissionMode_tm3: + phy_vars_ue->transmission_mode[eNB_id] = 3; + break; + case AntennaInfoDedicated__transmissionMode_tm4: + phy_vars_ue->transmission_mode[eNB_id] = 4; + break; + case AntennaInfoDedicated__transmissionMode_tm5: + phy_vars_ue->transmission_mode[eNB_id] = 5; + break; + case AntennaInfoDedicated__transmissionMode_tm6: + phy_vars_ue->transmission_mode[eNB_id] = 6; + break; + case AntennaInfoDedicated__transmissionMode_tm7: + lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); + phy_vars_ue->transmission_mode[eNB_id] = 7; + break; + default: + LOG_E(PHY,"Unknown transmission mode!\n"); + break; + } + } else { + LOG_D(PHY,"[UE %d] Received NULL physicalConfigDedicated->antennaInfo from eNB %d\n",Mod_id, eNB_id); + } + + if (physicalConfigDedicated->schedulingRequestConfig) { + if (physicalConfigDedicated->schedulingRequestConfig->present == SchedulingRequestConfig_PR_setup) { + phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; + phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex; + phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax; + + LOG_D(PHY,"scheduling_request_config.sr_PUCCH_ResourceIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + LOG_D(PHY,"scheduling_request_config.sr_ConfigIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex); + LOG_D(PHY,"scheduling_request_config.dsr_TransMax %d\n",phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax); + } + + LOG_D(PHY,"------------------------------------------------------------\n"); + + } + + if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { + + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0; + if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1; + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth; + phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; + + + LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex); + } + + LOG_D(PHY,"------------------------------------------------------------\n"); + + } + + + if (physicalConfigDedicated->cqi_ReportConfig) { + if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) { + // configure PUSCH CQI reporting + phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; + if ((phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm12) && + (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm30) && + (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm31)) + LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic); + } + if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { + if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { + // configure PUCCH CQI reporting + phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; + if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) + phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex; + } + else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_release) { + // handle release + phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; + phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; + } + } + } + +#ifdef CBA + + if (physicalConfigDedicated->pusch_CBAConfigDedicated_vlola) { + phy_vars_ue->pusch_ca_config_dedicated[eNB_id].betaOffset_CA_Index = (uint16_t) *physicalConfigDedicated->pusch_CBAConfigDedicated_vlola->betaOffset_CBA_Index; + phy_vars_ue->pusch_ca_config_dedicated[eNB_id].cShift = (uint16_t) *physicalConfigDedicated->pusch_CBAConfigDedicated_vlola->cShift_CBA; + LOG_D(PHY,"[UE %d ] physicalConfigDedicated pusch CBA config dedicated: beta offset %d cshift %d \n",Mod_id, + phy_vars_ue->pusch_ca_config_dedicated[eNB_id].betaOffset_CA_Index, + phy_vars_ue->pusch_ca_config_dedicated[eNB_id].cShift); + } + +#endif + } else { + LOG_D(PHY,"[PHY][UE %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id,eNB_id); + return; + } + + // fill cqi parameters for periodic CQI reporting + get_cqipmiri_params(phy_vars_ue,eNB_id); + + // disable MIB SIB decoding once we are on connected mode + first_dedicated_configuration ++; + if(first_dedicated_configuration > 1) + { + LOG_I(PHY,"Disable SIB MIB decoding \n"); + phy_vars_ue->decode_SIB = 0; + phy_vars_ue->decode_MIB = 0; + } + + if(nfapi_mode!=3){ + //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) + phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; + else + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + + LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); + } + + +} + +/*! \brief Helper function to allocate memory for DLSCH data structures. + * \param[out] pdsch Pointer to the LTE_UE_PDSCH structure to initialize. + * \param[in] frame_parms LTE_DL_FRAME_PARMS structure. + * \note This function is optimistic in that it expects malloc() to succeed. + */ +void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS* const fp ) +{ + AssertFatal( pdsch, "pdsch==0" ); + + pdsch->pmi_ext = (uint8_t*)malloc16_clear( fp->N_RB_DL ); + pdsch->llr[0] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + pdsch->llr128 = (int16_t**)malloc16_clear( sizeof(int16_t*) ); + // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV + // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there + + + pdsch->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->rxdataF_uespec_pilots = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->rxdataF_comp0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); + pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->dl_bf_ch_estimates = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->dl_bf_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + //pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + //pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->dl_ch_mag0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->dl_ch_magb0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + + + // the allocated memory size is fixed: + AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); + + for (int i=0; i<fp->nb_antennas_rx; i++) { + pdsch->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); + + for (int j=0; j<4; j++) { //fp->nb_antennas_tx; j++) + const int idx = (j<<1)+i; + const size_t num = 7*2*fp->N_RB_DL*12; + pdsch->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->rxdataF_uespec_pilots[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); + pdsch->rxdataF_comp0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_bf_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); + pdsch->dl_bf_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + //pdsch->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + //pdsch->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_mag0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_magb0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + } + } +} + +int init_lte_ue_signal(PHY_VARS_UE *ue, + int nb_connected_eNB, + uint8_t abstraction_flag) +{ + + // create shortcuts + LTE_DL_FRAME_PARMS* const fp = &ue->frame_parms; + LTE_UE_COMMON* const common_vars = &ue->common_vars; + LTE_UE_PDSCH** const pdsch_vars_SI = ue->pdsch_vars_SI; + LTE_UE_PDSCH** const pdsch_vars_ra = ue->pdsch_vars_ra; + LTE_UE_PDSCH** const pdsch_vars_p = ue->pdsch_vars_p; + LTE_UE_PDSCH** const pdsch_vars_mch = ue->pdsch_vars_MCH; + LTE_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars; + LTE_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdcch_vars; + LTE_UE_PBCH** const pbch_vars = ue->pbch_vars; + LTE_UE_PRACH** const prach_vars = ue->prach_vars; + + + + int i,j,k,l; + int eNB_id; + int th_id; + + LOG_D(PHY,"Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx); + + + + + init_frame_parms(&ue->frame_parms,1); + init_lte_top(&ue->frame_parms); + init_ul_hopping(&ue->frame_parms); + + + // many memory allocation sizes are hard coded + AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" ); + AssertFatal( ue->n_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" ); + // init phy_vars_ue + + for (i=0; i<4; i++) { + ue->rx_gain_max[i] = 135; + ue->rx_gain_med[i] = 128; + ue->rx_gain_byp[i] = 120; + } + + ue->n_connected_eNB = nb_connected_eNB; + + for(eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { + ue->total_TBS[eNB_id] = 0; + ue->total_TBS_last[eNB_id] = 0; + ue->bitrate[eNB_id] = 0; + ue->total_received_bits[eNB_id] = 0; + } + + for (i=0;i<10;i++) + ue->tx_power_dBm[i]=-127; + + + + // init TX buffers + + common_vars->txdata = (int32_t**)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) ); + common_vars->txdataF = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) ); + + for (i=0; i<fp->nb_antennas_tx; i++) { + + common_vars->txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); + common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); + } + + // init RX buffers + + common_vars->rxdata = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + common_vars->common_vars_rx_data_per_thread[0].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + common_vars->common_vars_rx_data_per_thread[1].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + + for (i=0; i<fp->nb_antennas_rx; i++) { + common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_tti*10+2048)*sizeof(int32_t) ); + common_vars->common_vars_rx_data_per_thread[0].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); + common_vars->common_vars_rx_data_per_thread[1].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); + } + + + // Channel estimates + for (eNB_id=0; eNB_id<7; eNB_id++) { + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*)); + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*)); + } + + for (i=0; i<fp->nb_antennas_rx; i++) + for (j=0; j<4; j++) { + int idx = (j<<1) + i; + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) ); + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 ); + } + } + } + + // DLSCH + for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) { + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); + } + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH)); + } + + pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); + pdsch_vars_ra[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); + pdsch_vars_p[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); + pdsch_vars_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); + prach_vars[eNB_id] = (LTE_UE_PRACH *)malloc16_clear(sizeof(LTE_UE_PRACH)); + pbch_vars[eNB_id] = (LTE_UE_PBCH *)malloc16_clear(sizeof(LTE_UE_PBCH)); + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp ); + } + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12); + (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts_p = (*pdsch_vars_th)[0][eNB_id]->llr_shifts; + (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + (*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) ); + (*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); + } + + for (int i=0; i<fp->nb_antennas_rx; i++){ + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + } + + } + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + } + + for (i=0; i<fp->nb_antennas_rx; i++) + for (j=0; j<4; j++) { + const int idx = (j<<1)+i; + const size_t num = 7*2*fp->N_RB_DL*12+4; + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + } + + } + + //const size_t num = 7*2*fp->N_RB_DL*12+4; + for (k=0;k<8;k++) { //harq_pid + for (l=0;l<8;l++) { //round + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + } + + + for (int i=0; i<fp->nb_antennas_rx; i++) + for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) + const int idx = (j<<1)+i; + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + } + + } + } + } + phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); + phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); + phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); + phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); + + // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); + + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + } + + for (i=0; i<fp->nb_antennas_rx; i++) { + //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); + } + + for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++) + int idx = (j<<1)+i; + // size_t num = 7*2*fp->N_RB_DL*12; + size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + } + } + } + phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); + phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); + phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); + phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); + + // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); + + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + + (*pdcch_vars_th)[th_id][eNB_id]->dciFormat = 0; + (*pdcch_vars_th)[th_id][eNB_id]->agregationLevel = 0xFF; + } + + for (i=0; i<fp->nb_antennas_rx; i++) { + //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); + } + + for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++) + int idx = (j<<1)+i; + // size_t num = 7*2*fp->N_RB_DL*12; + size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + } + } + } + + // PBCH + pbch_vars[eNB_id]->rxdataF_ext = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + pbch_vars[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pbch_vars[eNB_id]->llr = (int8_t*)malloc16_clear( 1920 ); + prach_vars[eNB_id]->prachF = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); + prach_vars[eNB_id]->prach = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); + + for (i=0; i<fp->nb_antennas_rx; i++) { + pbch_vars[eNB_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); + + for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) { + int idx = (j<<1)+i; + pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); + pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); + } + } + + + pbch_vars[eNB_id]->decoded_output = (uint8_t*)malloc16_clear( 64 ); + } + + // initialization for the last instance of pdsch_vars (used for MU-MIMO) + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); + } + + pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); + pdsch_vars_ra[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); + pdsch_vars_p[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp ); + (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + } + + + ue->sinr_CQI_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) ); + + ue->init_averaging = 1; + // default value until overwritten by RRCConnectionReconfiguration + if (fp->nb_antenna_ports_eNB==2) + ue->pdsch_config_dedicated->p_a = dBm3; + else + ue->pdsch_config_dedicated->p_a = dB0; + + // set channel estimation to do linear interpolation in time + ue->high_speed_flag = 1; + ue->ch_est_alpha = 24576; + + // enable MIB/SIB decoding by default + ue->decode_MIB = 1; + ue->decode_SIB = 1; + + init_prach_tables(839); + + + return 0; +} + +void init_lte_ue_transport(PHY_VARS_UE *ue,int abstraction_flag) { + + int i,j,k; + + for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { + for (j=0; j<2; j++) { + for (k=0; k<2; k++) { + AssertFatal((ue->dlsch[k][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); + + LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[i][j]); + } + } + + AssertFatal((ue->ulsch[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n"); + + ue->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); + ue->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); + + ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_eNB==1 ? 1 : 2; + } + + ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; + + ue->dlsch_MCH[0] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0); + +} diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index d510fc7261e908f153e6f1d714982997125f9799..0830058a8fb4bda41bb692a4e29b9aa460fb7104 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -25,23 +25,34 @@ #include <execinfo.h> #include <signal.h> -#include "SIMULATION/TOOLS/defs.h" +#include "SIMULATION/TOOLS/sim.h" #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern.h" +#include "phy_init.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" extern PHY_VARS_eNB *eNB; extern PHY_VARS_UE *UE; +extern RU_t *ru; +extern void phy_init_RU(RU_t*); -void lte_param_init(unsigned char N_tx_port_eNB, +void lte_param_init(PHY_VARS_eNB **eNBp, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, unsigned char N_tx_phy, - unsigned char N_rx, + unsigned char N_rx_ru, + unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, - frame_t frame_type, + frame_t frame_type, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, + uint8_t pa, uint8_t threequarter_fs, uint8_t osf, uint32_t perfect_ce) @@ -49,13 +60,27 @@ void lte_param_init(unsigned char N_tx_port_eNB, LTE_DL_FRAME_PARMS *frame_parms; int i; - + PHY_VARS_eNB *eNB; + PHY_VARS_UE *UE; + RU_t *ru; printf("Start lte_param_init\n"); - eNB = malloc(sizeof(PHY_VARS_eNB)); - UE = malloc(sizeof(PHY_VARS_UE)); + *eNBp = malloc(sizeof(PHY_VARS_eNB)); + *UEp = malloc(sizeof(PHY_VARS_UE)); + *rup = malloc(sizeof(RU_t)); + eNB = *eNBp; + UE = *UEp; + ru = *rup; + printf("eNB %p, UE %p, ru %p\n",eNB,UE,ru); + + + memset((void*)eNB,0,sizeof(PHY_VARS_eNB)); memset((void*)UE,0,sizeof(PHY_VARS_UE)); + memset((void*)ru,0,sizeof(RU_t)); + ru->eNB_list[0] = eNB; + eNB->RU_list[0] = ru; + ru->num_eNB=1; srand(0); randominit(0); @@ -71,7 +96,7 @@ void lte_param_init(unsigned char N_tx_port_eNB, frame_parms->Nid_cell = Nid_cell; frame_parms->nushift = Nid_cell%6; frame_parms->nb_antennas_tx = N_tx_phy; - frame_parms->nb_antennas_rx = N_rx; + frame_parms->nb_antennas_rx = N_rx_ru; frame_parms->nb_antenna_ports_eNB = N_tx_port_eNB; frame_parms->phich_config_common.phich_resource = oneSixth; frame_parms->phich_config_common.phich_duration = normal; @@ -90,12 +115,18 @@ void lte_param_init(unsigned char N_tx_port_eNB, UE->is_secondary_ue = 0; UE->frame_parms = *frame_parms; - eNB->frame_parms = *frame_parms; + UE->frame_parms.nb_antennas_rx=N_rx_ue; + // eNB->frame_parms = *frame_parms; + ru->frame_parms = *frame_parms; + ru->nb_tx = N_tx_phy; + ru->nb_rx = N_rx_ru; + ru->if_south = LOCAL_RF; + + eNB->configured=1; eNB->transmission_mode[0] = transmission_mode; UE->transmission_mode[0] = transmission_mode; - init_lte_top(frame_parms); dump_frame_parms(frame_parms); UE->measurements.n_adj_cells=0; @@ -105,23 +136,24 @@ void lte_param_init(unsigned char N_tx_port_eNB, for (i=0; i<3; i++) lte_gold(frame_parms,UE->lte_gold_table[i],Nid_cell+i); - init_lte_ue(UE,1,0); + printf("Calling init_lte_ue_signal\n"); + init_lte_ue_signal(UE,1,0); + printf("Calling phy_init_lte_eNB\n"); phy_init_lte_eNB(eNB,0,0); - + printf("Calling phy_init_RU (%p)\n",ru); + phy_init_RU(ru); generate_pcfich_reg_mapping(&UE->frame_parms); generate_phich_reg_mapping(&UE->frame_parms); // DL power control init //if (transmission_mode == 1) { + UE->pdsch_config_dedicated->p_a = pa; + if (transmission_mode == 1 || transmission_mode ==7) { - eNB->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB ((eNB->frame_parms).pdsch_config_common).p_b = 0; - UE->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 0; } else { // rho_a = rhob - eNB->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((eNB->frame_parms).pdsch_config_common).p_b = 1; - UE->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 1; } @@ -130,6 +162,13 @@ void lte_param_init(unsigned char N_tx_port_eNB, /* the UE code is multi-thread "aware", we need to setup this array */ for (i = 0; i < 10; i++) UE->current_thread_id[i] = i % 2; + if (eNB->frame_parms.frame_type == TDD) { + if (eNB->frame_parms.N_RB_DL == 100) ru->N_TA_offset = 624; + else if (eNB->frame_parms.N_RB_DL == 50) ru->N_TA_offset = 624/2; + else if (eNB->frame_parms.N_RB_DL == 25) ru->N_TA_offset = 624/4; + } + else ru->N_TA_offset=0; + printf("Done lte_param_init\n"); diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c index 2f2bd95617ebcffa60092376e9778935bd3ce877..e7c4ced5d37351977dc61f7d21e9c85ff8516905 100644 --- a/openair1/PHY/INIT/lte_parms.c +++ b/openair1/PHY/INIT/lte_parms.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -#include "defs.h" +#include "phy_init.h" #include "log.h" uint16_t dl_S_table_normal[10]={3,9,10,11,12,3,9,10,11,6}; diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/phy_init.h similarity index 95% rename from openair1/PHY/INIT/defs.h rename to openair1/PHY/INIT/phy_init.h index 744fb3d3ceb30ec24e58780daaaaae5e35353a20..8da34fc51cb9bc9ef43349e3fcf750f37e3afdc4 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/phy_init.h @@ -22,8 +22,8 @@ #ifndef __INIT_DEFS__H__ #define __INIT_DEFS__H__ -#include "PHY/defs.h" - +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" #include "SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" @@ -32,7 +32,7 @@ #include "PHICH-Config.h" #include "MBSFN-SubframeConfigList.h" #include "MobilityControlInfo.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "SCellToAddMod-r10.h" #endif /** @addtogroup _PHY_STRUCTURES_ @@ -90,6 +90,13 @@ int phy_init_lte_eNB(PHY_VARS_eNB *phy_vars_eNb, unsigned char is_secondary_eNb, unsigned char abstraction_flag); +/*! +\brief Free the PHY variables relevant to the LTE implementation (eNB). +\details Only a subset of phy_vars_eNb is freed (those who have been allocated with phy_init_lte_eNB()). +@param[in] phy_vars_eNb Pointer to eNB Variables + */ +void phy_free_lte_eNB(PHY_VARS_eNB *phy_vars_eNb); + /** \brief Configure LTE_DL_FRAME_PARMS with components derived after initial synchronization (MIB decoding + primary/secondary synch). \details The basically allows configuration of \f$N_{\mathrm{RB}}^{\mathrm{DL}}\f$, the cell id \f$N_{\mathrm{ID}}^{\mathrm{cell}}\f$, the normal/extended prefix mode, the frame type (FDD/TDD), \f$N_{\mathrm{cp}}\f$, the number of TX antennas at eNB (\f$p\f$) and the number of PHICH groups, \f$N_{\mathrm{group}}^{\mathrm{PHICH}}\f$ @param lte_frame_parms pointer to LTE parameter structure @@ -317,25 +324,32 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *phy_vars_eNB); */ int phy_init_secsys_eNB(PHY_VARS_eNB *phy_vars_eNb); +void free_lte_top(void); void init_lte_top(LTE_DL_FRAME_PARMS *lte_frame_parms); //void copy_lte_parms_to_phy_framing(LTE_DL_FRAME_PARMS *frame_parm, PHY_FRAMING *phy_framing); -void lte_param_init(unsigned char N_tx_port_eNB, - unsigned char N_tx, - unsigned char N_rx, +void lte_param_init(PHY_VARS_eNB **eNBp, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, + unsigned char N_tx_phy, + unsigned char N_rx_ru, + unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, - frame_t frame_type, + frame_t frame_type, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, + uint8_t pa, uint8_t threequarter_fs, uint8_t osf, uint32_t perfect_ce); -#if defined(Rel10) || defined(Rel14) + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, SCellToAddMod_r10_t *sCellToAddMod_r10, @@ -359,18 +373,6 @@ void phy_config_request(PHY_Config_t *phy_config); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); -void lte_param_init(unsigned char N_tx_port_eNB, - unsigned char N_tx_phy, - unsigned char N_rx, - unsigned char transmission_mode, - uint8_t extended_prefix_flag, - frame_t frame_type, - uint16_t Nid_cell, - uint8_t tdd_config, - uint8_t N_RB_DL, - uint8_t threequarter_fs, - uint8_t osf, - uint32_t perfect_ce); /** @} */ #endif diff --git a/openair1/PHY/LTE_ESTIMATION/adjust_gain.c b/openair1/PHY/LTE_ESTIMATION/adjust_gain.c index 7272b7247d93f451754d41eadfa5edfaf2b51057..27e6c106863e98a5d317bfad32926583536205bc 100644 --- a/openair1/PHY/LTE_ESTIMATION/adjust_gain.c +++ b/openair1/PHY/LTE_ESTIMATION/adjust_gain.c @@ -20,8 +20,8 @@ */ #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" void phy_adjust_gain (PHY_VARS_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id) diff --git a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c index 74a844da8ad943806bbd0ffe7e04c52ff63f3c03..3fd58a4989701d795401ae296b3a4241e159136a 100644 --- a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c +++ b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" #include "PHY/sse_intrin.h" // This is 512/(1:256) in __m128i format @@ -306,7 +306,7 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms, AssertFatal(symbol<frame_parms->symbols_per_tti,"symbol %d >= %d\n", symbol,frame_parms->symbols_per_tti); - AssertFatal(Msc_RS<frame_parms->N_RB_UL*12,"Msc_RS %d >= %d\n", + AssertFatal(Msc_RS<=frame_parms->N_RB_UL*12,"Msc_RS %d >= %d\n", Msc_RS,frame_parms->N_RB_UL*12); for (re=0; re<(Msc_RS>>2); re++) { diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c index afa7985962ff4099a2a9a766b1259f066de28b12..e268a5b061c0e06031681909be23cfbb4acc87cd 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c @@ -20,10 +20,11 @@ */ #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #include "UTIL/LOG/vcd_signal_dumper.h" +#include "openair2/LAYER2/MAC/mac_proto.h" #define DEBUG_PHY @@ -84,6 +85,11 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); +#if BASIC_SIMULATOR + /* a hack without which the UE does not connect (to be fixed somehow) */ + diff = 0; +#endif + if ( abs(diff) < SYNCH_HYST ) ue->rx_offset = 0; else @@ -134,128 +140,3 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); } } - - -int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms, - LTE_eNB_SRS *lte_eNB_srs, - unsigned int *eNB_id, - unsigned char clear, - unsigned char number_of_cards, - short coef) - -{ - - static int max_pos_fil2 = 0; - int temp, i, aa, max_pos = 0,ind; - int max_val=0; - short Re,Im,ncoef; -#ifdef DEBUG_PHY - char fname[100],vname[100]; -#endif - - ncoef = 32768 - coef; - - for (ind=0; ind<number_of_cards; ind++) { - - if (ind==0) - max_val=0; - - - for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - // do ifft of channel estimate - switch(frame_parms->N_RB_DL) { - case 6: - dft128((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], - (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], - 1); - break; - case 25: - dft512((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], - (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], - 1); - break; - case 50: - dft1024((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], - (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], - 1); - break; - case 100: - dft2048((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], - (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], - 1); - break; - } -#ifdef DEBUG_PHY - sprintf(fname,"srs_ch_estimates_time_%d%d.m",ind,aa); - sprintf(vname,"srs_time_%d%d",ind,aa); - write_output(fname,vname,lte_eNB_srs->srs_ch_estimates_time[aa],frame_parms->ofdm_symbol_size*2,2,1); -#endif - } - - // we only use channel estimates from tx antenna 0 here - // remember we fixed the SRS to use only every second subcarriers - for (i = 0; i < frame_parms->ofdm_symbol_size/2; i++) { - temp = 0; - - for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)lte_eNB_srs->srs_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)lte_eNB_srs->srs_ch_estimates_time[aa])[1+(i<<1)]; - temp += (Re*Re/2) + (Im*Im/2); - } - - if (temp > max_val) { - max_pos = i; - max_val = temp; - *eNB_id = ind; - } - } - } - - // filter position to reduce jitter - if (clear == 1) - max_pos_fil2 = max_pos; - else - max_pos_fil2 = ((max_pos_fil2 * coef) + (max_pos * ncoef)) >> 15; - - return(max_pos_fil2); -} - - -int lte_est_timing_advance_pusch(PHY_VARS_eNB* eNB,module_id_t UE_id) -{ - int temp, i, aa, max_pos=0, max_val=0; - short Re,Im; - - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; - LTE_eNB_PUSCH *eNB_pusch_vars = eNB->pusch_vars[UE_id]; - int32_t **ul_ch_estimates_time= eNB_pusch_vars->drs_ch_estimates_time; - uint8_t cyclic_shift = 0; - int sync_pos = (frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size); - - AssertFatal(frame_parms->ofdm_symbol_size > 127,"frame_parms->ofdm_symbol_size %d<128\n",frame_parms->ofdm_symbol_size); - AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<3,"frame_parms->nb_antennas_rx %d not in [0,1]\n", - frame_parms->nb_antennas_rx); - for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { - temp = 0; - - for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; - temp += (Re*Re/2) + (Im*Im/2); - } - - if (temp > max_val) { - max_pos = i; - max_val = temp; - } - } - - if (max_pos>frame_parms->ofdm_symbol_size/2) - max_pos = max_pos-frame_parms->ofdm_symbol_size; - - //#ifdef DEBUG_PHY - LOG_D(PHY,"frame %d: max_pos = %d, sync_pos=%d\n",eNB->proc.frame_rx,max_pos,sync_pos); - //#endif //DEBUG_PHY - - return max_pos - sync_pos; -} diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c new file mode 100644 index 0000000000000000000000000000000000000000..f893b70baf7bf42f2d828fa8edef06c9470c12ae --- /dev/null +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c @@ -0,0 +1,153 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "PHY/types.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" + +#include "UTIL/LOG/vcd_signal_dumper.h" + +#define DEBUG_PHY + +int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms, + LTE_eNB_SRS *lte_eNB_srs, + unsigned int *eNB_id, + unsigned char clear, + unsigned char number_of_cards, + short coef) + +{ + + static int max_pos_fil2 = 0; + int temp, i, aa, max_pos = 0,ind; + int max_val=0; + short Re,Im,ncoef; +#ifdef DEBUG_PHY + char fname[100],vname[100]; +#endif + + ncoef = 32768 - coef; + + for (ind=0; ind<number_of_cards; ind++) { + + if (ind==0) + max_val=0; + + + for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { + // do ifft of channel estimate + switch(frame_parms->N_RB_DL) { + case 6: + dft128((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], + (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], + 1); + break; + case 25: + dft512((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], + (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], + 1); + break; + case 50: + dft1024((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], + (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], + 1); + break; + case 100: + dft2048((int16_t*) <e_eNB_srs->srs_ch_estimates[aa][0], + (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa], + 1); + break; + } +#ifdef DEBUG_PHY + sprintf(fname,"srs_ch_estimates_time_%d%d.m",ind,aa); + sprintf(vname,"srs_time_%d%d",ind,aa); + write_output(fname,vname,lte_eNB_srs->srs_ch_estimates_time[aa],frame_parms->ofdm_symbol_size*2,2,1); +#endif + } + + // we only use channel estimates from tx antenna 0 here + // remember we fixed the SRS to use only every second subcarriers + for (i = 0; i < frame_parms->ofdm_symbol_size/2; i++) { + temp = 0; + + for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { + Re = ((int16_t*)lte_eNB_srs->srs_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)lte_eNB_srs->srs_ch_estimates_time[aa])[1+(i<<1)]; + temp += (Re*Re/2) + (Im*Im/2); + } + + if (temp > max_val) { + max_pos = i; + max_val = temp; + *eNB_id = ind; + } + } + } + + // filter position to reduce jitter + if (clear == 1) + max_pos_fil2 = max_pos; + else + max_pos_fil2 = ((max_pos_fil2 * coef) + (max_pos * ncoef)) >> 15; + + return(max_pos_fil2); +} + + +int lte_est_timing_advance_pusch(PHY_VARS_eNB* eNB,module_id_t UE_id) +{ + int temp, i, aa, max_pos=0, max_val=0; + short Re,Im; + + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + LTE_eNB_PUSCH *eNB_pusch_vars = eNB->pusch_vars[UE_id]; + int32_t **ul_ch_estimates_time= eNB_pusch_vars->drs_ch_estimates_time; + uint8_t cyclic_shift = 0; + int sync_pos = (frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size); + + AssertFatal(frame_parms->ofdm_symbol_size > 127,"frame_parms->ofdm_symbol_size %d<128\n",frame_parms->ofdm_symbol_size); + AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<3,"frame_parms->nb_antennas_rx %d not in [0,1]\n", + frame_parms->nb_antennas_rx); + for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { + temp = 0; + + for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { + Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; + temp += (Re*Re/2) + (Im*Im/2); + } + + if (temp > max_val) { + max_pos = i; + max_val = temp; + } + } + + if (max_pos>frame_parms->ofdm_symbol_size/2) + max_pos = max_pos-frame_parms->ofdm_symbol_size; + + //#ifdef DEBUG_PHY + LOG_D(PHY,"frame %d: max_pos = %d, sync_pos=%d\n",eNB->proc.frame_rx,max_pos,sync_pos); + //#endif //DEBUG_PHY + + return max_pos - sync_pos; +} + diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..74d6248d1502029b7d0001a155bb306690f8a904 --- /dev/null +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c @@ -0,0 +1,138 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "PHY/types.h" +#include "PHY/defs_UE.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" +#include "PHY/impl_defs_top.h" +#include "openair2/LAYER2/MAC/mac_proto.h" + +#include "UTIL/LOG/vcd_signal_dumper.h" + +#define DEBUG_PHY + +// Adjust location synchronization point to account for drift +// The adjustment is performed once per frame based on the +// last channel estimate of the receiver + +void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, + PHY_VARS_UE *ue, + module_id_t eNB_id, + uint8_t subframe, + unsigned char clear, + short coef) +{ + + static int max_pos_fil = 0; + static int count_max_pos_ok = 0; + static int first_time = 1; + int temp = 0, i, aa, max_val = 0, max_pos = 0; + int diff; + short Re,Im,ncoef; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN); + + ncoef = 32767 - coef; + +#ifdef DEBUG_PHY + LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (before) = %d\n",ue->proc.proc_rxtx[0].frame_rx%1024,subframe,ue->rx_offset); +#endif //DEBUG_PHY + + + // we only use channel estimates from tx antenna 0 here + for (i = 0; i < frame_parms->nb_prefix_samples; i++) { + temp = 0; + + for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { + Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)]; + Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)]; + temp += (Re*Re/2) + (Im*Im/2); + } + + if (temp > max_val) { + max_pos = i; + max_val = temp; + } + } + + // filter position to reduce jitter + if (clear == 1) + max_pos_fil = max_pos; + else + max_pos_fil = ((max_pos_fil * coef) + (max_pos * ncoef)) >> 15; + + // do not filter to have proactive timing adjustment + max_pos_fil = max_pos; + + if(subframe == 6) + { + diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); + + if ( abs(diff) < SYNCH_HYST ) + ue->rx_offset = 0; + else + ue->rx_offset = diff; + + if(abs(diff)<5) + count_max_pos_ok ++; + else + count_max_pos_ok = 0; + + if(count_max_pos_ok > 10 && first_time == 1) + { + first_time = 0; + ue->time_sync_cell = 1; + if (ue->mac_enabled==1) { + LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); + //mac_resynch(); + dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id); + ue->UE_mode[0] = PRACH; + } + else { + ue->UE_mode[0] = PUSCH; + } + } + + if ( ue->rx_offset < 0 ) + ue->rx_offset += FRAME_LENGTH_COMPLEX_SAMPLES; + + if ( ue->rx_offset >= FRAME_LENGTH_COMPLEX_SAMPLES ) + ue->rx_offset -= FRAME_LENGTH_COMPLEX_SAMPLES; + + + + #ifdef DEBUG_PHY + LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", + ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx, + subframe, + ue->current_thread_id[subframe], + diff, + ue->rx_offset, + clear, + max_pos, + max_pos_fil, + temp,max_val, + (frame_parms->nb_prefix_samples>>3)); + #endif //DEBUG_PHY + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); + } +} diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c index f697bd53085e7ce0a9a9822eed424058442af750..a406e246a6264066c299669fe3df5ddf7d1f7c97 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c @@ -20,8 +20,10 @@ */ #include <string.h> -#include "defs.h" -#include "PHY/defs.h" +#include "PHY/defs_UE.h" +#include "lte_estimation.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" + #include "filt16_32.h" //#define DEBUG_BF_CH diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c index 55f1a8e17c2ce255132dff9cbee7841727dd5aae..f7c4a3ead3156cb0b2e49ad7db1b837d6ecd5ec6 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c @@ -20,12 +20,13 @@ */ #include <string.h> -#include "defs.h" -#include "SCHED/defs.h" -#include "PHY/defs.h" +#include "PHY/defs_UE.h" #include "filt96_32.h" #include "T.h" //#define DEBUG_CH +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "SCHED_UE/sched_UE.h" int lte_dl_channel_estimation(PHY_VARS_UE *ue, module_id_t eNB_id, diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c index 75f87a6549166e7bfd2fce32247eb7f4c6aa8299..1a0611b9626ac960b6c228d798b72c4c8369b543 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c @@ -20,8 +20,9 @@ */ #include <string.h> -#include "defs.h" -#include "PHY/defs.h" +#include "PHY/defs_UE.h" +#include "lte_estimation.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" //#define DEBUG_CH int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue, diff --git a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c index 26869eb287c34f068bea39e35fd7ef808ba51204..a881773910c70a2719fc47cd178d786372e23e93 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" #include "PHY/sse_intrin.h" diff --git a/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c b/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c index cce1e06df4bce134e149558b4b64c8a4b3f95de5..ed82aeb09e36c602ee2b8d71d2db425176b19b60 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c @@ -25,7 +25,7 @@ date: 19.11.2009 */ -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" //#define DEBUG_PHY #if defined(__x86_64__) || defined(__i386__) diff --git a/openair1/PHY/LTE_ESTIMATION/defs.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h similarity index 99% rename from openair1/PHY/LTE_ESTIMATION/defs.h rename to openair1/PHY/LTE_ESTIMATION/lte_estimation.h index a7b5d14701874da4fb4894dca2382bfd7102708b..4512fc0d9be15bf9d52efaf1f68248725fc0d8ba 100644 --- a/openair1/PHY/LTE_ESTIMATION/defs.h +++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h @@ -22,7 +22,9 @@ #ifndef __LTE_ESTIMATION_DEFS__H__ #define __LTE_ESTIMATION_DEFS__H__ -#include "PHY/defs.h" + +#include "PHY/defs_UE.h" +#include "PHY/defs_eNB.h" /** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ * @{ */ diff --git a/openair1/PHY/LTE_ESTIMATION/extern.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation_extern.h similarity index 100% rename from openair1/PHY/LTE_ESTIMATION/extern.h rename to openair1/PHY/LTE_ESTIMATION/lte_estimation_extern.h diff --git a/openair1/PHY/LTE_ESTIMATION/vars.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation_vars.h similarity index 100% rename from openair1/PHY/LTE_ESTIMATION/vars.h rename to openair1/PHY/LTE_ESTIMATION/lte_estimation_vars.h diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index 2525f19b0df9f2c74575133a1e0d732e895e2132..587dbed6c506f4221797cd27b83e2d7723ae60d6 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -26,19 +26,15 @@ */ //#include <string.h> -#include "defs.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #include <math.h> -#ifdef OPENAIR2 -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" -#include "RRC/LITE/extern.h" -#include "PHY_INTERFACE/extern.h" -#endif -//#define DEBUG_PHY + +#include "LAYER2/MAC/mac.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface.h" + int* sync_corr_ue0 = NULL; int* sync_corr_ue1 = NULL; @@ -465,7 +461,7 @@ int lte_sync_time(int **rxdata, ///rx data in time domain *eNB_id = sync_source; - LOG_D(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val,dB_fixed(peak_val)/2); + LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val,dB_fixed(peak_val)/2); #ifdef DEBUG_PHY @@ -487,8 +483,6 @@ int lte_sync_time(int **rxdata, ///rx data in time domain } -//#define DEBUG_PHY - int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain LTE_DL_FRAME_PARMS *frame_parms, uint32_t length, @@ -578,3 +572,6 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain } + + + diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c index d428f8e6e6d9f927da6dbc7be5a0ffd77ebbf501..fd7b8d601ab9db9811c99a7df8b6b75cd0e2a9e0 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c @@ -36,8 +36,8 @@ */ //#include "defs.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #if defined(__x86_64__) || defined(__i386__) #include "pss6144.h" diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 1049232bd8e9c403be59373ad2cae69e82c6b32a..bf228021452834bb65f3dddf8bfa3a168b367c95 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -21,10 +21,8 @@ // this function fills the PHY_vars->PHY_measurement structure -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #include "log.h" #include "PHY/sse_intrin.h" @@ -207,10 +205,8 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ((ue->frame_parms.frame_type == TDD) && ((subframe == 1) || (subframe == 6))) ) { // FDD PSS/SSS, compute noise in DTX REs - - if (ue->frame_parms.Ncp==NORMAL) { + if (ue->frame_parms.Ncp == NORMAL) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { - if(ue->frame_parms.frame_type == FDD) { rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)]; @@ -266,7 +262,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); } else { - LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n"); + LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length == EXTENDED\n"); } } else if ((ue->frame_parms.frame_type == TDD) && @@ -456,385 +452,327 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, } -void lte_ue_measurements(PHY_VARS_UE *ue, - unsigned int subframe_offset, - unsigned char N0_symbol, - unsigned char abstraction_flag, - unsigned char rank_adaptation, - uint8_t subframe) +void conjch0_mult_ch1(int *ch0, + int *ch1, + int32_t *ch0conj_ch1, + unsigned short nb_rb, + unsigned char output_shift0) { + //This function is used to compute multiplications in Hhermitian * H matrix + unsigned short rb; + __m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + dl_ch0_128 = (__m128i *)ch0; + dl_ch1_128 = (__m128i *)ch1; - int aarx,aatx,eNB_id=0; //,gain_offset=0; - //int rx_power[NUMBER_OF_CONNECTED_eNB_MAX]; - int i; - unsigned int limit,subband; -#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch0_128,*dl_ch1_128; -#elif defined(__arm__) - int16x8_t *dl_ch0_128, *dl_ch1_128; -#endif - int *dl_ch0,*dl_ch1; - - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - int nb_subbands,subband_size,last_subband_size; - int N_RB_DL = frame_parms->N_RB_DL; + ch0conj_ch1_128 = (__m128i *)ch0conj_ch1; + for (rb=0; rb<3*nb_rb; rb++) { - int rank_tm3_tm4; + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); + mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch1_128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + ch0conj_ch1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; +#ifdef DEBUG_RANK_EST + printf("\n Computing conjugates \n"); + print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]); + print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]); + print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]); +#endif + dl_ch0_128+=1; + dl_ch1_128+=1; + ch0conj_ch1_128+=1; + } + _mm_empty(); + _m_empty(); +} - switch (N_RB_DL) { - case 6: - nb_subbands = 6; - subband_size = 12; - last_subband_size = 0; - break; +void construct_HhH_elements(int *ch0conj_ch0, //00_00 + int *ch1conj_ch1,//01_01 + int *ch2conj_ch2,//11_11 + int *ch3conj_ch3,//10_10 + int *ch0conj_ch1,//00_01 + int *ch1conj_ch0,//01_00 + int *ch2conj_ch3,//10_11 + int *ch3conj_ch2,//11_10 + int32_t *after_mf_00, + int32_t *after_mf_01, + int32_t *after_mf_10, + int32_t *after_mf_11, + unsigned short nb_rb) +{ + unsigned short rb; + __m128i *ch0conj_ch0_128, *ch1conj_ch1_128, *ch2conj_ch2_128, *ch3conj_ch3_128; + __m128i *ch0conj_ch1_128, *ch1conj_ch0_128, *ch2conj_ch3_128, *ch3conj_ch2_128; + __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128; - default: - case 25: - nb_subbands = 7; - subband_size = 4*12; - last_subband_size = 12; - break; + ch0conj_ch0_128 = (__m128i *)ch0conj_ch0; + ch1conj_ch1_128 = (__m128i *)ch1conj_ch1; + ch2conj_ch2_128 = (__m128i *)ch2conj_ch2; + ch3conj_ch3_128 = (__m128i *)ch3conj_ch3; + ch0conj_ch1_128 = (__m128i *)ch0conj_ch1; + ch1conj_ch0_128 = (__m128i *)ch1conj_ch0; + ch2conj_ch3_128 = (__m128i *)ch2conj_ch3; + ch3conj_ch2_128 = (__m128i *)ch3conj_ch2; + after_mf_00_128 = (__m128i *)after_mf_00; + after_mf_01_128 = (__m128i *)after_mf_01; + after_mf_10_128 = (__m128i *)after_mf_10; + after_mf_11_128 = (__m128i *)after_mf_11; - case 50: - nb_subbands = 9; - subband_size = 6*12; - last_subband_size = 2*12; - break; + for (rb=0; rb<3*nb_rb; rb++) { - case 100: - nb_subbands = 13; - subband_size = 8*12; - last_subband_size = 4*12; - break; - } + after_mf_00_128[0] =_mm_adds_epi16(ch0conj_ch0_128[0],ch3conj_ch3_128[0]);// _mm_adds_epi32(ch0conj_ch0_128[0], ch3conj_ch3_128[0]); //00_00 + 10_10 + after_mf_11_128[0] =_mm_adds_epi16(ch1conj_ch1_128[0], ch2conj_ch2_128[0]); //01_01 + 11_11 + after_mf_01_128[0] =_mm_adds_epi16(ch0conj_ch1_128[0], ch2conj_ch3_128[0]);//00_01 + 10_11 + after_mf_10_128[0] =_mm_adds_epi16(ch1conj_ch0_128[0], ch3conj_ch2_128[0]);//01_00 + 11_10 - // signal measurements - for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) { - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { - ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = - (signal_energy_nodc(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0], - (N_RB_DL*12))); - //- ue->measurements.n0_power[aarx]; +#ifdef DEBUG_RANK_EST + printf(" \n construct_HhH_elements \n"); + print_shorts("ch0conj_ch0_128:",(int16_t*)&ch0conj_ch0_128[0]); + print_shorts("ch1conj_ch1_128:",(int16_t*)&ch1conj_ch1_128[0]); + print_shorts("ch2conj_ch2_128:",(int16_t*)&ch2conj_ch2_128[0]); + print_shorts("ch3conj_ch3_128:",(int16_t*)&ch3conj_ch3_128[0]); + print_shorts("ch0conj_ch1_128:",(int16_t*)&ch0conj_ch1_128[0]); + print_shorts("ch1conj_ch0_128:",(int16_t*)&ch1conj_ch0_128[0]); + print_shorts("ch2conj_ch3_128:",(int16_t*)&ch2conj_ch3_128[0]); + print_shorts("ch3conj_ch2_128:",(int16_t*)&ch3conj_ch2_128[0]); + print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); + print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); + print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); + print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); +#endif - if (ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]<0) - ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = 0; //ue->measurements.n0_power[aarx]; + ch0conj_ch0_128+=1; + ch1conj_ch1_128+=1; + ch2conj_ch2_128+=1; + ch3conj_ch3_128+=1; + ch0conj_ch1_128+=1; + ch1conj_ch0_128+=1; + ch2conj_ch3_128+=1; + ch3conj_ch2_128+=1; - ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); + after_mf_00_128+=1; + after_mf_01_128+=1; + after_mf_10_128+=1; + after_mf_11_128+=1; + } + _mm_empty(); + _m_empty(); +} - if (aatx==0) - ue->measurements.rx_power[eNB_id][aarx] = ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; - else - ue->measurements.rx_power[eNB_id][aarx] += ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; - } //aatx - ue->measurements.rx_power_dB[eNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); +void squared_matrix_element(int32_t *Hh_h_00, + int32_t *Hh_h_00_sq, + unsigned short nb_rb) +{ + unsigned short rb; + __m128i *Hh_h_00_128,*Hh_h_00_sq_128; - if (aarx==0) - ue->measurements.rx_power_tot[eNB_id] = ue->measurements.rx_power[eNB_id][aarx]; - else - ue->measurements.rx_power_tot[eNB_id] += ue->measurements.rx_power[eNB_id][aarx]; - } //aarx + Hh_h_00_128 = (__m128i *)Hh_h_00; + Hh_h_00_sq_128 = (__m128i *)Hh_h_00_sq; - ue->measurements.rx_power_tot_dB[eNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[eNB_id]); + for (rb=0; rb<3*nb_rb; rb++) { - } //eNB_id + Hh_h_00_sq_128[0] = _mm_madd_epi16(Hh_h_00_128[0],Hh_h_00_128[0]); - eNB_id=0; - if (ue->transmission_mode[0]==4 || ue->transmission_mode[0]==3){ - if (rank_adaptation == 1) - rank_tm3_tm4 = rank_estimation_tm3_tm4(&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][4], - &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][4], - &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][4], - &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][4], - N_RB_DL); - else - rank_tm3_tm4=1; #ifdef DEBUG_RANK_EST - printf("rank tm3 or tm4 %d\n", rank_tm3_tm4); + printf("\n Computing squared_matrix_element \n"); + print_shorts("Hh_h_00_128:",(int16_t*)&Hh_h_00_128[0]); + print_ints("Hh_h_00_sq_128:",(int32_t*)&Hh_h_00_sq_128[0]); #endif + + Hh_h_00_sq_128+=1; + Hh_h_00_128+=1; } + _mm_empty(); + _m_empty(); +} - if (ue->transmission_mode[eNB_id]!=4 && ue->transmission_mode[eNB_id]!=3) - ue->measurements.rank[eNB_id] = 0; - else - ue->measurements.rank[eNB_id] = rank_tm3_tm4; - // printf ("tx mode %d\n", ue->transmission_mode[eNB_id]); - // printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]); - // filter to remove jitter - if (ue->init_averaging == 0) { - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) - ue->measurements.rx_power_avg[eNB_id] = (int) - (((k1*((long long int)(ue->measurements.rx_power_avg[eNB_id]))) + - (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10); - //LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg, - // ue->measurements.n0_power_tot); - ue->measurements.n0_power_avg = (int) - (((k1*((long long int) (ue->measurements.n0_power_avg))) + - (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); - } else { - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) - ue->measurements.rx_power_avg[eNB_id] = ue->measurements.rx_power_tot[eNB_id]; +void det_HhH(int32_t *after_mf_00, + int32_t *after_mf_01, + int32_t *after_mf_10, + int32_t *after_mf_11, + int32_t *det_fin, + unsigned short nb_rb) - ue->measurements.n0_power_avg = ue->measurements.n0_power_tot; - ue->init_averaging = 0; - } +{ + unsigned short rb; + __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128; + __m128i *det_fin_128, det_128; - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { - ue->measurements.rx_power_avg_dB[eNB_id] = dB_fixed( ue->measurements.rx_power_avg[eNB_id]); - ue->measurements.wideband_cqi_tot[eNB_id] = dB_fixed2(ue->measurements.rx_power_tot[eNB_id],ue->measurements.n0_power_tot); - ue->measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(ue->measurements.rx_power_avg[eNB_id],ue->measurements.n0_power_avg); - ue->measurements.rx_rssi_dBm[eNB_id] = ue->measurements.rx_power_avg_dB[eNB_id] - ue->rx_total_gain_dB; -#ifdef DEBUG_MEAS_UE - LOG_I(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", - eNB_id, - subframe, - ue->measurements.rx_rssi_dBm[eNB_id], - ue->measurements.rx_power_avg_dB[eNB_id], - ue->measurements.wideband_cqi_avg[eNB_id], - ue->measurements.rx_power_avg[eNB_id], - ue->measurements.n0_power_tot); -#endif - } + after_mf_00_128 = (__m128i *)after_mf_00; + after_mf_01_128 = (__m128i *)after_mf_01; + after_mf_10_128 = (__m128i *)after_mf_10; + after_mf_11_128 = (__m128i *)after_mf_11; - ue->measurements.n0_power_avg_dB = dB_fixed( ue->measurements.n0_power_avg); - - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { - if (frame_parms->nb_antenna_ports_eNB!=1) { - // cqi/pmi information + det_fin_128 = (__m128i *)det_fin; - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch0 = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; - dl_ch1 = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4]; + for (rb=0; rb<3*nb_rb; rb++) { - for (subband=0; subband<nb_subbands; subband++) { + ad_re_128 = _mm_madd_epi16(after_mf_00_128[0],after_mf_11_128[0]); + bc_re_128 = _mm_madd_epi16(after_mf_01_128[0],after_mf_01_128[0]); + det_128 = _mm_sub_epi32(ad_re_128, bc_re_128); + det_fin_128[0] = _mm_abs_epi32(det_128); - // cqi - if (aarx==0) - ue->measurements.subband_cqi_tot[eNB_id][subband]=0; +#ifdef DEBUG_RANK_EST + printf("\n Computing denominator \n"); + print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); + print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); + print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); + print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); + print_ints("ad_re_128:",(int32_t*)&ad_re_128); + print_ints("bc_re_128:",(int32_t*)&bc_re_128); + print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]); +#endif - if ((subband<(nb_subbands-1))||(N_RB_DL==6)) { - /*for (i=0;i<48;i++) - msg("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); - */ - ue->measurements.subband_cqi[eNB_id][aarx][subband] = - (signal_energy_nodc(dl_ch0,subband_size) + signal_energy_nodc(dl_ch1,subband_size)); + det_fin_128+=1; + after_mf_00_128+=1; + after_mf_01_128+=1; + after_mf_10_128+=1; + after_mf_11_128+=1; + } + _mm_empty(); + _m_empty(); +} - if ( ue->measurements.subband_cqi[eNB_id][aarx][subband] < 0) - ue->measurements.subband_cqi[eNB_id][aarx][subband]=0; +void numer(int32_t *Hh_h_00_sq, + int32_t *Hh_h_01_sq, + int32_t *Hh_h_10_sq, + int32_t *Hh_h_11_sq, + int32_t *num_fin, + unsigned short nb_rb) - /* - else - ue->measurements.subband_cqi[eNB_id][aarx][subband]-=ue->measurements.n0_power[aarx]; - */ +{ + unsigned short rb; + __m128i *h_h_00_sq_128, *h_h_01_sq_128, *h_h_10_sq_128, *h_h_11_sq_128; + __m128i *num_fin_128, sq_a_plus_sq_d_128, sq_b_plus_sq_c_128; - ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; - ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], - ue->measurements.n0_power[aarx]); - } else { // this is for the last subband which is smaller in size - // for (i=0;i<12;i++) - // printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); - ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,last_subband_size) + - signal_energy_nodc(dl_ch1,last_subband_size)); // - ue->measurements.n0_power[aarx]; - ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; - ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], - ue->measurements.n0_power[aarx]); - } + h_h_00_sq_128 = (__m128i *)Hh_h_00_sq; + h_h_01_sq_128 = (__m128i *)Hh_h_01_sq; + h_h_10_sq_128 = (__m128i *)Hh_h_10_sq; + h_h_11_sq_128 = (__m128i *)Hh_h_11_sq; - dl_ch1+=subband_size; - dl_ch0+=subband_size; - // msg("subband_cqi[%d][%d][%d] => %d (%d dB)\n",eNB_id,aarx,subband,ue->measurements.subband_cqi[eNB_id][aarx][subband],ue->measurements.subband_cqi_dB[eNB_id][aarx][subband]); - } + num_fin_128 = (__m128i *)num_fin; - } + for (rb=0; rb<3*nb_rb; rb++) { - for (subband=0; subband<nb_subbands; subband++) { - ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot); - // msg("subband_cqi_tot[%d][%d] => %d dB (n0 %d)\n",eNB_id,subband,ue->measurements.subband_cqi_tot_dB[eNB_id][subband],ue->measurements.n0_power_tot); - } + sq_a_plus_sq_d_128 = _mm_add_epi32(h_h_00_sq_128[0],h_h_11_sq_128[0]); + sq_b_plus_sq_c_128 = _mm_add_epi32(h_h_01_sq_128[0],h_h_10_sq_128[0]); + num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128); - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - //printf("aarx=%d", aarx); - // skip the first 4 RE due to interpolation filter length of 5 (not possible to skip 5 due to 128i alignment, must be multiple of 128bit) +#ifdef DEBUG_RANK_EST + printf("\n Computing numerator \n"); + print_ints("h_h_00_sq_128:",(int32_t*)&h_h_00_sq_128[0]); + print_ints("h_h_01_sq_128:",(int32_t*)&h_h_01_sq_128[0]); + print_ints("h_h_10_sq_128:",(int32_t*)&h_h_10_sq_128[0]); + print_ints("h_h_11_sq_128:",(int32_t*)&h_h_11_sq_128[0]); + print_shorts("sq_a_plus_sq_d_128:",(int16_t*)&sq_a_plus_sq_d_128); + print_shorts("sq_b_plus_sq_c_128:",(int16_t*)&sq_b_plus_sq_c_128); + print_shorts("num_fin_128:",(int16_t*)&num_fin_128[0]); +#endif -#if defined(__x86_64__) || defined(__i386__) - __m128i pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1 /* ,mmtmpPMI2,mmtmpPMI3 */ ; + num_fin_128+=1; + h_h_00_sq_128+=1; + h_h_01_sq_128+=1; + h_h_10_sq_128+=1; + h_h_11_sq_128+=1; + } + _mm_empty(); + _m_empty(); +} - dl_ch0_128 = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; - dl_ch1_128 = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4]; -#elif defined(__arm__) - int32x4_t pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1,mmtmpPMI0b,mmtmpPMI1b; +void dlsch_channel_level_TM34_meas(int *ch00, + int *ch01, + int *ch10, + int *ch11, + int *avg_0, + int *avg_1, + unsigned short nb_rb) +{ - dl_ch0_128 = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; - dl_ch1_128 = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4]; +#if defined(__x86_64__)||defined(__i386__) -#endif - for (subband=0; subband<nb_subbands; subband++) { + short rb; + unsigned char nre=12; + __m128i *ch00_128, *ch01_128, *ch10_128, *ch11_128; + __m128i avg_0_row0_128D, avg_1_row0_128D, avg_0_row1_128D, avg_1_row1_128D; + __m128i ch00_128_tmp, ch01_128_tmp, ch10_128_tmp, ch11_128_tmp; + avg_0[0] = 0; + avg_0[1] = 0; + avg_1[0] = 0; + avg_1[1] = 0; - // pmi -#if defined(__x86_64__) || defined(__i386__) + ch00_128 = (__m128i *)ch00; + ch01_128 = (__m128i *)ch01; + ch10_128 = (__m128i *)ch10; + ch11_128 = (__m128i *)ch11; - pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); - pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); -#elif defined(__arm__) + avg_0_row0_128D = _mm_setzero_si128(); + avg_1_row0_128D = _mm_setzero_si128(); + avg_0_row1_128D = _mm_setzero_si128(); + avg_1_row1_128D = _mm_setzero_si128(); - pmi128_re = vdupq_n_s32(0); - pmi128_im = vdupq_n_s32(0); -#endif - // limit is the number of groups of 4 REs in a subband (12 = 4 RBs, 3 = 1 RB) - // for 5 MHz channelization, there are 7 subbands, 6 of size 4 RBs and 1 of size 1 RB - if ((N_RB_DL==6) || (subband<(nb_subbands-1))) - limit = subband_size>>2; - else - limit = last_subband_size>>2; + for (rb=0; rb<3*nb_rb; rb++) { + ch00_128_tmp = _mm_load_si128(&ch00_128[0]); + ch01_128_tmp = _mm_load_si128(&ch01_128[0]); + ch10_128_tmp = _mm_load_si128(&ch10_128[0]); + ch11_128_tmp = _mm_load_si128(&ch11_128[0]); - for (i=0; i<limit; i++) { + avg_0_row0_128D = _mm_add_epi32(avg_0_row0_128D,_mm_madd_epi16(ch00_128_tmp,ch00_128_tmp)); + avg_1_row0_128D = _mm_add_epi32(avg_1_row0_128D,_mm_madd_epi16(ch01_128_tmp,ch01_128_tmp)); + avg_0_row1_128D = _mm_add_epi32(avg_0_row1_128D,_mm_madd_epi16(ch10_128_tmp,ch10_128_tmp)); + avg_1_row1_128D = _mm_add_epi32(avg_1_row1_128D,_mm_madd_epi16(ch11_128_tmp,ch11_128_tmp)); -#if defined(__x86_64__) || defined(__i386__) - mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0); - mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1); + ch00_128+=1; + ch01_128+=1; + ch10_128+=1; + ch11_128+=1; + } - // For each RE in subband perform ch0 * conj(ch1) - // multiply by conjugated channel - // print_ints("ch0",&dl_ch0_128[0]); - // print_ints("ch1",&dl_ch1_128[0]); + avg_0[0] = (((int*)&avg_0_row0_128D)[0])/(nb_rb*nre) + + (((int*)&avg_0_row0_128D)[1])/(nb_rb*nre) + + (((int*)&avg_0_row0_128D)[2])/(nb_rb*nre) + + (((int*)&avg_0_row0_128D)[3])/(nb_rb*nre); - mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); - // print_ints("re",&mmtmpPMI0); - mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1)); - // print_ints("_mm_shufflelo_epi16",&mmtmpPMI1); - mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1)); - // print_ints("_mm_shufflehi_epi16",&mmtmpPMI1); - mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate[0]); - // print_ints("_mm_sign_epi16",&mmtmpPMI1); - mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[0]); - // print_ints("mm_madd_epi16",&mmtmpPMI1); - // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit) - pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0); - // print_ints(" pmi128_re 0",&pmi128_re); - pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); - // print_ints(" pmi128_im 0 ",&pmi128_im); + avg_1[0] = (((int*)&avg_1_row0_128D)[0])/(nb_rb*nre) + + (((int*)&avg_1_row0_128D)[1])/(nb_rb*nre) + + (((int*)&avg_1_row0_128D)[2])/(nb_rb*nre) + + (((int*)&avg_1_row0_128D)[3])/(nb_rb*nre); - /* mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0); - mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1); + avg_0[1] = (((int*)&avg_0_row1_128D)[0])/(nb_rb*nre) + + (((int*)&avg_0_row1_128D)[1])/(nb_rb*nre) + + (((int*)&avg_0_row1_128D)[2])/(nb_rb*nre) + + (((int*)&avg_0_row1_128D)[3])/(nb_rb*nre); - mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]); - // print_ints("re",&mmtmpPMI0); - mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1)); - // print_ints("_mm_shufflelo_epi16",&mmtmpPMI1); - mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1)); - // print_ints("_mm_shufflehi_epi16",&mmtmpPMI1); - mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate); - // print_ints("_mm_sign_epi16",&mmtmpPMI1); - mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[1]); - // print_ints("mm_madd_epi16",&mmtmpPMI1); - // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit) - pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0); - // print_ints(" pmi128_re 1",&pmi128_re); - pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); - //print_ints(" pmi128_im 1 ",&pmi128_im);*/ + avg_1[1] = (((int*)&avg_1_row1_128D)[0])/(nb_rb*nre) + + (((int*)&avg_1_row1_128D)[1])/(nb_rb*nre) + + (((int*)&avg_1_row1_128D)[2])/(nb_rb*nre) + + (((int*)&avg_1_row1_128D)[3])/(nb_rb*nre); -#elif defined(__arm__) + avg_0[0] = avg_0[0] + avg_0[1]; + avg_1[0] = avg_1[0] + avg_1[1]; + avg_0[0] = min (avg_0[0], avg_1[0]); + avg_1[0] = avg_0[0]; - mmtmpPMI0 = vmull_s16(((int16x4_t*)dl_ch0_128)[0], ((int16x4_t*)dl_ch1_128)[0]); - mmtmpPMI1 = vmull_s16(((int16x4_t*)dl_ch0_128)[1], ((int16x4_t*)dl_ch1_128)[1]); - pmi128_re = vqaddq_s32(pmi128_re,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0),vget_high_s32(mmtmpPMI0)),vpadd_s32(vget_low_s32(mmtmpPMI1),vget_high_s32(mmtmpPMI1)))); + _mm_empty(); + _m_empty(); - mmtmpPMI0b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[0]); - mmtmpPMI1b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[1]); - pmi128_im = vqaddq_s32(pmi128_im,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0b),vget_high_s32(mmtmpPMI0b)),vpadd_s32(vget_low_s32(mmtmpPMI1b),vget_high_s32(mmtmpPMI1b)))); +#elif defined(__arm__) #endif - dl_ch0_128++; - dl_ch1_128++; - } - - ue->measurements.subband_pmi_re[eNB_id][subband][aarx] = (((int *)&pmi128_re)[0] + ((int *)&pmi128_re)[1] + ((int *)&pmi128_re)[2] + ((int *)&pmi128_re)[3])>>2; - ue->measurements.subband_pmi_im[eNB_id][subband][aarx] = (((int *)&pmi128_im)[0] + ((int *)&pmi128_im)[1] + ((int *)&pmi128_im)[2] + ((int *)&pmi128_im)[3])>>2; - ue->measurements.wideband_pmi_re[eNB_id][aarx] += ue->measurements.subband_pmi_re[eNB_id][subband][aarx]; - ue->measurements.wideband_pmi_im[eNB_id][aarx] += ue->measurements.subband_pmi_im[eNB_id][subband][aarx]; - } // subband loop - } // rx antenna loop - } // if frame_parms->mode1_flag == 0 - else { - // cqi information only for mode 1 - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch0 = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; - - for (subband=0; subband<7; subband++) { - - // cqi - if (aarx==0) - ue->measurements.subband_cqi_tot[eNB_id][subband]=0; - - if (subband<6) { - // for (i=0;i<48;i++) - // printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); - ue->measurements.subband_cqi[eNB_id][aarx][subband] = - (signal_energy_nodc(dl_ch0,48) ) - ue->measurements.n0_power[aarx]; - - ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; - ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], - ue->measurements.n0_power[aarx]); - } else { - // for (i=0;i<12;i++) - // printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); - ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,12) ) - ue->measurements.n0_power[aarx]; - ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; - ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], - ue->measurements.n0_power[aarx]); - } - - dl_ch1+=48; - // msg("subband_cqi[%d][%d][%d] => %d (%d dB)\n",eNB_id,aarx,subband,ue->measurements.subband_cqi[eNB_id][aarx][subband],ue->measurements.subband_cqi_dB[eNB_id][aarx][subband]); - } - } - - for (subband=0; subband<nb_subbands; subband++) { - ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot); - } - } - - //ue->measurements.rank[eNB_id] = 0; - - for (i=0; i<nb_subbands; i++) { - ue->measurements.selected_rx_antennas[eNB_id][i] = 0; - - if (frame_parms->nb_antennas_rx>1) { - if (ue->measurements.subband_cqi_dB[eNB_id][0][i] >= ue->measurements.subband_cqi_dB[eNB_id][1][i]) - ue->measurements.selected_rx_antennas[eNB_id][i] = 0; - else - ue->measurements.selected_rx_antennas[eNB_id][i] = 1; - } else - ue->measurements.selected_rx_antennas[eNB_id][i] = 0; - } - - // if(eNB_id==0) - // printf("in lte_ue_measurements: selected rx_antenna[eNB_id==0]:%u\n", ue->measurements.selected_rx_antennas[eNB_id][i]); - } // eNB_id loop - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - - -void lte_ue_measurements_emul(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id) -{ - - LOG_D(PHY,"EMUL UE lte_ue_measurements_emul subframe %d, eNB_id %d\n",subframe,eNB_id); -} - +} uint8_t rank_estimation_tm3_tm4 (int *dl_ch_estimates_00, // please respect the order of channel estimates int *dl_ch_estimates_01, @@ -1060,328 +998,390 @@ uint8_t rank_estimation_tm3_tm4 (int *dl_ch_estimates_00, // please respect the return(rank); } -void conjch0_mult_ch1(int *ch0, - int *ch1, - int32_t *ch0conj_ch1, - unsigned short nb_rb, - unsigned char output_shift0) -{ - //This function is used to compute multiplications in Hhermitian * H matrix - unsigned short rb; - __m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; - dl_ch0_128 = (__m128i *)ch0; - dl_ch1_128 = (__m128i *)ch1; - ch0conj_ch1_128 = (__m128i *)ch0conj_ch1; - for (rb=0; rb<3*nb_rb; rb++) { - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); - mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch1_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - ch0conj_ch1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); -#ifdef DEBUG_RANK_EST - printf("\n Computing conjugates \n"); - print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]); - print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]); - print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]); +void lte_ue_measurements(PHY_VARS_UE *ue, + unsigned int subframe_offset, + unsigned char N0_symbol, + unsigned char abstraction_flag, + unsigned char rank_adaptation, + uint8_t subframe) +{ + + + int aarx,aatx,eNB_id=0; //,gain_offset=0; + //int rx_power[NUMBER_OF_CONNECTED_eNB_MAX]; + int i; + unsigned int limit,subband; +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch0_128,*dl_ch1_128; +#elif defined(__arm__) + int16x8_t *dl_ch0_128, *dl_ch1_128; #endif + int *dl_ch0,*dl_ch1; - dl_ch0_128+=1; - dl_ch1_128+=1; - ch0conj_ch1_128+=1; - } - _mm_empty(); - _m_empty(); -} + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + int nb_subbands,subband_size,last_subband_size; + int N_RB_DL = frame_parms->N_RB_DL; -void construct_HhH_elements(int *ch0conj_ch0, //00_00 - int *ch1conj_ch1,//01_01 - int *ch2conj_ch2,//11_11 - int *ch3conj_ch3,//10_10 - int *ch0conj_ch1,//00_01 - int *ch1conj_ch0,//01_00 - int *ch2conj_ch3,//10_11 - int *ch3conj_ch2,//11_10 - int32_t *after_mf_00, - int32_t *after_mf_01, - int32_t *after_mf_10, - int32_t *after_mf_11, - unsigned short nb_rb) -{ - unsigned short rb; - __m128i *ch0conj_ch0_128, *ch1conj_ch1_128, *ch2conj_ch2_128, *ch3conj_ch3_128; - __m128i *ch0conj_ch1_128, *ch1conj_ch0_128, *ch2conj_ch3_128, *ch3conj_ch2_128; - __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128; - ch0conj_ch0_128 = (__m128i *)ch0conj_ch0; - ch1conj_ch1_128 = (__m128i *)ch1conj_ch1; - ch2conj_ch2_128 = (__m128i *)ch2conj_ch2; - ch3conj_ch3_128 = (__m128i *)ch3conj_ch3; - ch0conj_ch1_128 = (__m128i *)ch0conj_ch1; - ch1conj_ch0_128 = (__m128i *)ch1conj_ch0; - ch2conj_ch3_128 = (__m128i *)ch2conj_ch3; - ch3conj_ch2_128 = (__m128i *)ch3conj_ch2; - after_mf_00_128 = (__m128i *)after_mf_00; - after_mf_01_128 = (__m128i *)after_mf_01; - after_mf_10_128 = (__m128i *)after_mf_10; - after_mf_11_128 = (__m128i *)after_mf_11; + int rank_tm3_tm4; - for (rb=0; rb<3*nb_rb; rb++) { - after_mf_00_128[0] =_mm_adds_epi16(ch0conj_ch0_128[0],ch3conj_ch3_128[0]);// _mm_adds_epi32(ch0conj_ch0_128[0], ch3conj_ch3_128[0]); //00_00 + 10_10 - after_mf_11_128[0] =_mm_adds_epi16(ch1conj_ch1_128[0], ch2conj_ch2_128[0]); //01_01 + 11_11 - after_mf_01_128[0] =_mm_adds_epi16(ch0conj_ch1_128[0], ch2conj_ch3_128[0]);//00_01 + 10_11 - after_mf_10_128[0] =_mm_adds_epi16(ch1conj_ch0_128[0], ch3conj_ch2_128[0]);//01_00 + 11_10 + ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; -#ifdef DEBUG_RANK_EST - printf(" \n construct_HhH_elements \n"); - print_shorts("ch0conj_ch0_128:",(int16_t*)&ch0conj_ch0_128[0]); - print_shorts("ch1conj_ch1_128:",(int16_t*)&ch1conj_ch1_128[0]); - print_shorts("ch2conj_ch2_128:",(int16_t*)&ch2conj_ch2_128[0]); - print_shorts("ch3conj_ch3_128:",(int16_t*)&ch3conj_ch3_128[0]); - print_shorts("ch0conj_ch1_128:",(int16_t*)&ch0conj_ch1_128[0]); - print_shorts("ch1conj_ch0_128:",(int16_t*)&ch1conj_ch0_128[0]); - print_shorts("ch2conj_ch3_128:",(int16_t*)&ch2conj_ch3_128[0]); - print_shorts("ch3conj_ch2_128:",(int16_t*)&ch3conj_ch2_128[0]); - print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); - print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); - print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); - print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); -#endif - ch0conj_ch0_128+=1; - ch1conj_ch1_128+=1; - ch2conj_ch2_128+=1; - ch3conj_ch3_128+=1; - ch0conj_ch1_128+=1; - ch1conj_ch0_128+=1; - ch2conj_ch3_128+=1; - ch3conj_ch2_128+=1; + switch (N_RB_DL) { + case 6: + nb_subbands = 6; + subband_size = 12; + last_subband_size = 0; + break; - after_mf_00_128+=1; - after_mf_01_128+=1; - after_mf_10_128+=1; - after_mf_11_128+=1; + default: + case 25: + nb_subbands = 7; + subband_size = 4*12; + last_subband_size = 12; + break; + + case 50: + nb_subbands = 9; + subband_size = 6*12; + last_subband_size = 2*12; + break; + + case 100: + nb_subbands = 13; + subband_size = 8*12; + last_subband_size = 4*12; + break; } - _mm_empty(); - _m_empty(); -} + // signal measurements + for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) { + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { + ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = + (signal_energy_nodc(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0], + (N_RB_DL*12))); + //- ue->measurements.n0_power[aarx]; -void squared_matrix_element(int32_t *Hh_h_00, - int32_t *Hh_h_00_sq, - unsigned short nb_rb) -{ - unsigned short rb; - __m128i *Hh_h_00_128,*Hh_h_00_sq_128; + if (ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]<0) + ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = 0; //ue->measurements.n0_power[aarx]; - Hh_h_00_128 = (__m128i *)Hh_h_00; - Hh_h_00_sq_128 = (__m128i *)Hh_h_00_sq; + ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); - for (rb=0; rb<3*nb_rb; rb++) { + if (aatx==0) + ue->measurements.rx_power[eNB_id][aarx] = ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; + else + ue->measurements.rx_power[eNB_id][aarx] += ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; + } //aatx - Hh_h_00_sq_128[0] = _mm_madd_epi16(Hh_h_00_128[0],Hh_h_00_128[0]); + ue->measurements.rx_power_dB[eNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); + + if (aarx==0) + ue->measurements.rx_power_tot[eNB_id] = ue->measurements.rx_power[eNB_id][aarx]; + else + ue->measurements.rx_power_tot[eNB_id] += ue->measurements.rx_power[eNB_id][aarx]; + } //aarx + + ue->measurements.rx_power_tot_dB[eNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[eNB_id]); + } //eNB_id + + eNB_id=0; + if (ue->transmission_mode[0]==4 || ue->transmission_mode[0]==3){ + if (rank_adaptation == 1) + rank_tm3_tm4 = rank_estimation_tm3_tm4(&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][4], + &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][4], + &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][4], + &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][4], + N_RB_DL); + else + rank_tm3_tm4=1; #ifdef DEBUG_RANK_EST - printf("\n Computing squared_matrix_element \n"); - print_shorts("Hh_h_00_128:",(int16_t*)&Hh_h_00_128[0]); - print_ints("Hh_h_00_sq_128:",(int32_t*)&Hh_h_00_sq_128[0]); + printf("rank tm3 or tm4 %d\n", rank_tm3_tm4); #endif + } - Hh_h_00_sq_128+=1; - Hh_h_00_128+=1; + if (ue->transmission_mode[eNB_id]!=4 && ue->transmission_mode[eNB_id]!=3) + ue->measurements.rank[eNB_id] = 0; + else + ue->measurements.rank[eNB_id] = rank_tm3_tm4; + // printf ("tx mode %d\n", ue->transmission_mode[eNB_id]); + // printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]); + + // filter to remove jitter + if (ue->init_averaging == 0) { + for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) + ue->measurements.rx_power_avg[eNB_id] = (int) + (((k1*((long long int)(ue->measurements.rx_power_avg[eNB_id]))) + + (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10); + + //LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg, + // ue->measurements.n0_power_tot); + ue->measurements.n0_power_avg = (int) + (((k1*((long long int) (ue->measurements.n0_power_avg))) + + (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); + } else { + for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) + ue->measurements.rx_power_avg[eNB_id] = ue->measurements.rx_power_tot[eNB_id]; + + ue->measurements.n0_power_avg = ue->measurements.n0_power_tot; + ue->init_averaging = 0; } - _mm_empty(); - _m_empty(); -} + for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { + ue->measurements.rx_power_avg_dB[eNB_id] = dB_fixed( ue->measurements.rx_power_avg[eNB_id]); + ue->measurements.wideband_cqi_tot[eNB_id] = dB_fixed2(ue->measurements.rx_power_tot[eNB_id],ue->measurements.n0_power_tot); + ue->measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(ue->measurements.rx_power_avg[eNB_id],ue->measurements.n0_power_avg); + ue->measurements.rx_rssi_dBm[eNB_id] = ue->measurements.rx_power_avg_dB[eNB_id] - ue->rx_total_gain_dB; +#ifdef DEBUG_MEAS_UE + LOG_I(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", + eNB_id, + subframe, + ue->measurements.rx_rssi_dBm[eNB_id], + ue->measurements.rx_power_avg_dB[eNB_id], + ue->measurements.wideband_cqi_avg[eNB_id], + ue->measurements.rx_power_avg[eNB_id], + ue->measurements.n0_power_tot); +#endif + } + ue->measurements.n0_power_avg_dB = dB_fixed( ue->measurements.n0_power_avg); -void det_HhH(int32_t *after_mf_00, - int32_t *after_mf_01, - int32_t *after_mf_10, - int32_t *after_mf_11, - int32_t *det_fin, - unsigned short nb_rb) + for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { + if (frame_parms->nb_antenna_ports_eNB!=1) { + // cqi/pmi information -{ - unsigned short rb; - __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128; - __m128i *det_fin_128, det_128; + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + dl_ch0 = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; + dl_ch1 = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4]; - after_mf_00_128 = (__m128i *)after_mf_00; - after_mf_01_128 = (__m128i *)after_mf_01; - after_mf_10_128 = (__m128i *)after_mf_10; - after_mf_11_128 = (__m128i *)after_mf_11; + for (subband=0; subband<nb_subbands; subband++) { - det_fin_128 = (__m128i *)det_fin; + // cqi + if (aarx==0) + ue->measurements.subband_cqi_tot[eNB_id][subband]=0; - for (rb=0; rb<3*nb_rb; rb++) { + if ((subband<(nb_subbands-1))||(N_RB_DL==6)) { + /*for (i=0;i<48;i++) + msg("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); + */ + ue->measurements.subband_cqi[eNB_id][aarx][subband] = + (signal_energy_nodc(dl_ch0,subband_size) + signal_energy_nodc(dl_ch1,subband_size)); - ad_re_128 = _mm_madd_epi16(after_mf_00_128[0],after_mf_11_128[0]); - bc_re_128 = _mm_madd_epi16(after_mf_01_128[0],after_mf_01_128[0]); - det_128 = _mm_sub_epi32(ad_re_128, bc_re_128); - det_fin_128[0] = _mm_abs_epi32(det_128); + if ( ue->measurements.subband_cqi[eNB_id][aarx][subband] < 0) + ue->measurements.subband_cqi[eNB_id][aarx][subband]=0; -#ifdef DEBUG_RANK_EST - printf("\n Computing denominator \n"); - print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); - print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); - print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); - print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); - print_ints("ad_re_128:",(int32_t*)&ad_re_128); - print_ints("bc_re_128:",(int32_t*)&bc_re_128); - print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]); -#endif + /* + else + ue->measurements.subband_cqi[eNB_id][aarx][subband]-=ue->measurements.n0_power[aarx]; + */ + + ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; + ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], + ue->measurements.n0_power[aarx]); + } else { // this is for the last subband which is smaller in size + // for (i=0;i<12;i++) + // printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); + ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,last_subband_size) + + signal_energy_nodc(dl_ch1,last_subband_size)); // - ue->measurements.n0_power[aarx]; + ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; + ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], + ue->measurements.n0_power[aarx]); + } + + dl_ch1+=subband_size; + dl_ch0+=subband_size; + // msg("subband_cqi[%d][%d][%d] => %d (%d dB)\n",eNB_id,aarx,subband,ue->measurements.subband_cqi[eNB_id][aarx][subband],ue->measurements.subband_cqi_dB[eNB_id][aarx][subband]); + } + + } - det_fin_128+=1; - after_mf_00_128+=1; - after_mf_01_128+=1; - after_mf_10_128+=1; - after_mf_11_128+=1; - } - _mm_empty(); - _m_empty(); -} + for (subband=0; subband<nb_subbands; subband++) { + ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot); + // msg("subband_cqi_tot[%d][%d] => %d dB (n0 %d)\n",eNB_id,subband,ue->measurements.subband_cqi_tot_dB[eNB_id][subband],ue->measurements.n0_power_tot); + } -void numer(int32_t *Hh_h_00_sq, - int32_t *Hh_h_01_sq, - int32_t *Hh_h_10_sq, - int32_t *Hh_h_11_sq, - int32_t *num_fin, - unsigned short nb_rb) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + //printf("aarx=%d", aarx); + // skip the first 4 RE due to interpolation filter length of 5 (not possible to skip 5 due to 128i alignment, must be multiple of 128bit) -{ - unsigned short rb; - __m128i *h_h_00_sq_128, *h_h_01_sq_128, *h_h_10_sq_128, *h_h_11_sq_128; - __m128i *num_fin_128, sq_a_plus_sq_d_128, sq_b_plus_sq_c_128; +#if defined(__x86_64__) || defined(__i386__) + __m128i pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1 /* ,mmtmpPMI2,mmtmpPMI3 */ ; - h_h_00_sq_128 = (__m128i *)Hh_h_00_sq; - h_h_01_sq_128 = (__m128i *)Hh_h_01_sq; - h_h_10_sq_128 = (__m128i *)Hh_h_10_sq; - h_h_11_sq_128 = (__m128i *)Hh_h_11_sq; + dl_ch0_128 = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; + dl_ch1_128 = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4]; +#elif defined(__arm__) + int32x4_t pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1,mmtmpPMI0b,mmtmpPMI1b; - num_fin_128 = (__m128i *)num_fin; + dl_ch0_128 = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; + dl_ch1_128 = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4]; - for (rb=0; rb<3*nb_rb; rb++) { +#endif + for (subband=0; subband<nb_subbands; subband++) { - sq_a_plus_sq_d_128 = _mm_add_epi32(h_h_00_sq_128[0],h_h_11_sq_128[0]); - sq_b_plus_sq_c_128 = _mm_add_epi32(h_h_01_sq_128[0],h_h_10_sq_128[0]); - num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128); -#ifdef DEBUG_RANK_EST - printf("\n Computing numerator \n"); - print_ints("h_h_00_sq_128:",(int32_t*)&h_h_00_sq_128[0]); - print_ints("h_h_01_sq_128:",(int32_t*)&h_h_01_sq_128[0]); - print_ints("h_h_10_sq_128:",(int32_t*)&h_h_10_sq_128[0]); - print_ints("h_h_11_sq_128:",(int32_t*)&h_h_11_sq_128[0]); - print_shorts("sq_a_plus_sq_d_128:",(int16_t*)&sq_a_plus_sq_d_128); - print_shorts("sq_b_plus_sq_c_128:",(int16_t*)&sq_b_plus_sq_c_128); - print_shorts("num_fin_128:",(int16_t*)&num_fin_128[0]); + // pmi +#if defined(__x86_64__) || defined(__i386__) + + pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); + pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); +#elif defined(__arm__) + + pmi128_re = vdupq_n_s32(0); + pmi128_im = vdupq_n_s32(0); #endif + // limit is the number of groups of 4 REs in a subband (12 = 4 RBs, 3 = 1 RB) + // for 5 MHz channelization, there are 7 subbands, 6 of size 4 RBs and 1 of size 1 RB + if ((N_RB_DL==6) || (subband<(nb_subbands-1))) + limit = subband_size>>2; + else + limit = last_subband_size>>2; - num_fin_128+=1; - h_h_00_sq_128+=1; - h_h_01_sq_128+=1; - h_h_10_sq_128+=1; - h_h_11_sq_128+=1; - } - _mm_empty(); - _m_empty(); -} + for (i=0; i<limit; i++) { +#if defined(__x86_64__) || defined(__i386__) + mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0); + mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1); + // For each RE in subband perform ch0 * conj(ch1) + // multiply by conjugated channel + // print_ints("ch0",&dl_ch0_128[0]); + // print_ints("ch1",&dl_ch1_128[0]); + mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); + // print_ints("re",&mmtmpPMI0); + mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1)); + // print_ints("_mm_shufflelo_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1)); + // print_ints("_mm_shufflehi_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate[0]); + // print_ints("_mm_sign_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[0]); + // print_ints("mm_madd_epi16",&mmtmpPMI1); + // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit) + pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0); + // print_ints(" pmi128_re 0",&pmi128_re); + pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); + // print_ints(" pmi128_im 0 ",&pmi128_im); + /* mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0); + mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1); -void dlsch_channel_level_TM34_meas(int *ch00, - int *ch01, - int *ch10, - int *ch11, - int *avg_0, - int *avg_1, - unsigned short nb_rb) -{ + mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]); + // print_ints("re",&mmtmpPMI0); + mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1)); + // print_ints("_mm_shufflelo_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1)); + // print_ints("_mm_shufflehi_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate); + // print_ints("_mm_sign_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[1]); + // print_ints("mm_madd_epi16",&mmtmpPMI1); + // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit) + pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0); + // print_ints(" pmi128_re 1",&pmi128_re); + pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); + //print_ints(" pmi128_im 1 ",&pmi128_im);*/ -#if defined(__x86_64__)||defined(__i386__) +#elif defined(__arm__) - short rb; - unsigned char nre=12; - __m128i *ch00_128, *ch01_128, *ch10_128, *ch11_128; - __m128i avg_0_row0_128D, avg_1_row0_128D, avg_0_row1_128D, avg_1_row1_128D; - __m128i ch00_128_tmp, ch01_128_tmp, ch10_128_tmp, ch11_128_tmp; + mmtmpPMI0 = vmull_s16(((int16x4_t*)dl_ch0_128)[0], ((int16x4_t*)dl_ch1_128)[0]); + mmtmpPMI1 = vmull_s16(((int16x4_t*)dl_ch0_128)[1], ((int16x4_t*)dl_ch1_128)[1]); + pmi128_re = vqaddq_s32(pmi128_re,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0),vget_high_s32(mmtmpPMI0)),vpadd_s32(vget_low_s32(mmtmpPMI1),vget_high_s32(mmtmpPMI1)))); - avg_0[0] = 0; - avg_0[1] = 0; - avg_1[0] = 0; - avg_1[1] = 0; + mmtmpPMI0b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[0]); + mmtmpPMI1b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[1]); + pmi128_im = vqaddq_s32(pmi128_im,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0b),vget_high_s32(mmtmpPMI0b)),vpadd_s32(vget_low_s32(mmtmpPMI1b),vget_high_s32(mmtmpPMI1b)))); - ch00_128 = (__m128i *)ch00; - ch01_128 = (__m128i *)ch01; - ch10_128 = (__m128i *)ch10; - ch11_128 = (__m128i *)ch11; +#endif + dl_ch0_128++; + dl_ch1_128++; + } - avg_0_row0_128D = _mm_setzero_si128(); - avg_1_row0_128D = _mm_setzero_si128(); - avg_0_row1_128D = _mm_setzero_si128(); - avg_1_row1_128D = _mm_setzero_si128(); + ue->measurements.subband_pmi_re[eNB_id][subband][aarx] = (((int *)&pmi128_re)[0] + ((int *)&pmi128_re)[1] + ((int *)&pmi128_re)[2] + ((int *)&pmi128_re)[3])>>2; + ue->measurements.subband_pmi_im[eNB_id][subband][aarx] = (((int *)&pmi128_im)[0] + ((int *)&pmi128_im)[1] + ((int *)&pmi128_im)[2] + ((int *)&pmi128_im)[3])>>2; + ue->measurements.wideband_pmi_re[eNB_id][aarx] += ue->measurements.subband_pmi_re[eNB_id][subband][aarx]; + ue->measurements.wideband_pmi_im[eNB_id][aarx] += ue->measurements.subband_pmi_im[eNB_id][subband][aarx]; + } // subband loop + } // rx antenna loop + } // if frame_parms->mode1_flag == 0 + else { + // cqi information only for mode 1 + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + dl_ch0 = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4]; - for (rb=0; rb<3*nb_rb; rb++) { - ch00_128_tmp = _mm_load_si128(&ch00_128[0]); - ch01_128_tmp = _mm_load_si128(&ch01_128[0]); - ch10_128_tmp = _mm_load_si128(&ch10_128[0]); - ch11_128_tmp = _mm_load_si128(&ch11_128[0]); + for (subband=0; subband<7; subband++) { - avg_0_row0_128D = _mm_add_epi32(avg_0_row0_128D,_mm_madd_epi16(ch00_128_tmp,ch00_128_tmp)); - avg_1_row0_128D = _mm_add_epi32(avg_1_row0_128D,_mm_madd_epi16(ch01_128_tmp,ch01_128_tmp)); - avg_0_row1_128D = _mm_add_epi32(avg_0_row1_128D,_mm_madd_epi16(ch10_128_tmp,ch10_128_tmp)); - avg_1_row1_128D = _mm_add_epi32(avg_1_row1_128D,_mm_madd_epi16(ch11_128_tmp,ch11_128_tmp)); + // cqi + if (aarx==0) + ue->measurements.subband_cqi_tot[eNB_id][subband]=0; - ch00_128+=1; - ch01_128+=1; - ch10_128+=1; - ch11_128+=1; - } + if (subband<6) { + // for (i=0;i<48;i++) + // printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); + ue->measurements.subband_cqi[eNB_id][aarx][subband] = + (signal_energy_nodc(dl_ch0,48) ) - ue->measurements.n0_power[aarx]; - avg_0[0] = (((int*)&avg_0_row0_128D)[0])/(nb_rb*nre) + - (((int*)&avg_0_row0_128D)[1])/(nb_rb*nre) + - (((int*)&avg_0_row0_128D)[2])/(nb_rb*nre) + - (((int*)&avg_0_row0_128D)[3])/(nb_rb*nre); + ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; + ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], + ue->measurements.n0_power[aarx]); + } else { + // for (i=0;i<12;i++) + // printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]); + ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,12) ) - ue->measurements.n0_power[aarx]; + ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband]; + ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband], + ue->measurements.n0_power[aarx]); + } - avg_1[0] = (((int*)&avg_1_row0_128D)[0])/(nb_rb*nre) + - (((int*)&avg_1_row0_128D)[1])/(nb_rb*nre) + - (((int*)&avg_1_row0_128D)[2])/(nb_rb*nre) + - (((int*)&avg_1_row0_128D)[3])/(nb_rb*nre); + dl_ch1+=48; + // msg("subband_cqi[%d][%d][%d] => %d (%d dB)\n",eNB_id,aarx,subband,ue->measurements.subband_cqi[eNB_id][aarx][subband],ue->measurements.subband_cqi_dB[eNB_id][aarx][subband]); + } + } - avg_0[1] = (((int*)&avg_0_row1_128D)[0])/(nb_rb*nre) + - (((int*)&avg_0_row1_128D)[1])/(nb_rb*nre) + - (((int*)&avg_0_row1_128D)[2])/(nb_rb*nre) + - (((int*)&avg_0_row1_128D)[3])/(nb_rb*nre); + for (subband=0; subband<nb_subbands; subband++) { + ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot); + } + } - avg_1[1] = (((int*)&avg_1_row1_128D)[0])/(nb_rb*nre) + - (((int*)&avg_1_row1_128D)[1])/(nb_rb*nre) + - (((int*)&avg_1_row1_128D)[2])/(nb_rb*nre) + - (((int*)&avg_1_row1_128D)[3])/(nb_rb*nre); + //ue->measurements.rank[eNB_id] = 0; - avg_0[0] = avg_0[0] + avg_0[1]; - avg_1[0] = avg_1[0] + avg_1[1]; - avg_0[0] = min (avg_0[0], avg_1[0]); - avg_1[0] = avg_0[0]; + for (i=0; i<nb_subbands; i++) { + ue->measurements.selected_rx_antennas[eNB_id][i] = 0; + + if (frame_parms->nb_antennas_rx>1) { + if (ue->measurements.subband_cqi_dB[eNB_id][0][i] >= ue->measurements.subband_cqi_dB[eNB_id][1][i]) + ue->measurements.selected_rx_antennas[eNB_id][i] = 0; + else + ue->measurements.selected_rx_antennas[eNB_id][i] = 1; + } else + ue->measurements.selected_rx_antennas[eNB_id][i] = 0; + } + // if(eNB_id==0) + // printf("in lte_ue_measurements: selected rx_antenna[eNB_id==0]:%u\n", ue->measurements.selected_rx_antennas[eNB_id][i]); + } // eNB_id loop + +#if defined(__x86_64__) || defined(__i386__) _mm_empty(); _m_empty(); +#endif +} -#elif defined(__arm__) -#endif +void lte_ue_measurements_emul(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id) +{ + + LOG_D(PHY,"EMUL UE lte_ue_measurements_emul subframe %d, eNB_id %d\n",subframe,eNB_id); } + + + diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 44eebb0df4717e7862ceb67d3fb841d0667ab73b..2d3acfce9b1f678b31e4a7fd5be285e808fbdafd 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -19,13 +19,14 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" #include "PHY/sse_intrin.h" //#define DEBUG_CH #include "UTIL/LOG/log.h" - +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include "T.h" +#include "lte_estimation.h" // round(exp(sqrt(-1)*(pi/2)*[0:1:N-1]/N)*pow2(15)) static int16_t ru_90[2*128] = {32767, 0,32766, 402,32758, 804,32746, 1206,32729, 1608,32706, 2009,32679, 2411,32647, 2811,32610, 3212,32568, 3612,32522, 4011,32470, 4410,32413, 4808,32352, 5205,32286, 5602,32214, 5998,32138, 6393,32058, 6787,31972, 7180,31881, 7571,31786, 7962,31686, 8351,31581, 8740,31471, 9127,31357, 9512,31238, 9896,31114, 10279,30986, 10660,30853, 11039,30715, 11417,30572, 11793,30425, 12167,30274, 12540,30118, 12910,29957, 13279,29792, 13646,29622, 14010,29448, 14373,29269, 14733,29086, 15091,28899, 15447,28707, 15800,28511, 16151,28311, 16500,28106, 16846,27897, 17190,27684, 17531,27467, 17869,27246, 18205,27020, 18538,26791, 18868,26557, 19195,26320, 19520,26078, 19841,25833, 20160,25583, 20475,25330, 20788,25073, 21097,24812, 21403,24548, 21706,24279, 22006,24008, 22302,23732, 22595,23453, 22884,23170, 23170,22884, 23453,22595, 23732,22302, 24008,22006, 24279,21706, 24548,21403, 24812,21097, 25073,20788, 25330,20475, 25583,20160, 25833,19841, 26078,19520, 26320,19195, 26557,18868, 26791,18538, 27020,18205, 27246,17869, 27467,17531, 27684,17190, 27897,16846, 28106,16500, 28311,16151, 28511,15800, 28707,15447, 28899,15091, 29086,14733, 29269,14373, 29448,14010, 29622,13646, 29792,13279, 29957,12910, 30118,12540, 30274,12167, 30425,11793, 30572,11417, 30715,11039, 30853,10660, 30986,10279, 31114,9896, 31238,9512, 31357,9127, 31471,8740, 31581,8351, 31686,7962, 31786,7571, 31881,7180, 31972,6787, 32058,6393, 32138,5998, 32214,5602, 32286,5205, 32352,4808, 32413,4410, 32470,4011, 32522,3612, 32568,3212, 32610,2811, 32647,2411, 32679,2009, 32706,1608, 32729,1206, 32746,804, 32758,402, 32766}; @@ -100,7 +101,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); return(-1); } - // LOG_I(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); + LOG_D(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); #ifdef DEBUG_CH if (Ns==0) @@ -291,7 +292,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); #ifdef DEBUG_CH - if (aa==0) { + if (aa==1) { if (Ns == 0) { write_output("rxdataF_ext.m","rxF_ext",&rxdataF_ext[aa][symbol_offset],512*2,2,1); write_output("tmpin_ifft.m","drs_in",temp_in_ifft_0,512,1,1); diff --git a/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..8f0b7b8c4ce7fb48a2dcabc360d9756ddae98d7e --- /dev/null +++ b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h @@ -0,0 +1,60 @@ +/******************************************************************************* + + *******************************************************************************/ +/*! \file PHY/LTE_REFSIG/defs_NB_IoT.c +* \function called by lte_dl_cell_spec_NB_IoT.c , TS 36-211, V13.4.0 2017-02 +* \author M. KANJ +* \date 2017 +* \version 0.0 +* \company bcom +* \email: matthieu.kanj@b-com.com +* \note +* \warning +*/ + +/* Definitions for NB_IoT Reference signals */ + +#ifndef __LTE_REFSIG_DEFS_NB_IOT__H__ +#define __LTE_REFSIG_DEFS_NB_IOT__H__ + +#include "PHY/defs_L1_NB_IoT.h" + +/** @ingroup _PHY_REF_SIG + * @{ +*/ +/*!\brief This function generates the LTE Gold sequence (36-211, Sec 7.2), specifically for DL reference signals. +@param frame_parms LTE DL Frame parameters +@param lte_gold_table pointer to table where sequences are stored +@param Nid_cell Cell Id for NB_IoT (to compute sequences for local and adjacent cells) */ + +void lte_gold_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, + uint32_t lte_gold_table_NB_IoT[20][2][14], + uint16_t Nid_cell); + +/*! \brief This function generates the Narrowband reference signal (NRS) sequence (36-211, Sec 6.10.1.1) +@param phy_vars_eNB Pointer to eNB variables +@param output Output vector for OFDM symbol (Frequency Domain) +@param amp Q15 amplitude +@param Ns Slot number (0..19) +@param l symbol (0,1) - Note 1 means 3! +@param p antenna index +@param RB_IoT_ID the ID of the RB dedicated for NB_IoT +*/ +int lte_dl_cell_spec_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + int32_t *output, + short amp, + unsigned char Ns, + unsigned char l, + unsigned char p, + unsigned short RB_IoT_ID); + + +unsigned int lte_gold_generic_NB_IoT(unsigned int *x1, + unsigned int *x2, + unsigned char reset); + +void generate_ul_ref_sigs_rx_NB_IoT(void); + +void free_ul_ref_sigs_NB_IoT(void); + +#endif diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c b/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c index 5bf69578d194269b656266e0245d38fbd2a39b56..56d8aaf1dfce1826cedefec58e856a64620aabd7 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c @@ -22,8 +22,9 @@ #include <stdio.h> #include <stdlib.h> -#include "defs.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/impl_defs_top.h" //extern unsigned int lte_gold_table[3][20][2][14]; //#define DEBUG_DL_CELL_SPEC diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c index 35e5fe6affa62885f33bde299fe1d63a7375d475..54f52ef40b9d3990abbf044d48aed421cdb31f78 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c @@ -24,8 +24,10 @@ #include <stdio.h> #include <stdlib.h> -#include "defs.h" -#include "PHY/defs.h" +#include "lte_refsig.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/impl_defs_top.h" //extern unsigned int lte_gold_table[10][3][42]; //#define DEBUG_DL_MBSFN diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c index a7db8fd5aa321848cb1a4b903b5fb2b1cc780842..fc03299f2b60bda1ff969d5307c478b51f9fa686 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c @@ -33,9 +33,11 @@ #include <stdio.h> #include <stdlib.h> -#include "defs.h" -#include "PHY/defs.h" +#include "lte_refsig.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" #include "log.h" +#include "PHY/impl_defs_top.h" //extern unsigned int lte_gold_table[3][20][2][14]; //#define DEBUG_DL_CELL_SPEC diff --git a/openair1/PHY/LTE_REFSIG/lte_gold.c b/openair1/PHY/LTE_REFSIG/lte_gold.c index c3a3f42456293460213b3bea994b8757b0be37a0..78fae8b8f3304a69a1d2c0d67cac522e08209135 100644 --- a/openair1/PHY/LTE_REFSIG/lte_gold.c +++ b/openair1/PHY/LTE_REFSIG/lte_gold.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -#include "defs.h" +#include "lte_refsig.h" /* c(n) = x1(n+Nc) + x2(n+Nc) mod 2 diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c index 66d7fa8fb253c3cb3ed3d6220e475f0d526ab7b3..14def309b7bdb11043ef66712b0828d5546898d6 100644 --- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c @@ -42,7 +42,7 @@ //unsigned int lte_gold_table[10][3][42]; // need 165 bytes for sequence //slot index x pilot within slot x sequence*/ -#include "defs.h" +#include "lte_refsig.h" void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_table[10][3][42],uint16_t Nid_mbsfn) { diff --git a/openair1/PHY/LTE_REFSIG/defs.h b/openair1/PHY/LTE_REFSIG/lte_refsig.h similarity index 99% rename from openair1/PHY/LTE_REFSIG/defs.h rename to openair1/PHY/LTE_REFSIG/lte_refsig.h index 838406b4444222c2ca341f69ad85213fcd27018c..27788e5e1a92c2266b23cad399af48f2506a2580 100644 --- a/openair1/PHY/LTE_REFSIG/defs.h +++ b/openair1/PHY/LTE_REFSIG/lte_refsig.h @@ -23,7 +23,8 @@ /* Author R. Knopp / EURECOM / OpenAirInterface.org */ #ifndef __LTE_REFSIG_DEFS__H__ #define __LTE_REFSIG_DEFS__H__ -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" /** @ingroup _PHY_REF_SIG * @{ diff --git a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c index cddb642b2b41818f8d814dfd3e2eeb0b4e260bd3..01b27205c21b619bc273b8ef43309073de21a7e1 100644 --- a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c +++ b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c @@ -24,7 +24,8 @@ #include <stdlib.h> #include <math.h> #endif -#include "defs.h" +#include "lte_refsig.h" +#include "PHY/defs_eNB.h" uint16_t dftsizes[33] = {12,24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,864,900,960,972,1080,1152,1200}; @@ -185,14 +186,18 @@ void free_ul_ref_sigs(void) unsigned int u,v,Msc_RS; - for (Msc_RS=2; Msc_RS<33; Msc_RS++) { + for (Msc_RS=0; Msc_RS<33; Msc_RS++) { for (u=0; u<30; u++) { for (v=0; v<2; v++) { - if (ul_ref_sigs[u][v][Msc_RS]) + if (ul_ref_sigs[u][v][Msc_RS]) { free16(ul_ref_sigs[u][v][Msc_RS],2*sizeof(int16_t)*dftsizes[Msc_RS]); + ul_ref_sigs[u][v][Msc_RS] = NULL; + } - if (ul_ref_sigs_rx[u][v][Msc_RS]) + if (ul_ref_sigs_rx[u][v][Msc_RS]) { free16(ul_ref_sigs_rx[u][v][Msc_RS],4*sizeof(int16_t)*dftsizes[Msc_RS]); + ul_ref_sigs_rx[u][v][Msc_RS] = NULL; + } } } } diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 39e61c601d16bcbcf38c8b611d76c562ee58fd6a..d8a13bbbfdbc0abfc760aa4853aba0eeba25362d 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -32,16 +32,19 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" +#include "SIMULATION/TOOLS/sim.h" // for taus #include "PHY/sse_intrin.h" - -#include "assertions.h" +#include "transport_proto.h" +#include "transport_common_proto.h" +#include "assertions.h" #include "T.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" +#include "PHY/LTE_TRANSPORT/transport_extern.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" //#define DEBUG_DCI_ENCODING 1 //#define DEBUG_DCI_DECODING 1 @@ -52,109 +55,6 @@ //extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; //extern uint16_t pcfich_reg[4]; -uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi) -{ - - uint16_t i; - uint16_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; - uint16_t mprime; - uint16_t *pcfich_reg = frame_parms->pcfich_reg; - - if ((lprime>0) && (frame_parms->Ncp==0) ) - return(0); - - // printf("check_phich_reg : mi %d\n",mi); - - // compute REG based on symbol - if ((lprime == 0)|| - ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) - mprime = kprime/6; - else - mprime = kprime>>2; - - // check if PCFICH uses mprime - if ((lprime==0) && - ((mprime == pcfich_reg[0]) || - (mprime == pcfich_reg[1]) || - (mprime == pcfich_reg[2]) || - (mprime == pcfich_reg[3]))) { -#ifdef DEBUG_DCI_ENCODING - printf("[PHY] REG %d allocated to PCFICH\n",mprime); -#endif - return(1); - } - - // handle Special subframe case for TDD !!! - - // printf("Checking phich_reg %d\n",mprime); - if (mi > 0) { - if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) - Ngroup_PHICH++; - - if (frame_parms->Ncp == 1) { - Ngroup_PHICH<<=1; - } - - - - for (i=0; i<Ngroup_PHICH; i++) { - if ((mprime == frame_parms->phich_reg[i][0]) || - (mprime == frame_parms->phich_reg[i][1]) || - (mprime == frame_parms->phich_reg[i][2])) { -#ifdef DEBUG_DCI_ENCODING - printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime); -#endif - return(1); - } - } - } - - return(0); -} - -uint16_t extract_crc(uint8_t *dci,uint8_t dci_len) -{ - - uint16_t crc16; - // uint8_t i; - - /* - uint8_t crc; - crc = ((uint16_t *)dci)[DCI_LENGTH>>4]; - printf("crc1: %x, shift %d (DCI_LENGTH %d)\n",crc,DCI_LENGTH&0xf,DCI_LENGTH); - crc = (crc>>(DCI_LENGTH&0xf)); - // clear crc bits - ((uint16_t *)dci)[DCI_LENGTH>>4] &= (0xffff>>(16-(DCI_LENGTH&0xf))); - printf("crc2: %x, dci0 %x\n",crc,((int16_t *)dci)[DCI_LENGTH>>4]); - crc |= (((uint16_t *)dci)[1+(DCI_LENGTH>>4)])<<(16-(DCI_LENGTH&0xf)); - // clear crc bits - (((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0; - printf("extract_crc: crc %x\n",crc); - */ -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY,"dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)], - dci_len&0x7); -#endif - - if ((dci_len&0x7) > 0) { - ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]<<(dci_len&0x7) | dci[2+(dci_len>>3)]>>(8-(dci_len&0x7)); - ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]<<(dci_len&0x7) | dci[1+(dci_len>>3)]>>(8-(dci_len&0x7)); - } else { - ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]; - ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]; - } - -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY,"dci_crc =>%x\n",crc16); -#endif - - // dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf)); - // dci[(dci_len>>3)+1] = 0; - // dci[(dci_len>>3)+2] = 0; - return((uint16_t)crc16); - -} - static uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96]; @@ -177,7 +77,7 @@ void dci_encoding(uint8_t *a, // encode dci #ifdef DEBUG_DCI_ENCODING - printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti); + printf("Doing DCI encoding for %d bits, e %p, rnti %x, E %d\n",A,e,rnti,E); #endif memset((void *)d,LTE_NULL,96); @@ -215,11 +115,11 @@ uint8_t *generate_dci0(uint8_t *dci, uint16_t coded_bits; uint8_t dci_flip[8]; - AssertFatal((aggregation_level==1) || - (aggregation_level==2) || - (aggregation_level==4) || - (aggregation_level==8) -#ifdef Rel14 // Added for EPDCCH/MPDCCH + AssertFatal((aggregation_level==1) || + (aggregation_level==2) || + (aggregation_level==4) || + (aggregation_level==8) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Added for EPDCCH/MPDCCH || (aggregation_level==16) || (aggregation_level==24) || @@ -227,22 +127,27 @@ uint8_t *generate_dci0(uint8_t *dci, #endif , "generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level); - + coded_bits = 72 * aggregation_level; - /* + #ifdef DEBUG_DCI_ENCODING - for (i=0;i<1+((DCI_LENGTH+16)/8);i++) + for (int i=0;i<1+((DCI_LENGTH+16)/8);i++) printf("i %d : %x\n",i,dci[i]); #endif - */ + if (DCI_LENGTH<=32) { dci_flip[0] = dci[3]; dci_flip[1] = dci[2]; dci_flip[2] = dci[1]; dci_flip[3] = dci[0]; +#ifdef DEBUG_DCI_ENCODING + printf("DCI => %x,%x,%x,%x\n", + dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]); + +#endif } else { dci_flip[0] = dci[7]; dci_flip[1] = dci[6]; @@ -266,15 +171,10 @@ uint8_t *generate_dci0(uint8_t *dci, uint32_t Y; -#define CCEBITS 72 -#define CCEPERSYMBOL 33 // This is for 1200 RE -#define CCEPERSYMBOL0 22 // This is for 1200 RE -#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS) -#define Msymb (DCI_BITS_MAX/2) -//#define Mquad (Msymb/4) -static uint32_t bitrev_cc_dci[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30}; -static int32_t wtemp[2][Msymb]; + + + void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) { @@ -287,6 +187,8 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w #ifdef RM_DEBUG int32_t nulled=0; #endif + uint32_t Msymb=(DCI_BITS_MAX/2); + int32_t wtemp[2][Msymb]; // printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch); if ((Mquad&0x1f) > 0) @@ -341,1853 +243,34 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w } } -void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parms,uint8_t num_pdcch_symbols,uint8_t mi) -{ - - uint32_t i, lprime; - uint16_t kprime,kprime_mod12,mprime,symbol_offset,tti_offset,tti_offset0; - int16_t re_offset,re_offset0; - - // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5 - - int Msymb2; - - switch (frame_parms->N_RB_DL) { - case 100: - Msymb2 = Msymb; - break; - - case 75: - Msymb2 = 3*Msymb/4; - break; - - case 50: - Msymb2 = Msymb>>1; - break; - - case 25: - Msymb2 = Msymb>>2; - break; - - case 15: - Msymb2 = Msymb*15/100; - break; - - case 6: - Msymb2 = Msymb*6/100; - break; - - default: - Msymb2 = Msymb>>2; - break; - } - - mprime=0; - - - re_offset = 0; - re_offset0 = 0; // counter for symbol with pilots (extracted outside!) - - for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) { - for (lprime=0; lprime<num_pdcch_symbols; lprime++) { - - symbol_offset = (uint32_t)frame_parms->N_RB_DL*12*lprime; - - tti_offset = symbol_offset + re_offset; - tti_offset0 = symbol_offset + re_offset0; - - // if REG is allocated to PHICH, skip it - if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) { - // printf("dci_demapping : skipping REG %d (RE %d)\n",(lprime==0)?kprime/6 : kprime>>2,kprime); - if ((lprime == 0)&&((kprime%6)==0)) - re_offset0+=4; - } else { // not allocated to PHICH/PCFICH - // printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2); - if (lprime == 0) { - // first symbol, or second symbol+4 TX antennas skip pilots - kprime_mod12 = kprime%12; - - if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) { - // kprime represents REG - - for (i=0; i<4; i++) { - wbar[mprime] = llr[tti_offset0+i]; -#ifdef DEBUG_DCI_DECODING -// LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime])); -#endif - mprime++; - re_offset0++; - } - } - } else if ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)) { - // LATER!!!! - } else { // no pilots in this symbol - kprime_mod12 = kprime%12; - - if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) { - // kprime represents REG - for (i=0; i<4; i++) { - wbar[mprime] = llr[tti_offset+i]; -#ifdef DEBUG_DCI_DECODING -// LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime])); -#endif - mprime++; - } - } // is representative - } // no pilots case - } // not allocated to PHICH/PCFICH - - // Stop when all REGs are copied in - if (mprime>=Msymb2) - break; - } //lprime loop - - re_offset++; - - } // kprime loop -} - -static uint16_t wtemp_rx[Msymb]; -void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t *wbar,uint8_t number_pdcch_symbols,uint8_t mi) -{ - - uint16_t *wptr,*zptr,*wptr2; - - uint16_t Mquad=get_nquad(number_pdcch_symbols,frame_parms,mi); - uint32_t RCC = (Mquad>>5), ND; - uint32_t row,col,Kpi,index; - int32_t i,k; - - - // printf("Mquad %d, RCC %d\n",Mquad,RCC); - - AssertFatal(z!=NULL,"dci.c: pdcch_deinterleaving: FATAL z is Null\n"); - - // undo permutation - for (i=0; i<Mquad; i++) { - wptr = &wtemp_rx[((i+frame_parms->Nid_cell)%Mquad)<<2]; - wptr2 = &wbar[i<<2]; - - wptr[0] = wptr2[0]; - wptr[1] = wptr2[1]; - wptr[2] = wptr2[2]; - wptr[3] = wptr2[3]; - /* - printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad, - ((char*)wptr2)[0], - ((char*)wptr2)[1], - ((char*)wptr2)[2], - ((char*)wptr2)[3], - ((char*)wptr2)[4], - ((char*)wptr2)[5], - ((char*)wptr2)[6], - ((char*)wptr2)[7]); - */ - - } - - if ((Mquad&0x1f) > 0) - RCC++; - - Kpi = (RCC<<5); - ND = Kpi - Mquad; - - k=0; - - for (col=0; col<32; col++) { - index = bitrev_cc_dci[col]; - - for (row=0; row<RCC; row++) { - // printf("row %d, index %d, Nd %d\n",row,index,ND); - if (index>=ND) { - - - - wptr = &wtemp_rx[k<<2]; - zptr = &z[(index-ND)<<2]; - - zptr[0] = wptr[0]; - zptr[1] = wptr[1]; - zptr[2] = wptr[2]; - zptr[3] = wptr[3]; - - /* - printf("deinterleaving ; k %d, index-Nd %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND), - ((int8_t *)wptr)[0], - ((int8_t *)wptr)[1], - ((int8_t *)wptr)[2], - ((int8_t *)wptr)[3], - ((int8_t *)wptr)[4], - ((int8_t *)wptr)[5], - ((int8_t *)wptr)[6], - ((int8_t *)wptr)[7]); - */ - k++; - } - - index+=32; - - } - } - - for (i=0; i<Mquad; i++) { - zptr = &z[i<<2]; - /* - printf("deinterleaving ; quad %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i, - ((int8_t *)zptr)[0], - ((int8_t *)zptr)[1], - ((int8_t *)zptr)[2], - ((int8_t *)zptr)[3], - ((int8_t *)zptr)[4], - ((int8_t *)zptr)[5], - ((int8_t *)zptr)[6], - ((int8_t *)zptr)[7]); - */ - } - -} - - -int32_t pdcch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - int32_t **rxdataF_comp_i, - int32_t **rho_i, - int16_t *pdcch_llr16, - int16_t *pdcch_llr8in, - uint8_t symbol) -{ - - int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *llr128; - int32_t i; - char *pdcch_llr8; - int16_t *pdcch_llr; - pdcch_llr8 = (char *)&pdcch_llr8in[symbol*frame_parms->N_RB_DL*12]; - pdcch_llr = &pdcch_llr16[symbol*frame_parms->N_RB_DL*12]; - - // printf("dlsch_qpsk_qpsk: symbol %d\n",symbol); - - llr128 = (int16_t*)pdcch_llr; - - if (!llr128) { - printf("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol); - return -1; - } - - qpsk_qpsk(rxF, - rxF_i, - llr128, - rho, - frame_parms->N_RB_DL*12); - - //prepare for Viterbi which accepts 8 bit, but prefers 4 bit, soft input. - for (i=0; i<(frame_parms->N_RB_DL*24); i++) { - if (*pdcch_llr>7) - *pdcch_llr8=7; - else if (*pdcch_llr<-8) - *pdcch_llr8=-8; - else - *pdcch_llr8 = (char)(*pdcch_llr); - - pdcch_llr++; - pdcch_llr8++; - } - - return(0); -} - - -int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - char *pdcch_llr, - uint8_t symbol) -{ - - int16_t *rxF= (int16_t*) &rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int32_t i; - char *pdcch_llr8; - - pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12]; - - if (!pdcch_llr8) { - printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); - return(-1); - } - - // printf("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr); - - for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) { - - if (*rxF>31) - *pdcch_llr8=31; - else if (*rxF<-32) - *pdcch_llr8=-32; - else - *pdcch_llr8 = (char)(*rxF); - - // printf("%d %d => %d\n",i,*rxF,*pdcch_llr8); - rxF++; - pdcch_llr8++; - } - - return(0); - -} - -//__m128i avg128P; - -//compute average channel_level on each (TX,RX) antenna pair -void pdcch_channel_level(int32_t **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - int32_t *avg, - uint8_t nb_rb) -{ - - int16_t rb; - uint8_t aatx,aarx; -#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch128; - __m128i avg128P; -#elif defined(__arm__) - int16x8_t *dl_ch128; - int32x4_t *avg128P; -#endif - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - //clear average level -#if defined(__x86_64__) || defined(__i386__) - avg128P = _mm_setzero_si128(); - dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][0]; -#elif defined(__arm__) - -#endif - for (rb=0; rb<nb_rb; rb++) { - -#if defined(__x86_64__) || defined(__i386__) - avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); - avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); - avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); -#elif defined(__arm__) - -#endif - dl_ch128+=3; - /* - if (rb==0) { - print_shorts("dl_ch128",&dl_ch128[0]); - print_shorts("dl_ch128",&dl_ch128[1]); - print_shorts("dl_ch128",&dl_ch128[2]); - } - */ - } - - DevAssert( nb_rb ); - avg[(aatx<<1)+aarx] = (((int32_t*)&avg128P)[0] + - ((int32_t*)&avg128P)[1] + - ((int32_t*)&avg128P)[2] + - ((int32_t*)&avg128P)[3])/(nb_rb*12); - - // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); - } - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif - -} - -#if defined(__x86_64) || defined(__i386__) -__m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3; -#elif defined(__arm__) - -#endif -void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t symbol, - int32_t **dl_ch_estimates_ext, - int32_t **dl_ch_estimates_ext_i, - int32_t **dl_ch_rho_ext, - uint8_t output_shift) -{ - - uint16_t rb; -#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128; -#elif defined(__arm__) - -#endif - uint8_t aarx; - - // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol); - - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - -#if defined(__x86_64__) || defined(__i386__) - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - -#elif defined(__arm__) - -#endif - - for (rb=0; rb<frame_parms->N_RB_DL; rb++) { - // multiply by conjugated channel -#if defined(__x86_64__) || defined(__i386__) - mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]); - // print_ints("re",&mmtmpPD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpPD1); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - // print_ints("re(shift)",&mmtmpPD0); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - // print_ints("im(shift)",&mmtmpPD1); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - // print_ints("c0",&mmtmpPD2); - // print_ints("c1",&mmtmpPD3); - dl_ch_rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); - - //print_shorts("rx:",dl_ch128_2); - //print_shorts("ch:",dl_ch128); - //print_shorts("pack:",rho128); - - // multiply by conjugated channel - mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[1]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - - dl_ch_rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - //print_shorts("rx:",dl_ch128_2+1); - //print_shorts("ch:",dl_ch128+1); - //print_shorts("pack:",rho128+1); - // multiply by conjugated channel - mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[2]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - dl_ch_rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); - //print_shorts("rx:",dl_ch128_2+2); - //print_shorts("ch:",dl_ch128+2); - //print_shorts("pack:",rho128+2); - - dl_ch128+=3; - dl_ch128i+=3; - dl_ch_rho128+=3; - - -#elif defined(__arm__) - -#endif - } - } -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif - -} - - -void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - int32_t **rxdataF_comp_i, - int32_t **rho, - int32_t **rho_i, - uint8_t symbol) +void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + uint8_t *e, + uint32_t length) { - - uint8_t aatx; - -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; -#elif defined(__arm__) - int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; -#endif - int32_t i; - - if (frame_parms->nb_antennas_rx>1) { - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { - //if (frame_parms->mode1_flag && (aatx>0)) break; - -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; -#elif defined(__arm__) - rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; -#endif - // MRC on each re of rb on MF output - for (i=0; i<frame_parms->N_RB_DL*3; i++) { -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); -#elif defined(__arm__) - rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); -#endif - } - } - -#if defined(__x86_64__) || defined(__i386__) - rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12]; - rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; -#elif defined(__arm__) - rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12]; - rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12]; -#endif - for (i=0; i<frame_parms->N_RB_DL*3; i++) { -#if defined(__x86_64__) || defined(__i386__) - rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); -#elif defined(__arm__) - rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]); -#endif - } - -#if defined(__x86_64__) || defined(__i386__) - rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; - rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12]; -#elif defined(__arm__) - rho128_i0 = (int16x8_t*) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; - rho128_i1 = (int16x8_t*) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i0 = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i1 = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12]; - -#endif - // MRC on each re of rb on MF and rho - for (i=0; i<frame_parms->N_RB_DL*3; i++) { -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1)); - rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); -#elif defined(__arm__) - rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]); - rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]); - -#endif - } - } - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - - -void pdcch_extract_rbs_single(int32_t **rxdataF, - int32_t **dl_ch_estimates, - int32_t **rxdataF_ext, - int32_t **dl_ch_estimates_ext, - uint8_t symbol, - uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms) -{ - - - uint16_t rb,nb_rb=0; - uint8_t i,j,aarx; - int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; - - - int nushiftmod3 = frame_parms->nushift%3; - uint8_t symbol_mod; - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod); -#endif - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - if (high_speed_flag == 1) - dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; - else - dl_ch0 = &dl_ch_estimates[aarx][5]; - - dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; - - rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; - - rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; - - if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs - for (rb=0; rb<frame_parms->N_RB_DL; rb++) { - - // For second half of RBs skip DC carrier - if (rb==(frame_parms->N_RB_DL>>1)) { - rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; - - //dl_ch0++; - } - - if (symbol_mod>0) { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); - - for (i=0; i<12; i++) { - - rxF_ext[i]=rxF[i]; - - } - - nb_rb++; - dl_ch0_ext+=12; - rxF_ext+=12; - - dl_ch0+=12; - rxF+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i!=nushiftmod3) && - (i!=(nushiftmod3+3)) && - (i!=(nushiftmod3+6)) && - (i!=(nushiftmod3+9))) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); - } - } - - nb_rb++; - dl_ch0_ext+=8; - rxF_ext+=8; - - dl_ch0+=12; - rxF+=12; - } - } - } else { // Odd number of RBs - for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) { - - if (symbol_mod>0) { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); - - for (i=0; i<12; i++) - rxF_ext[i]=rxF[i]; - - nb_rb++; - dl_ch0_ext+=12; - rxF_ext+=12; - - dl_ch0+=12; - rxF+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i!=nushiftmod3) && - (i!=(nushiftmod3+3)) && - (i!=(nushiftmod3+6)) && - (i!=(nushiftmod3+9))) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); - } - } - - nb_rb++; - dl_ch0_ext+=8; - rxF_ext+=8; - - dl_ch0+=12; - rxF+=12; - } - } - - // Do middle RB (around DC) - // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); - - if (symbol_mod==0) { - j=0; - - for (i=0; i<6; i++) { - if ((i!=nushiftmod3) && - (i!=(nushiftmod3+3))) { - dl_ch0_ext[j]=dl_ch0[i]; - rxF_ext[j++]=rxF[i]; - // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); - } - } - - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; - - for (; i<12; i++) { - if ((i!=(nushiftmod3+6)) && - (i!=(nushiftmod3+9))) { - dl_ch0_ext[j]=dl_ch0[i]; - rxF_ext[j++]=rxF[(1+i-6)]; - // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); - } - } - - - nb_rb++; - dl_ch0_ext+=8; - rxF_ext+=8; - dl_ch0+=12; - rxF+=7; - rb++; - } else { - for (i=0; i<6; i++) { - dl_ch0_ext[i]=dl_ch0[i]; - rxF_ext[i]=rxF[i]; - } - - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; - - for (; i<12; i++) { - dl_ch0_ext[i]=dl_ch0[i]; - rxF_ext[i]=rxF[(1+i-6)]; - } - - - nb_rb++; - dl_ch0_ext+=12; - rxF_ext+=12; - dl_ch0+=12; - rxF+=7; - rb++; - } - - for (; rb<frame_parms->N_RB_DL; rb++) { - if (symbol_mod > 0) { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); - - for (i=0; i<12; i++) - rxF_ext[i]=rxF[i]; - - nb_rb++; - dl_ch0_ext+=12; - rxF_ext+=12; - - dl_ch0+=12; - rxF+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i!=(nushiftmod3)) && - (i!=(nushiftmod3+3)) && - (i!=(nushiftmod3+6)) && - (i!=(nushiftmod3+9))) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - } - } - - nb_rb++; - dl_ch0_ext+=8; - rxF_ext+=8; - - dl_ch0+=12; - rxF+=12; - } - } - } - } -} - -void pdcch_extract_rbs_dual(int32_t **rxdataF, - int32_t **dl_ch_estimates, - int32_t **rxdataF_ext, - int32_t **dl_ch_estimates_ext, - uint8_t symbol, - uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms) -{ - - - uint16_t rb,nb_rb=0; - uint8_t i,aarx,j; - int32_t *dl_ch0,*dl_ch0_ext,*dl_ch1,*dl_ch1_ext,*rxF,*rxF_ext; - uint8_t symbol_mod; - int nushiftmod3 = frame_parms->nushift%3; - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY, "extract_rbs_dual: symbol_mod %d\n",symbol_mod); -#endif - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - if (high_speed_flag==1) { - dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; - dl_ch1 = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; - } else { - dl_ch0 = &dl_ch_estimates[aarx][5]; - dl_ch1 = &dl_ch_estimates[2+aarx][5]; - } - - dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; - dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)]; - - // printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12)); - rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; - - rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; - - if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs - for (rb=0; rb<frame_parms->N_RB_DL; rb++) { - - // For second half of RBs skip DC carrier - if (rb==(frame_parms->N_RB_DL>>1)) { - rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; - // dl_ch0++; - //dl_ch1++; - } - - if (symbol_mod>0) { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); - - /* - printf("rb %d\n",rb); - for (i=0;i<12;i++) - printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]); - printf("\n"); - */ - for (i=0; i<12; i++) { - rxF_ext[i]=rxF[i]; - // printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2, - // ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]); - } - - nb_rb++; - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i!=nushiftmod3) && - (i!=nushiftmod3+3) && - (i!=nushiftmod3+6) && - (i!=nushiftmod3+9)) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j] =dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - } - } - - nb_rb++; - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - } - - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; - } - - else { // Odd number of RBs - for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) { - - // printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]); - - if (symbol_mod>0) { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); - - for (i=0; i<12; i++) - rxF_ext[i]=rxF[i]; - - nb_rb++; - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; - - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i!=nushiftmod3) && - (i!=nushiftmod3+3) && - (i!=nushiftmod3+6) && - (i!=nushiftmod3+9)) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); - } - } - - nb_rb++; - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - - - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; - } - } - - // Do middle RB (around DC) - - if (symbol_mod > 0) { - for (i=0; i<6; i++) { - dl_ch0_ext[i]=dl_ch0[i]; - dl_ch1_ext[i]=dl_ch1[i]; - rxF_ext[i]=rxF[i]; - } - - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; - - for (; i<12; i++) { - dl_ch0_ext[i]=dl_ch0[i]; - dl_ch1_ext[i]=dl_ch1[i]; - rxF_ext[i]=rxF[(1+i)]; - } - - nb_rb++; - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - - dl_ch0+=12; - dl_ch1+=12; - rxF+=7; - rb++; - } else { - j=0; - - for (i=0; i<6; i++) { - if ((i!=nushiftmod3) && - (i!=nushiftmod3+3)) { - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j]=dl_ch1[i]; - rxF_ext[j++]=rxF[i]; - // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); - } - } - - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; - - for (; i<12; i++) { - if ((i!=nushiftmod3+6) && - (i!=nushiftmod3+9)) { - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j]=dl_ch1[i]; - rxF_ext[j++]=rxF[(1+i-6)]; - // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); - } - } - - - nb_rb++; - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - dl_ch0+=12; - dl_ch1+=12; - rxF+=7; - rb++; - } - - for (; rb<frame_parms->N_RB_DL; rb++) { - - if (symbol_mod>0) { - // printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]); - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); - - for (i=0; i<12; i++) - rxF_ext[i]=rxF[i]; - - nb_rb++; - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i!=nushiftmod3) && - (i!=nushiftmod3+3) && - (i!=nushiftmod3+6) && - (i!=nushiftmod3+9)) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - } - } - - nb_rb++; - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; - } - } - } - } -} - - -void pdcch_channel_compensation(int32_t **rxdataF_ext, - int32_t **dl_ch_estimates_ext, - int32_t **rxdataF_comp, - int32_t **rho, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t symbol, - uint8_t output_shift) -{ - - uint16_t rb; -#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; - __m128i *dl_ch128_2, *rho128; -#elif defined(__arm__) - -#endif - uint8_t aatx,aarx,pilots=0; - - - - -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol); -#endif - - if (symbol==0) - pilots=1; - - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { - //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - -#if defined(__x86_64__) || defined(__i386__) - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - -#elif defined(__arm__) - -#endif - - for (rb=0; rb<frame_parms->N_RB_DL; rb++) { - -#if defined(__x86_64__) || defined(__i386__) - // multiply by conjugated channel - mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpPD0); - - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpPD1); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[0]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - // print_ints("re(shift)",&mmtmpPD0); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - // print_ints("im(shift)",&mmtmpPD1); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - // print_ints("c0",&mmtmpPD2); - // print_ints("c1",&mmtmpPD3); - rxdataF_comp128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - - // multiply by conjugated channel - mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[1]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); - - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); - // multiply by conjugated channel - if (pilots == 0) { - mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[2]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); - } - - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - - if (pilots==0) { - dl_ch128+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { - dl_ch128+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } -#elif defined(__arm__) - -#endif - } - } - } - - - if (rho) { - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - -#if defined(__x86_64__) || defined(__i386__) - rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - -#elif defined(__arm__) - -#endif - for (rb=0; rb<frame_parms->N_RB_DL; rb++) { -#if defined(__x86_64__) || defined(__i386__) - - // multiply by conjugated channel - mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpPD1); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[0]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - // print_ints("c0",&mmtmpPD2); - // print_ints("c1",&mmtmpPD3); - rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); - - //print_shorts("rx:",dl_ch128_2); - //print_shorts("ch:",dl_ch128); - //print_shorts("pack:",rho128); - - // multiply by conjugated channel - mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - - rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3); - //print_shorts("rx:",dl_ch128_2+1); - //print_shorts("ch:",dl_ch128+1); - //print_shorts("pack:",rho128+1); - // multiply by conjugated channel - mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]); - // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); - mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[2]); - // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); - mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); - mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); - mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); - - rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); - //print_shorts("rx:",dl_ch128_2+2); - //print_shorts("ch:",dl_ch128+2); - //print_shorts("pack:",rho128+2); - - dl_ch128+=3; - dl_ch128_2+=3; - rho128+=3; - -#elif defined(__arm_) - - -#endif - } - } - - } - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - -void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - uint8_t symbol) -{ - - uint8_t aatx; - -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1; -#elif defined(__arm__) - int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1; -#endif - int32_t i; - - if (frame_parms->nb_antennas_rx>1) { - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; -#elif defined(__arm__) - rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; -#endif - // MRC on each re of rb - for (i=0; i<frame_parms->N_RB_DL*3; i++) { -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); -#elif defined(__arm__) - rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); -#endif - } - } - } - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif - -} - -void pdcch_siso(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - uint8_t l) -{ - - - uint8_t rb,re,jj,ii; - - jj=0; - ii=0; - - for (rb=0; rb<frame_parms->N_RB_DL; rb++) { - - for (re=0; re<12; re++) { - - rxdataF_comp[0][jj++] = rxdataF_comp[0][ii]; - ii++; - } - } -} - - -void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - uint8_t symbol) -{ - - - int16_t *rxF0,*rxF1; - uint8_t rb,re; - int32_t jj=(symbol*frame_parms->N_RB_DL*12); - - rxF0 = (int16_t*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y - rxF1 = (int16_t*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y - - for (rb=0; rb<frame_parms->N_RB_DL; rb++) { - - for (re=0; re<12; re+=2) { - - // Alamouti RX combining - - rxF0[0] = rxF0[0] + rxF1[2]; - rxF0[1] = rxF0[1] - rxF1[3]; - - rxF0[2] = rxF0[2] - rxF1[0]; - rxF0[3] = rxF0[3] + rxF1[1]; - - rxF0+=4; - rxF1+=4; - } - } - - -} - -int32_t avgP[4]; - -int32_t rx_pdcch(PHY_VARS_UE *ue, - uint32_t frame, - uint8_t subframe, - uint8_t eNB_id, - MIMO_mode_t mimo_mode, - uint32_t high_speed_flag, - uint8_t is_secondary_ue) -{ - - LTE_UE_COMMON *common_vars = &ue->common_vars; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]]; - - uint8_t log2_maxh,aatx,aarx; -#ifdef MU_RECEIVER - uint8_t eNB_id_i=eNB_id+1;//add 1 to eNB_id to separate from wanted signal, chosen as the B/F'd pilots from the SeNB are shifted by 1 -#endif - int32_t avgs; - uint8_t n_pdcch_symbols; - uint8_t mi = get_mi(frame_parms,subframe); - - //printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d \n",subframe,eNB_id,pdcch_vars); - // procress ofdm symbol 0 - if (is_secondary_ue == 1) { - pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB - pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - 0, - high_speed_flag, - frame_parms); -#ifdef MU_RECEIVER - pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB - pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna - pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna - 0, - high_speed_flag, - frame_parms); -#endif //MU_RECEIVER - } else if (frame_parms->nb_antenna_ports_eNB>1) { - pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], - pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - 0, - high_speed_flag, - frame_parms); - } else { - pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], - pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - 0, - high_speed_flag, - frame_parms); - } - - - // compute channel level based on ofdm symbol 0 - pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - avgP, - frame_parms->N_RB_DL); - - avgs = 0; - - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) - avgs = cmax(avgs,avgP[(aarx<<1)+aatx]); - - log2_maxh = (log2_approx(avgs)/2) + 5; //+frame_parms->nb_antennas_rx; -#ifdef UE_DEBUG_TRACE - LOG_D(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs); -#endif - - T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id), T_INT(frame%1024), T_INT(subframe), - T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); - - // compute LLRs for ofdm symbol 0 only - pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - pdcch_vars[eNB_id]->rxdataF_comp, - (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL, - frame_parms, - 0, - log2_maxh); // log2_maxh+I0_shift - - -#ifdef DEBUG_PHY - - if (subframe==5) - write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - -#endif - -#ifdef MU_RECEIVER - - if (is_secondary_ue) { - //get MF output for interfering stream - pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext, - pdcch_vars[eNB_id_i]->dl_ch_estimates_ext, - pdcch_vars[eNB_id_i]->rxdataF_comp, - (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL, - frame_parms, - 0, - log2_maxh); // log2_maxh+I0_shift -#ifdef DEBUG_PHY - write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); -#endif - pdcch_dual_stream_correlation(frame_parms, - 0, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - pdcch_vars[eNB_id_i]->dl_ch_estimates_ext, - pdcch_vars[eNB_id]->dl_ch_rho_ext, - log2_maxh); - } - -#endif //MU_RECEIVER - - - if (frame_parms->nb_antennas_rx > 1) { -#ifdef MU_RECEIVER - - if (is_secondary_ue) { - pdcch_detection_mrc_i(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - pdcch_vars[eNB_id_i]->rxdataF_comp, - pdcch_vars[eNB_id]->rho, - pdcch_vars[eNB_id]->dl_ch_rho_ext, - 0); -#ifdef DEBUG_PHY - write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); -#endif - } else -#endif //MU_RECEIVER - pdcch_detection_mrc(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - 0); - } - - if (mimo_mode == SISO) - pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0); - else - pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0); - - -#ifdef MU_RECEIVER - - if (is_secondary_ue) { - pdcch_qpsk_qpsk_llr(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - pdcch_vars[eNB_id_i]->rxdataF_comp, - pdcch_vars[eNB_id]->dl_ch_rho_ext, - pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder) - pdcch_vars[eNB_id]->llr, - 0); - /* - #ifdef DEBUG_PHY - if (subframe==5) { - write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); - write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); - } - #endif*/ - } else { -#endif //MU_RECEIVER - pdcch_llr(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - (char *)pdcch_vars[eNB_id]->llr, - 0); - /*#ifdef DEBUG_PHY - write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); - #endif*/ - -#ifdef MU_RECEIVER - } - -#endif //MU_RECEIVER - - -#if T_TRACER - T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), - T_INT(n_pdcch_symbols), - T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); -#endif - - // decode pcfich here and find out pdcch ofdm symbol number - n_pdcch_symbols = rx_pcfich(frame_parms, - subframe, - pdcch_vars[eNB_id], - mimo_mode); - - - if (n_pdcch_symbols>3) - n_pdcch_symbols=1; - - -#ifdef DEBUG_DCI_DECODING - - LOG_I(PHY,"demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config); -#endif - - // process pdcch ofdm symbol 1 and 2 if necessary - for (int s=1; s<n_pdcch_symbols; s++){ - if (is_secondary_ue == 1) { - pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB - pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - s, - high_speed_flag, - frame_parms); -#ifdef MU_RECEIVER -pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB - pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna - pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna - s, - high_speed_flag, - frame_parms); -#endif //MU_RECEIVER - } else if (frame_parms->nb_antenna_ports_eNB>1) { - pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], - pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - s, - high_speed_flag, - frame_parms); - } else { - pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], - pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - s, - high_speed_flag, - frame_parms); - } - - - pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - pdcch_vars[eNB_id]->rxdataF_comp, - (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL, - frame_parms, - s, - log2_maxh); // log2_maxh+I0_shift - - -#ifdef DEBUG_PHY - -if (subframe==5) - write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - -#endif - -#ifdef MU_RECEIVER - -if (is_secondary_ue) { - //get MF output for interfering stream - pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext, - pdcch_vars[eNB_id_i]->dl_ch_estimates_ext, - pdcch_vars[eNB_id_i]->rxdataF_comp, - (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL, - frame_parms, - s, - log2_maxh); // log2_maxh+I0_shift -#ifdef DEBUG_PHY -write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); -#endif -pdcch_dual_stream_correlation(frame_parms, - s, - pdcch_vars[eNB_id]->dl_ch_estimates_ext, - pdcch_vars[eNB_id_i]->dl_ch_estimates_ext, - pdcch_vars[eNB_id]->dl_ch_rho_ext, - log2_maxh); -} - -#endif //MU_RECEIVER - - -if (frame_parms->nb_antennas_rx > 1) { -#ifdef MU_RECEIVER - - if (is_secondary_ue) { - pdcch_detection_mrc_i(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - pdcch_vars[eNB_id_i]->rxdataF_comp, - pdcch_vars[eNB_id]->rho, - pdcch_vars[eNB_id]->dl_ch_rho_ext, - s); -#ifdef DEBUG_PHY -write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); -write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); -#endif - } else -#endif //MU_RECEIVER - pdcch_detection_mrc(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - s); - -} - -if (mimo_mode == SISO) - pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s); -else - pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s); - - -#ifdef MU_RECEIVER - -if (is_secondary_ue) { - pdcch_qpsk_qpsk_llr(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - pdcch_vars[eNB_id_i]->rxdataF_comp, - pdcch_vars[eNB_id]->dl_ch_rho_ext, - pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder) - pdcch_vars[eNB_id]->llr, - s); - /* - #ifdef DEBUG_PHY - if (subframe==5) { - write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); - write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); - } - #endif*/ -} else { -#endif //MU_RECEIVER - pdcch_llr(frame_parms, - pdcch_vars[eNB_id]->rxdataF_comp, - (char *)pdcch_vars[eNB_id]->llr, - s); - /*#ifdef DEBUG_PHY - write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); - #endif*/ - -#ifdef MU_RECEIVER -} - -#endif //MU_RECEIVER - - } - - pdcch_demapping(pdcch_vars[eNB_id]->llr, - pdcch_vars[eNB_id]->wbar, - frame_parms, - n_pdcch_symbols, - get_mi(frame_parms,subframe)); - - pdcch_deinterleaving(frame_parms, - (uint16_t*)pdcch_vars[eNB_id]->e_rx, - pdcch_vars[eNB_id]->wbar, - n_pdcch_symbols, - mi); - - pdcch_unscrambling(frame_parms, - subframe, - pdcch_vars[eNB_id]->e_rx, - get_nCCE(n_pdcch_symbols,frame_parms,mi)*72); - - pdcch_vars[eNB_id]->num_pdcch_symbols = n_pdcch_symbols; - - return(0); -} - - -void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t subframe, - uint8_t *e, - uint32_t length) -{ - int i; - uint8_t reset; - uint32_t x1, x2, s=0; - - //LOG_D(PHY, "%s(fp, subframe:%d, e, length:%d)\n", __FUNCTION__, subframe, length); - - reset = 1; - // x1 is set in lte_gold_generic - - x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 - - for (i=0; i<length; i++) { - if ((i&0x1f)==0) { - s = lte_gold_generic(&x1, &x2, reset); - //printf("lte_gold[%d]=%x\n",i,s); - reset = 0; - } - - // printf("scrambling %d : e %d, c %d\n",i,e[i],((s>>(i&0x1f))&1)); - if (e[i] != 2) // <NIL> element is 2 - e[i] = (e[i]&1) ^ ((s>>(i&0x1f))&1); - } -} - -void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t subframe, - int8_t* llr, - uint32_t length) -{ - int i; uint8_t reset; uint32_t x1, x2, s=0; + //LOG_D(PHY, "%s(fp, subframe:%d, e, length:%d)\n", __FUNCTION__, subframe, length); + reset = 1; - // x1 is set in first call to lte_gold_generic + // x1 is set in lte_gold_generic x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 for (i=0; i<length; i++) { if ((i&0x1f)==0) { s = lte_gold_generic(&x1, &x2, reset); - // printf("lte_gold[%d]=%x\n",i,s); + //printf("lte_gold[%d]=%x\n",i,s); reset = 0; } - - // printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1)); - if (((s>>(i%32))&1)==0) - llr[i] = -llr[i]; - // printf("%d\n",llr[i]); - - } -} - -/* -uint8_t get_num_pdcch_symbols(uint8_t num_dci, - DCI_ALLOC_t *dci_alloc, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t subframe) -{ - - uint16_t numCCE = 0; - uint8_t i; - uint8_t nCCEmin = 0; - uint16_t CCE_max_used_index = 0; - uint16_t firstCCE_max = dci_alloc[0].firstCCE; - uint8_t L = dci_alloc[0].L; - - // check pdcch duration imposed by PHICH duration (Section 6.9 of 36-211) - if (frame_parms->Ncp==1) { // extended prefix - if ((frame_parms->frame_type == TDD) && - ((frame_parms->tdd_config<3)||(frame_parms->tdd_config==6)) && - ((subframe==1) || (subframe==6))) // subframes 1 and 6 (S-subframes) for 5ms switching periodicity are 2 symbols - nCCEmin = 2; - else { // 10ms switching periodicity is always 3 symbols, any DL-only subframe is 3 symbols - nCCEmin = 3; - } - } - - // compute numCCE - for (i=0; i<num_dci; i++) { - // printf("dci %d => %d\n",i,dci_alloc[i].L); - numCCE += (1<<(dci_alloc[i].L)); - - if(firstCCE_max < dci_alloc[i].firstCCE) { - firstCCE_max = dci_alloc[i].firstCCE; - L = dci_alloc[i].L; - } - } - CCE_max_used_index = firstCCE_max + (1<<L) - 1; - - //if ((9*numCCE) <= (frame_parms->N_RB_DL*2)) - if (CCE_max_used_index < get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) - return(cmax(1,nCCEmin)); - //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5))) - else if (CCE_max_used_index < get_nCCE(2, frame_parms, get_mi(frame_parms, subframe))) - return(cmax(2,nCCEmin)); - //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8))) - else if (CCE_max_used_index < get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))) - return(cmax(3,nCCEmin)); - else if (frame_parms->N_RB_DL<=10) { - if (frame_parms->Ncp == 0) { // normal CP - printf("numCCE %d, N_RB_DL = %d : should be returning 4 PDCCH symbols (%d,%d,%d)\n",numCCE,frame_parms->N_RB_DL, - get_nCCE(1, frame_parms, get_mi(frame_parms, subframe)), - get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)), - get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))); - - if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 10 : 11))) - return(4); - } else { // extended CP - if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 9 : 10))) - return(4); - } + // printf("scrambling %d : e %d, c %d\n",i,e[i],((s>>(i&0x1f))&1)); + if (e[i] != 2) // <NIL> element is 2 + e[i] = (e[i]&1) ^ ((s>>(i&0x1f))&1); } - - - - // LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci); - //for (i=0;i<num_dci;i++) { - // printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L); - //} - //exit(-1); -exit(1); - return(0); } -*/ - uint8_t generate_dci_top(uint8_t num_pdcch_symbols, uint8_t num_dci, @@ -2206,8 +289,9 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, uint32_t gain_lin_QPSK,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset; int16_t re_offset; uint8_t mi = get_mi(frame_parms,subframe); - static uint8_t e[DCI_BITS_MAX]; - static int32_t yseq0[Msymb],yseq1[Msymb],wbar0[Msymb],wbar1[Msymb]; + uint8_t e[DCI_BITS_MAX]; + uint32_t Msymb=(DCI_BITS_MAX/2); + int32_t yseq0[Msymb],yseq1[Msymb],wbar0[Msymb],wbar1[Msymb]; int32_t *y[2]; int32_t *wbar[2]; @@ -2260,7 +344,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, y[0] = &yseq0[0]; y[1] = &yseq1[0]; -#if 0 +#if 1 // reset all bits to <NIL>, here we set <NIL> elements as 2 // memset(e, 2, DCI_BITS_MAX); // here we interpret NIL as a random QPSK sequence. That makes power estimation easier. @@ -2271,7 +355,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, /* clear all bits, the above code may generate too much false detections * (not sure about this, to be checked somehow) */ - memset(e, 0, DCI_BITS_MAX); + //memset(e, 0, DCI_BITS_MAX); e_ptr = e; @@ -2285,14 +369,15 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (dci_alloc[i].L == (uint8_t)L) { #ifdef DEBUG_DCI_ENCODING - if (dci_alloc[i].rnti==0x02) - LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, + if (dci_alloc[i].rnti==0x1234) + LOG_D(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, *(unsigned int*)dci_alloc[i].dci_pdu, dci_alloc[i].rnti); - //dump_dci(frame_parms,&dci_alloc[i]); + dump_dci(frame_parms,&dci_alloc[i]); #endif if (dci_alloc[i].firstCCE>=0) { +//printf("generate DCI .%d rnti %d length %d\n", subframe, dci_alloc[i].rnti, dci_alloc[i].dci_length); e_ptr = generate_dci0(dci_alloc[i].dci_pdu, e+(72*dci_alloc[i].firstCCE), dci_alloc[i].dci_length, @@ -2340,7 +425,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, for (i=0; i<Msymb2; i++) { - + //((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; //((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; ((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; @@ -2535,1706 +620,3 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, } - -void dci_decoding(uint8_t DCI_LENGTH, - uint8_t aggregation_level, - int8_t *e, - uint8_t *decoded_output) -{ - - uint8_t dummy_w_rx[3*(MAX_DCI_SIZE_BITS+16+64)]; - int8_t w_rx[3*(MAX_DCI_SIZE_BITS+16+32)],d_rx[96+(3*(MAX_DCI_SIZE_BITS+16))]; - - uint16_t RCC; - - uint16_t D=(DCI_LENGTH+16+64); - uint16_t coded_bits; -#ifdef DEBUG_DCI_DECODING - int32_t i; -#endif - - AssertFatal(aggregation_level<4, - "dci_decoding FATAL, illegal aggregation_level %d\n",aggregation_level); - - coded_bits = 72 * (1<<aggregation_level); - -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY," Doing DCI decoding for %d bits, DCI_LENGTH %d,coded_bits %d, e %p\n",3*(DCI_LENGTH+16),DCI_LENGTH,coded_bits,e); -#endif - - // now do decoding - memset((void*)dummy_w_rx,0,3*D); - RCC = generate_dummy_w_cc(DCI_LENGTH+16, - dummy_w_rx); - - - -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY," Doing DCI Rate Matching RCC %d, w %p\n",RCC,w); -#endif - - lte_rate_matching_cc_rx(RCC,coded_bits,w_rx,dummy_w_rx,e); - - sub_block_deinterleaving_cc((uint32_t)(DCI_LENGTH+16), - &d_rx[96], - &w_rx[0]); - -#ifdef DEBUG_DCI_DECODING - - for (i=0; i<16+DCI_LENGTH; i++) - LOG_I(PHY," DCI %d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i))); - -#endif - memset(decoded_output,0,2+((16+DCI_LENGTH)>>3)); - -#ifdef DEBUG_DCI_DECODING - printf("Before Viterbi\n"); - - for (i=0; i<16+DCI_LENGTH; i++) - printf("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i))); - -#endif - //debug_printf("Doing DCI Viterbi \n"); - phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH); - //debug_printf("Done DCI Viterbi \n"); -} - - -static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8]; - -uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi) -{ - return(get_nquad(num_pdcch_symbols,frame_parms,mi)/9); -} - -uint16_t get_nquad(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi) -{ - - uint16_t Nreg=0; - uint8_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; - - if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) - Ngroup_PHICH++; - - if (frame_parms->Ncp == 1) { - Ngroup_PHICH<<=1; - } - - Ngroup_PHICH*=mi; - - if ((num_pdcch_symbols>0) && (num_pdcch_symbols<4)) - switch (frame_parms->N_RB_DL) { - case 6: - Nreg=12+(num_pdcch_symbols-1)*18; - break; - - case 25: - Nreg=50+(num_pdcch_symbols-1)*75; - break; - - case 50: - Nreg=100+(num_pdcch_symbols-1)*150; - break; - - case 100: - Nreg=200+(num_pdcch_symbols-1)*300; - break; - - default: - return(0); - } - - // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); - return(Nreg - 4 - (3*Ngroup_PHICH)); -} - -uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe) -{ - - // check for eNB only ! - return(get_nCCE(num_pdcch_symbols, - &RC.eNB[Mod_id][CC_id]->frame_parms, - get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe))); -} - - -int get_nCCE_offset_l1(int *CCE_table, - const unsigned char L, - const int nCCE, - const int common_dci, - const unsigned short rnti, - const unsigned char subframe) -{ - - int search_space_free,m,nb_candidates = 0,l,i; - unsigned int Yk; - /* - printf("CCE Allocation: "); - for (i=0;i<nCCE;i++) - printf("%d.",CCE_table[i]); - printf("\n"); - */ - if (common_dci == 1) { - // check CCE(0 ... L-1) - nb_candidates = (L==4) ? 4 : 2; - nb_candidates = min(nb_candidates,nCCE/L); - - // printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L); - - for (m = nb_candidates-1 ; m >=0 ; m--) { - - search_space_free = 1; - for (l=0; l<L; l++) { - - // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); - if (CCE_table[(m*L) + l] == 1) { - search_space_free = 0; - break; - } - } - - if (search_space_free == 1) { - - // printf("returning %d\n",m*L); - - for (l=0; l<L; l++) - CCE_table[(m*L)+l]=1; - return(m*L); - } - } - - return(-1); - - } else { // Find first available in ue specific search space - // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) - // compute Yk - Yk = (unsigned int)rnti; - - for (i=0; i<=subframe; i++) - Yk = (Yk*39827)%65537; - - Yk = Yk % (nCCE/L); - - - switch (L) { - case 1: - case 2: - nb_candidates = 6; - break; - - case 4: - case 8: - nb_candidates = 2; - break; - - default: - DevParam(L, nCCE, rnti); - break; - } - - - LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates); - - for (m = 0 ; m < nb_candidates ; m++) { - search_space_free = 1; - - for (l=0; l<L; l++) { - int cce = (((Yk+m)%(nCCE/L))*L) + l; - if (cce >= nCCE || CCE_table[cce] == 1) { - search_space_free = 0; - break; - } - } - - if (search_space_free == 1) { - for (l=0; l<L; l++) - CCE_table[(((Yk+m)%(nCCE/L))*L)+l]=1; - - return(((Yk+m)%(nCCE/L))*L); - } - } - - return(-1); - } -} - - -void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, - int do_common, - dci_detect_mode_t mode, - uint8_t subframe, - DCI_ALLOC_t *dci_alloc, - int16_t eNB_id, - uint8_t current_thread_id, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t mi, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint8_t L, - uint8_t format_si, - uint8_t format_p, - uint8_t format_ra, - uint8_t format_c, - uint8_t sizeof_bits, - uint8_t sizeof_bytes, - uint8_t *dci_cnt, - uint8_t *format0_found, - uint8_t *format_c_found, - uint32_t *CCEmap0, - uint32_t *CCEmap1, - uint32_t *CCEmap2) -{ - - uint16_t crc,CCEind,nCCE; - uint32_t *CCEmap=NULL,CCEmap_mask=0; - int L2=(1<<L); - unsigned int Yk,nb_candidates = 0,i,m; - unsigned int CCEmap_cand; - - nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi); - - if (nCCE > get_nCCE(3,frame_parms,1)) { - LOG_D(PHY,"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", nCCE, get_nCCE(3,frame_parms,1)); - return; - } - - if (nCCE<L2) { - LOG_D(PHY,"skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2); - return; - } - - if (mode == NO_DCI) { - LOG_D(PHY, "skip DCI decoding: expect no DCIs at subframe %d\n", subframe); - return; - } - - if (do_common == 1) { - nb_candidates = (L2==4) ? 4 : 2; - Yk=0; - } else { - // Find first available in ue specific search space - // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) - // compute Yk - Yk = (unsigned int)pdcch_vars[eNB_id]->crnti; - - for (i=0; i<=subframe; i++) - Yk = (Yk*39827)%65537; - - Yk = Yk % (nCCE/L2); - - switch (L2) { - case 1: - case 2: - nb_candidates = 6; - break; - - case 4: - case 8: - nb_candidates = 2; - break; - - default: - DevParam(L2, do_common, eNB_id); - break; - } - } - - /* for (CCEind=0; - CCEind<nCCE2; - CCEind+=(1<<L)) {*/ - - if (nb_candidates*L2 > nCCE) - nb_candidates = nCCE/L2; - - for (m=0; m<nb_candidates; m++) { - - CCEind = (((Yk+m)%(nCCE/L2))*L2); - - if (CCEind<32) - CCEmap = CCEmap0; - else if (CCEind<64) - CCEmap = CCEmap1; - else if (CCEind<96) - CCEmap = CCEmap2; - else { - AssertFatal(1==0, - "Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind,Yk,m,nCCE,L2); - } - - switch (L2) { - case 1: - CCEmap_mask = (1<<(CCEind&0x1f)); - break; - - case 2: - CCEmap_mask = (3<<(CCEind&0x1f)); - break; - - case 4: - CCEmap_mask = (0xf<<(CCEind&0x1f)); - break; - - case 8: - CCEmap_mask = (0xff<<(CCEind&0x1f)); - break; - - default: - AssertFatal(1==0, - "Illegal L2 value %d\n", L2 ); - } - - CCEmap_cand = (*CCEmap)&CCEmap_mask; - - // CCE is not allocated yet - - if (CCEmap_cand == 0) { - - if (do_common == 1) - LOG_D(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); - else - LOG_D(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); - - dci_decoding(sizeof_bits, - L, - &pdcch_vars[eNB_id]->e_rx[CCEind*72], - &dci_decoded_output[current_thread_id][0]); - /* - for (i=0;i<3+(sizeof_bits>>3);i++) - printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]); - */ - - crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits); -#ifdef DEBUG_DCI_DECODING - printf("crc =>%x\n",crc); -#endif - - if (((L>1) && ((crc == si_rnti)|| - (crc == p_rnti)|| - (crc == ra_rnti)))|| - (crc == pdcch_vars[eNB_id]->crnti)) { - dci_alloc[*dci_cnt].dci_length = sizeof_bits; - dci_alloc[*dci_cnt].rnti = crc; - dci_alloc[*dci_cnt].L = L; - dci_alloc[*dci_cnt].firstCCE = CCEind; - - //printf("DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes); - if (sizeof_bytes<=4) { - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3]; -#ifdef DEBUG_DCI_DECODING - printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0], - dci_decoded_output[current_thread_id][1], - dci_decoded_output[current_thread_id][2], - dci_decoded_output[current_thread_id][3]); -#endif - } else { - dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0]; - dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1]; - dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2]; - dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3]; - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7]; -#ifdef DEBUG_DCI_DECODING - printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", - dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3], - dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]); -#endif - } - - if (crc==si_rnti) { - dci_alloc[*dci_cnt].format = format_si; - *dci_cnt = *dci_cnt+1; - } else if (crc==p_rnti) { - dci_alloc[*dci_cnt].format = format_p; - *dci_cnt = *dci_cnt+1; - } else if (crc==ra_rnti) { - dci_alloc[*dci_cnt].format = format_ra; - // store first nCCE of group for PUCCH transmission of ACK/NAK - pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; - *dci_cnt = *dci_cnt+1; - } else if (crc==pdcch_vars[eNB_id]->crnti) { - - if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A - if (*format0_found == 0) { - dci_alloc[*dci_cnt].format = format0; - *format0_found = 1; - *dci_cnt = *dci_cnt+1; - pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; - } - } else if (format_c == format0) { // this is a format 1A DCI - dci_alloc[*dci_cnt].format = format1A; - *dci_cnt = *dci_cnt+1; - pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; - } else { - // store first nCCE of group for PUCCH transmission of ACK/NAK - if (*format_c_found == 0) { - dci_alloc[*dci_cnt].format = format_c; - *dci_cnt = *dci_cnt+1; - *format_c_found = 1; - pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; - } - } - } - - //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2); - // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); - - - - switch (1<<L) { - case 1: - *CCEmap|=(1<<(CCEind&0x1f)); - break; - - case 2: - *CCEmap|=(1<<(CCEind&0x1f)); - break; - - case 4: - *CCEmap|=(1<<(CCEind&0x1f)); - break; - - case 8: - *CCEmap|=(1<<(CCEind&0x1f)); - break; - } - -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x) candidate %d / %d \n", - *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap,m,nb_candidates ); - dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]); - -#endif - return; - } // rnti match - } // CCEmap_cand == 0 -/* - if ( agregationLevel != 0xFF && - (format_c == format0 && m==0 && si_rnti != SI_RNTI)) - { - //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0. - return; - } -*/ - } // candidate loop -} - -uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue, - DCI_ALLOC_t *dci_alloc, - uint8_t DCIFormat, - uint8_t agregationLevel, - int16_t eNB_id, - uint8_t subframe) -{ - - uint8_t dci_cnt=0,old_dci_cnt=0; - uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0; - LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]]; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - uint8_t mi = get_mi(&ue->frame_parms,subframe); - uint16_t ra_rnti=99; - uint8_t format0_found=0,format_c_found=0; - uint8_t tmode = ue->transmission_mode[eNB_id]; - uint8_t frame_type = frame_parms->frame_type; - uint8_t format0_size_bits=0,format0_size_bytes=0; - uint8_t format1_size_bits=0,format1_size_bytes=0; - dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe); - - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t); - - } else { - format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t); - } - - break; - - case 25: - default: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_TDD_t); - } else { - format0_size_bits = sizeof_DCI0_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_FDD_t); - } - - break; - - case 50: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_10MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_TDD_t); - - } else { - format0_size_bits = sizeof_DCI0_10MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_10MHz_FDD_t); - format1_size_bits = sizeof_DCI1_10MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_FDD_t); - } - - break; - - case 100: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_20MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_TDD_t); - } else { - format0_size_bits = sizeof_DCI0_20MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_20MHz_FDD_t); - format1_size_bits = sizeof_DCI1_20MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_FDD_t); - } - - break; - } - - if (ue->prach_resources[eNB_id]) - ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; - - // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8 - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - agregationLevel, - format1A, - format1A, - format1A, - format0, - format0_size_bits, - format0_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (DCIFormat == 1) - { - if ((tmode < 3) || (tmode == 7)) { - //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); - - // Now check UE_SPEC format 1 search spaces at aggregation 1 - - //printf("[DCI search] Format 1/1A aggregation 1\n"); - - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format1, - format1_size_bits, - format1_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff) || - (format_c_found==1)) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); - - } - else - { - AssertFatal(0,"Other Transmission mode not yet coded\n"); - } - } - else - { - AssertFatal(0,"DCI format %d not yet implemented \n",DCIFormat); - } - - return(dci_cnt); - -} - -uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, - DCI_ALLOC_t *dci_alloc, - int do_common, - int16_t eNB_id, - uint8_t subframe) -{ - - uint8_t dci_cnt=0,old_dci_cnt=0; - uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0; - LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]]; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - uint8_t mi = get_mi(&ue->frame_parms,subframe); - uint16_t ra_rnti=99; - uint8_t format0_found=0,format_c_found=0; - uint8_t tmode = ue->transmission_mode[eNB_id]; - uint8_t frame_type = frame_parms->frame_type; - uint8_t format1A_size_bits=0,format1A_size_bytes=0; - uint8_t format1C_size_bits=0,format1C_size_bytes=0; - uint8_t format0_size_bits=0,format0_size_bytes=0; - uint8_t format1_size_bits=0,format1_size_bytes=0; - uint8_t format2_size_bits=0,format2_size_bytes=0; - uint8_t format2A_size_bits=0,format2A_size_bytes=0; - dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe); - - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_type == TDD) { - format1A_size_bits = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - format1A_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - format1C_size_bits = sizeof_DCI1C_1_5MHz_t; - format1C_size_bytes = sizeof(DCI1C_1_5MHz_t); - format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_1_5MHz_2A_TDD_t; - format2_size_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); - format2A_size_bits = sizeof_DCI2A_1_5MHz_2A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_1_5MHz_4A_TDD_t; - format2_size_bytes = sizeof(DCI2_1_5MHz_4A_TDD_t); - format2A_size_bits = sizeof_DCI2A_1_5MHz_4A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_TDD_t); - } - } else { - format1A_size_bits = sizeof_DCI1A_1_5MHz_FDD_t; - format1A_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - format1C_size_bits = sizeof_DCI1C_1_5MHz_t; - format1C_size_bytes = sizeof(DCI1C_1_5MHz_t); - format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_1_5MHz_2A_FDD_t; - format2_size_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); - format2A_size_bits = sizeof_DCI2A_1_5MHz_2A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_1_5MHz_4A_FDD_t; - format2_size_bytes = sizeof(DCI2_1_5MHz_4A_FDD_t); - format2A_size_bits = sizeof_DCI2A_1_5MHz_4A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_FDD_t); - } - } - - break; - - case 25: - default: - if (frame_type == TDD) { - format1A_size_bits = sizeof_DCI1A_5MHz_TDD_1_6_t; - format1A_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - format1C_size_bits = sizeof_DCI1C_5MHz_t; - format1C_size_bytes = sizeof(DCI1C_5MHz_t); - format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_TDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_5MHz_2A_TDD_t; - format2_size_bytes = sizeof(DCI2_5MHz_2A_TDD_t); - format2A_size_bits = sizeof_DCI2A_5MHz_2A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_5MHz_4A_TDD_t; - format2_size_bytes = sizeof(DCI2_5MHz_4A_TDD_t); - format2A_size_bits = sizeof_DCI2A_5MHz_4A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_5MHz_4A_TDD_t); - } - } else { - format1A_size_bits = sizeof_DCI1A_5MHz_FDD_t; - format1A_size_bytes = sizeof(DCI1A_5MHz_FDD_t); - format1C_size_bits = sizeof_DCI1C_5MHz_t; - format1C_size_bytes = sizeof(DCI1C_5MHz_t); - format0_size_bits = sizeof_DCI0_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_FDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_5MHz_2A_FDD_t; - format2_size_bytes = sizeof(DCI2_5MHz_2A_FDD_t); - format2A_size_bits = sizeof_DCI2A_5MHz_2A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_5MHz_4A_FDD_t; - format2_size_bytes = sizeof(DCI2_5MHz_4A_FDD_t); - format2A_size_bits = sizeof_DCI2A_5MHz_4A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_5MHz_4A_FDD_t); - } - } - - break; - - case 50: - if (frame_type == TDD) { - format1A_size_bits = sizeof_DCI1A_10MHz_TDD_1_6_t; - format1A_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - format1C_size_bits = sizeof_DCI1C_10MHz_t; - format1C_size_bytes = sizeof(DCI1C_10MHz_t); - format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_10MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_TDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_10MHz_2A_TDD_t; - format2_size_bytes = sizeof(DCI2_10MHz_2A_TDD_t); - format2A_size_bits = sizeof_DCI2A_10MHz_2A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_10MHz_4A_TDD_t; - format2_size_bytes = sizeof(DCI2_10MHz_4A_TDD_t); - format2A_size_bits = sizeof_DCI2A_10MHz_4A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_10MHz_4A_TDD_t); - } - } else { - format1A_size_bits = sizeof_DCI1A_10MHz_FDD_t; - format1A_size_bytes = sizeof(DCI1A_10MHz_FDD_t); - format1C_size_bits = sizeof_DCI1C_10MHz_t; - format1C_size_bytes = sizeof(DCI1C_10MHz_t); - format0_size_bits = sizeof_DCI0_10MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_10MHz_FDD_t); - format1_size_bits = sizeof_DCI1_10MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_FDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_10MHz_2A_FDD_t; - format2_size_bytes = sizeof(DCI2_10MHz_2A_FDD_t); - format2A_size_bits = sizeof_DCI2A_10MHz_2A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_10MHz_4A_FDD_t; - format2_size_bytes = sizeof(DCI2_10MHz_4A_FDD_t); - format2A_size_bits = sizeof_DCI2A_10MHz_4A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_10MHz_4A_FDD_t); - } - } - - break; - - case 100: - if (frame_type == TDD) { - format1A_size_bits = sizeof_DCI1A_20MHz_TDD_1_6_t; - format1A_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - format1C_size_bits = sizeof_DCI1C_20MHz_t; - format1C_size_bytes = sizeof(DCI1C_20MHz_t); - format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_20MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_TDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_20MHz_2A_TDD_t; - format2_size_bytes = sizeof(DCI2_20MHz_2A_TDD_t); - format2A_size_bits = sizeof_DCI2A_20MHz_2A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_20MHz_4A_TDD_t; - format2_size_bytes = sizeof(DCI2_20MHz_4A_TDD_t); - format2A_size_bits = sizeof_DCI2A_20MHz_4A_TDD_t; - format2A_size_bytes = sizeof(DCI2A_20MHz_4A_TDD_t); - } - } else { - format1A_size_bits = sizeof_DCI1A_20MHz_FDD_t; - format1A_size_bytes = sizeof(DCI1A_20MHz_FDD_t); - format1C_size_bits = sizeof_DCI1C_20MHz_t; - format1C_size_bytes = sizeof(DCI1C_20MHz_t); - format0_size_bits = sizeof_DCI0_20MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_20MHz_FDD_t); - format1_size_bits = sizeof_DCI1_20MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_FDD_t); - - if (frame_parms->nb_antenna_ports_eNB == 2) { - format2_size_bits = sizeof_DCI2_20MHz_2A_FDD_t; - format2_size_bytes = sizeof(DCI2_20MHz_2A_FDD_t); - format2A_size_bits = sizeof_DCI2A_20MHz_2A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - format2_size_bits = sizeof_DCI2_20MHz_4A_FDD_t; - format2_size_bytes = sizeof(DCI2_20MHz_4A_FDD_t); - format2A_size_bits = sizeof_DCI2A_20MHz_4A_FDD_t; - format2A_size_bytes = sizeof(DCI2A_20MHz_4A_FDD_t); - } - } - - break; - } - - if (do_common == 1) { -#ifdef DEBUG_DCI_DECODING - printf("[DCI search] doing common search/format0 aggregation 4\n"); -#endif - - if (ue->prach_resources[eNB_id]) - ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; - - // First check common search spaces at aggregation 4 (SI_RNTI, P_RNTI and RA_RNTI format 0/1A), - // and UE_SPEC format0 (PUSCH) too while we're at it - dci_decoding_procedure0(pdcch_vars,1,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0) , - ra_rnti, - P_RNTI, - 2, - format1A, - format1A, - format1A, - format0, - format1A_size_bits, - format1A_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff) || - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - // Now check common search spaces at aggregation 4 (SI_RNTI,P_RNTI and RA_RNTI and C-RNTI format 1C), - // and UE_SPEC format0 (PUSCH) too while we're at it - dci_decoding_procedure0(pdcch_vars,1,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 2, - format1C, - format1C, - format1C, - format1C, - format1C_size_bits, - format1C_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff) || - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - // Now check common search spaces at aggregation 8 (SI_RNTI,P_RNTI and RA_RNTI format 1A), - // and UE_SPEC format0 (PUSCH) too while we're at it - // printf("[DCI search] doing common search/format0 aggregation 3\n"); -#ifdef DEBUG_DCI_DECODING - printf("[DCI search] doing common search/format0 aggregation 8\n"); -#endif - dci_decoding_procedure0(pdcch_vars,1,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - P_RNTI, - ra_rnti, - 3, - format1A, - format1A, - format1A, - format0, - format1A_size_bits, - format1A_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - // Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI and C-RNTI format 1C), - // and UE_SPEC format0 (PUSCH) too while we're at it - dci_decoding_procedure0(pdcch_vars,1,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 3, - format1C, - format1C, - format1C, - format1C, - format1C_size_bits, - format1C_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - //#endif - - } - - if (ue->UE_mode[eNB_id] <= PRACH) - return(dci_cnt); - - if (ue->prach_resources[eNB_id]) - ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; - - // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8 - // printf("[DCI search] Format 0/1A aggregation 8\n"); - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format0, - format0_size_bits, - format0_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - //printf("[DCI search] Format 0 aggregation 1 dci_cnt %d\n",dci_cnt); - - if (dci_cnt == 0) - { - // Now check UE_SPEC format 0 search spaces at aggregation 4 - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 1, - format1A, - format1A, - format1A, - format0, - format0_size_bits, - format0_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - - //printf("[DCI search] Format 0 aggregation 2 dci_cnt %d\n",dci_cnt); - } - - if (dci_cnt == 0) - { - // Now check UE_SPEC format 0 search spaces at aggregation 2 - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 2, - format1A, - format1A, - format1A, - format0, - format0_size_bits, - format0_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - //printf("[DCI search] Format 0 aggregation 4 dci_cnt %d\n",dci_cnt); - } - - if (dci_cnt == 0) - { - // Now check UE_SPEC format 0 search spaces at aggregation 1 - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 3, - format1A, - format1A, - format1A, - format0, - format0_size_bits, - format0_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - //printf("[DCI search] Format 0 aggregation 8 dci_cnt %d\n",dci_cnt); - - } - // These are for CRNTI based on transmission mode - if ((tmode < 3) || (tmode == 7)) { - // Now check UE_SPEC format 1 search spaces at aggregation 1 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format1, - format1_size_bits, - format1_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - //printf("[DCI search] Format 1 aggregation 1 dci_cnt %d\n",dci_cnt); - - if ((CCEmap0==0xffff) || - (format_c_found==1)) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 1 search spaces at aggregation 2 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 1, - format1A, - format1A, - format1A, - format1, - format1_size_bits, - format1_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - //printf("[DCI search] Format 1 aggregation 2 dci_cnt %d\n",dci_cnt); - - if ((CCEmap0==0xffff)|| - (format_c_found==1)) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 1 search spaces at aggregation 4 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 2, - format1A, - format1A, - format1A, - format1, - format1_size_bits, - format1_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - //printf("[DCI search] Format 1 aggregation 4 dci_cnt %d\n",dci_cnt); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //#ifdef ALL_AGGREGATION - // Now check UE_SPEC format 1 search spaces at aggregation 8 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode,subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 3, - format1A, - format1A, - format1A, - format1, - format1_size_bits, - format1_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - //printf("[DCI search] Format 1 aggregation 8 dci_cnt %d\n",dci_cnt); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //#endif //ALL_AGGREGATION - } else if (tmode == 3) { - - - LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); - // Now check UE_SPEC format 2A_2A search spaces at aggregation 1 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format2A, - format2A_size_bits, - format2A_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - LOG_D(PHY," format 2A_2A search CCEmap0 %x, format0_found %d, format_c_found %d \n", CCEmap0, format0_found, format_c_found); - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 2 search spaces at aggregation 2 - LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 2 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 1, - format1A, - format1A, - format1A, - format2A, - format2A_size_bits, - format2A_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 2_2A search spaces at aggregation 4 - LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n"); - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 2, - format1A, - format1A, - format1A, - format2A, - format2A_size_bits, - format2A_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //#ifdef ALL_AGGREGATION - // Now check UE_SPEC format 2_2A search spaces at aggregation 8 - LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 8 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 3, - format1A, - format1A, - format1A, - format2A, - format2A_size_bits, - format2A_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - //#endif - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - } else if (tmode == 4) { - - // Now check UE_SPEC format 2_2A search spaces at aggregation 1 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format2, - format2_size_bits, - format2_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 2 search spaces at aggregation 2 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 1, - format1A, - format1A, - format1A, - format2, - format2_size_bits, - format2_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 2_2A search spaces at aggregation 4 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 2, - format1A, - format1A, - format1A, - format2, - format2_size_bits, - format2_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //#ifdef ALL_AGGREGATION - // Now check UE_SPEC format 2_2A search spaces at aggregation 8 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 3, - format1A, - format1A, - format1A, - format2, - format2_size_bits, - format2_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - //#endif - } else if ((tmode==5) || (tmode==6)) { // This is MU-MIMO - - // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 1 -#ifdef DEBUG_DCI_DECODING - LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n"); -#endif - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format1E_2A_M10PRB, - sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, - sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 1, - format1A, - format1A, - format1A, - format1E_2A_M10PRB, - sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, - sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 2, - format1A, - format1A, - format1A, - format1E_2A_M10PRB, - sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, - sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //#ifdef ALL_AGGREGATION - - // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8 - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode, - subframe, - dci_alloc, - eNB_id, - ue->current_thread_id[subframe], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 3, - format1A, - format1A, - format1A, - format1E_2A_M10PRB, - sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, - sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //#endif //ALL_AGGREGATION - - } - - return(dci_cnt); -} diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h index 9381dd63fdd1a3d49b50e6ce4b27793c1a1074c1..c5654aa7428203ca04b4c709eaedae3612adf84d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.h +++ b/openair1/PHY/LTE_TRANSPORT/dci.h @@ -30,8 +30,18 @@ * \warning */ +#ifndef __DCI__h__ +#define __DCI__h__ + #include <stdint.h> +#define CCEBITS 72 +#define CCEPERSYMBOL 33 // This is for 1200 RE +#define CCEPERSYMBOL0 22 // This is for 1200 RE +#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS) + +//#define Mquad (Msymb/4) + /// DCI Format Type 0 (5 MHz,TDD0, 27 bits) struct DCI0_5MHz_TDD0 { /// type = 0 => DCI Format 0, type = 1 => DCI Format 1A @@ -3014,3 +3024,5 @@ struct DCI_INFO_EXTRACTED { uint64_t ap_si_nl_id:3; }; typedef struct DCI_INFO_EXTRACTED DCI_INFO_EXTRACTED_t; + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..60720e13b706c7112aa40e6a29bb0200200be355 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h @@ -0,0 +1,292 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/dci.h +* \brief typedefs for LTE DCI structures from 36-212, V8.6 2009-03. Limited to 5 MHz formats for the moment.Current LTE compliance V8.6 2009-03. +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#ifndef __DCI_NB_IOT_H__ +#define __DCI_NB_IOT_H__ + +//#ifndef USER_MODE +//#include "PHY/types.h" +//#else +#include <stdint.h> +//#endif + +typedef enum +{ + DCIFormatN0 = 0, + DCIFormatN1, + DCIFormatN1_RA,//is for initial RA procedure (semi-static information) so maybe is not needed + DCIFormatN1_RAR, + DCIFormatN2, + DCIFormatN2_Ind, + DCIFormatN2_Pag, +}DCI_format_NB_IoT_t; + +/// DCI Format Type 0 (180 kHz, 23 bits) +struct DCIFormatN0{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type; + /// Subcarrier indication, 6 bits + uint8_t scind; + /// Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign; + /// Modulation and Coding Scheme, 4 bits + uint8_t mcs; + /// New Data Indicator, 1 bits + uint8_t ndi; + /// Scheduling Delay, 2 bits + uint8_t Scheddly; + /// Repetition Number, 3 bits + uint8_t RepNum; + /// Redundancy version for HARQ (only use 0 and 2), 1 bits + uint8_t rv; + /// DCI subframe repetition Number, 2 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN0 DCIFormatN0_t; + +/// DCI Format Type N1 for User data +struct DCIFormatN1{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits + uint8_t type; + //NPDCCH order indicator (set to 0), 1 bits + uint8_t orderIndicator; + // Scheduling Delay,3 bits + uint8_t Scheddly; + // Resourse Assignment (RU Assignment),3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme,4 bits + uint8_t mcs; + // Repetition Number,4 bits + uint8_t RepNum; + // New Data Indicator,1 bits + uint8_t ndi; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes; + // DCI subframe repetition Number,2 bits + uint8_t DCIRep; +}; + + +typedef struct DCIFormatN1 DCIFormatN1_t; + +/// DCI Format Type N1 for initial RA +struct DCIFormatN1_RA{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator; + // Start number of NPRACH repetiiton, 2 bits + uint8_t Scheddly; + // Subcarrier indication of NPRACH, 6 bits + uint8_t scind; + // All the remainging bits, 13 bits + uint8_t remaingingBits; +}; + +typedef struct DCIFormatN1_RA DCIFormatN1_RA_t; + +/// DCI Format Type N1 for User data +struct DCIFormatN1_RAR{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits + uint8_t type; + //NPDCCH order indicator (set to 0), 1 bits + uint8_t orderIndicator; + // Scheduling Delay,3 bits + uint8_t Scheddly; + // Resourse Assignment (RU Assignment),3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme,4 bits + uint8_t mcs; + // Repetition Number,4 bits + uint8_t RepNum; + // New Data Indicator,1 bits,reserved in the RAR + uint8_t ndi; + // HARQ-ACK resource,4 bits,reserved in the RAR + uint8_t HARQackRes; + // DCI subframe repetition Number,2 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN1_RAR DCIFormatN1_RAR_t; + +// DCI Format Type N2 for direct indication, 15 bits +struct DCIFormatN2_Ind{ + //Flag for paging(1)/direct indication(0), set to 0,1 bits + uint8_t type; + //Direct indication information, 8 bits + uint8_t directIndInf; + // Reserved information bits, 6 bits + uint8_t resInfoBits; +}; + +typedef struct DCIFormatN2_Ind DCIFormatN2_Ind_t; + +// DCI Format Type N2 for Paging, 15 bits +struct DCIFormatN2_Pag{ + //Flag for paging(1)/direct indication(0), set to 1,1 bits + uint8_t type; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs; + // Repetition Number, 4 bits + uint8_t RepNum; + // Reserved 3 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN2_Pag DCIFormatN2_Pag_t; + +typedef union DCI_CONTENT { + // + DCIFormatN0_t DCIN0; + // + DCIFormatN1_t DCIN1; + // + DCIFormatN1_RA_t DCIN1_RA; + // + DCIFormatN1_RAR_t DCIN1_RAR; + // + DCIFormatN2_Ind_t DCIN2_Ind; + // + DCIFormatN2_Pag_t DCIN2_Pag; + + }DCI_CONTENT; + + /*Structure for packing*/ + + struct DCIN0{ + /// DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + /// New Data Indicator, 1 bits + uint8_t ndi:1; + /// Repetition Number, 3 bits + uint8_t RepNum:3; + /// Redundancy version for HARQ (only use 0 and 2), 1 bits + uint8_t rv:1; + /// Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + /// Scheduling Delay, 2 bits + uint8_t Scheddly:2; + /// Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + /// Subcarrier indication, 6 bits + uint8_t scind:6; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN0 DCIN0_t; +#define sizeof_DCIN0_t 23 + +struct DCIN1_RAR{ + // DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes:4; + // New Data Indicator,1 bits + uint8_t ndi:1; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + // Scheduling Delay, 3 bits + uint8_t Scheddly:3; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator:1; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN1_RAR DCIN1_RAR_t; +#define sizeof_DCIN1_RAR_t 23 + +struct DCIN1{ + // DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes:4; + // New Data Indicator,1 bits + uint8_t ndi:1; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + // Scheduling Delay, 3 bits + uint8_t Scheddly:3; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator:1; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN1 DCIN1_t; +#define sizeof_DCIN1_t 23 + +// DCI Format Type N2 for direct indication, 15 bits +struct DCIN2_Ind{ + // Reserved information bits, 6 bits + uint8_t resInfoBits:6; + //Direct indication information, 8 bits + uint8_t directIndInf:8; + //Flag for paging(1)/direct indication(0), set to 0,1 bits + uint8_t type:1; +} __attribute__ ((__packed__));; + +typedef struct DCIN2_Ind DCIN2_Ind_t; +#define sizeof_DCIN2_Ind_t 15 + +// DCI Format Type N2 for Paging, 15 bits +struct DCIN2_Pag{ + // Reserved 3 bits + uint8_t DCIRep:3; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + //Flag for paging(1)/direct indication(0), set to 1,1 bits + uint8_t type:1; +} __attribute__ ((__packed__));; + +typedef struct DCIN2_Pag DCIN2_Pag_t; + +#define sizeof_DCIN2_Pag_t 15 + +#define MAX_DCI_SIZE_BITS_NB_IoT 23 + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index a832b97e70182f31b8fe9c63be7932d077e6c798..47ad00f099d10737c2441d16738d020cf4c644da 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -30,776 +30,23 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" #ifdef DEBUG_DCI_TOOLS -#include "PHY/vars.h" +#include "PHY/phy_vars.h" #endif #include "assertions.h" #include "nfapi_interface.h" //#define DEBUG_HARQ -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/defs.h" -//#define DEBUG_DCI - -uint32_t localRIV2alloc_LUT6[32]; -uint32_t distRIV2alloc_even_LUT6[32]; -uint32_t distRIV2alloc_odd_LUT6[32]; -uint16_t RIV2nb_rb_LUT6[32]; -uint16_t RIV2first_rb_LUT6[32]; -uint16_t RIV_max6=0; - -uint32_t localRIV2alloc_LUT25[512]; -uint32_t distRIV2alloc_even_LUT25[512]; -uint32_t distRIV2alloc_odd_LUT25[512]; -uint16_t RIV2nb_rb_LUT25[512]; -uint16_t RIV2first_rb_LUT25[512]; -uint16_t RIV_max25=0; - - -uint32_t localRIV2alloc_LUT50_0[1600]; -uint32_t localRIV2alloc_LUT50_1[1600]; -uint32_t distRIV2alloc_gap0_even_LUT50_0[1600]; -uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600]; -uint32_t distRIV2alloc_gap0_even_LUT50_1[1600]; -uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600]; -uint32_t distRIV2alloc_gap1_even_LUT50_0[1600]; -uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600]; -uint32_t distRIV2alloc_gap1_even_LUT50_1[1600]; -uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600]; -uint16_t RIV2nb_rb_LUT50[1600]; -uint16_t RIV2first_rb_LUT50[1600]; -uint16_t RIV_max50=0; - -uint32_t localRIV2alloc_LUT100_0[6000]; -uint32_t localRIV2alloc_LUT100_1[6000]; -uint32_t localRIV2alloc_LUT100_2[6000]; -uint32_t localRIV2alloc_LUT100_3[6000]; -uint32_t distRIV2alloc_gap0_even_LUT100_0[6000]; -uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000]; -uint32_t distRIV2alloc_gap0_even_LUT100_1[6000]; -uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000]; -uint32_t distRIV2alloc_gap0_even_LUT100_2[6000]; -uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000]; -uint32_t distRIV2alloc_gap0_even_LUT100_3[6000]; -uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000]; -uint32_t distRIV2alloc_gap1_even_LUT100_0[6000]; -uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000]; -uint32_t distRIV2alloc_gap1_even_LUT100_1[6000]; -uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000]; -uint32_t distRIV2alloc_gap1_even_LUT100_2[6000]; -uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000]; -uint32_t distRIV2alloc_gap1_even_LUT100_3[6000]; -uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000]; -uint16_t RIV2nb_rb_LUT100[6000]; -uint16_t RIV2first_rb_LUT100[6000]; -uint16_t RIV_max100=0; - - -extern uint32_t current_dlsch_cqi; - -// Table 8.6.3-3 36.213 -uint16_t beta_cqi[16] = {0, //reserved - 0, //reserved - 9, //1.125 - 10, //1.250 - 11, //1.375 - 13, //1.625 - 14, //1.750 - 16, //2.000 - 18, //2.250 - 20, //2.500 - 23, //2.875 - 25, //3.125 - 28, //3.500 - 32, //4.000 - 40, //5.000 - 50 - }; //6.250 - -// Table 8.6.3-2 36.213 -uint16_t beta_ri[16] = {10, //1.250 - 13, //1.625 - 16, //2.000 - 20, //2.500 - 25, //3.125 - 32, //4.000 - 40, //5.000 - 50, //6.250 - 64, //8.000 - 80, //10.000 - 101, //12.625 - 127, //15.875 - 160, //20.000 - 0, //reserved - 0, //reserved - 0 - }; //reserved - -// Table 8.6.3-2 36.213 -uint16_t beta_ack[16] = {16, //2.000 - 20, //2.500 - 25, //3.125 - 32, //4.000 - 40, //5.000 - 50, //6.250 - 64, //8.000 - 80, //10.000 - 101, //12.625 - 127, //15.875 - 160, //20.000 - 248, //31.000 - 400, //50.000 - 640, //80.000 - 808 - };//126.00 - -int8_t delta_PUSCH_abs[4] = {-4,-1,1,4}; -int8_t delta_PUSCH_acc[4] = {-1,0,1,3}; - -int8_t *delta_PUCCH_lut = delta_PUSCH_acc; - -void conv_eMTC_rballoc(uint16_t resource_block_coding, - uint32_t N_RB_DL, - uint32_t *rb_alloc) { - - - int narrowband = resource_block_coding>>5; - int RIV = resource_block_coding&31; - int N_NB_DL = N_RB_DL/6; - int i0 = (N_RB_DL>>1) - (3*N_NB_DL); - int first_rb = (6*narrowband)+i0; - int alloc = localRIV2alloc_LUT6[RIV]; - int ind = first_rb>>5; - int ind_mod = first_rb&31; - - if (((N_RB_DL&1) > 0) && (narrowband>=(N_NB_DL>>1))) first_rb++; - rb_alloc[0] = 0; - rb_alloc[1] = 0; - rb_alloc[2] = 0; - rb_alloc[3] = 0; - rb_alloc[ind] = alloc<<ind_mod; - if (ind_mod > 26) rb_alloc[ind+1] = alloc>>(6-(ind_mod-26)); -} - -void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2) -{ - - uint32_t i,shift,subset; - rb_alloc2[0] = 0; - rb_alloc2[1] = 0; - rb_alloc2[2] = 0; - rb_alloc2[3] = 0; - - // printf("N_RB_DL %d, ra_header %d, rb_alloc %x\n",N_RB_DL,ra_header,rb_alloc); - - switch (N_RB_DL) { - - case 6: - rb_alloc2[0] = rb_alloc&0x3f; - break; - - case 25: - if (ra_header == 0) {// Type 0 Allocation - - for (i=12; i>0; i--) { - if ((rb_alloc&(1<<i)) != 0) - rb_alloc2[0] |= (3<<((2*(12-i)))); - - // printf("rb_alloc2 (type 0) %x\n",rb_alloc2); - } - - if ((rb_alloc&1) != 0) - rb_alloc2[0] |= (1<<24); - } else { - subset = rb_alloc&1; - shift = (rb_alloc>>1)&1; - - for (i=0; i<11; i++) { - if ((rb_alloc&(1<<(i+2))) != 0) - rb_alloc2[0] |= (1<<(2*i)); - - //printf("rb_alloc2 (type 1) %x\n",rb_alloc2); - } - - if ((shift == 0) && (subset == 1)) - rb_alloc2[0]<<=1; - else if ((shift == 1) && (subset == 0)) - rb_alloc2[0]<<=4; - else if ((shift == 1) && (subset == 1)) - rb_alloc2[0]<<=3; - } - - break; - - case 50: - AssertFatal(ra_header==0,"resource type 1 not supported for N_RB_DL=50\n"); - - for (i=16; i>0; i--) { - if ((rb_alloc&(1<<i)) != 0) - rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32)); - } - - // bit mask across - if ((rb_alloc2[0]>>31)==1) - rb_alloc2[1] |= 1; - - if ((rb_alloc&1) != 0) - rb_alloc2[1] |= (3<<16); - break; - - case 100: - AssertFatal(ra_header==0,"resource type 1 not supported for N_RB_DL=100\n"); - for (i=0; i<25; i++) { - if ((rb_alloc&(1<<(24-i))) != 0) - rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32)); - - // printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i)); - } - - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", N_RB_DL); - DevParam (N_RB_DL, 0, 0); - break; - } - -} - - - -uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL) -{ - - uint32_t nprb=0,i; - - switch (N_RB_DL) { - case 6: - for (i=0; i<6; i++) { - if ((rb_alloc&(1<<i)) != 0) - nprb += 1; - } - - break; - - case 25: - if (ra_header == 0) {// Type 0 Allocation - - for (i=12; i>0; i--) { - if ((rb_alloc&(1<<i)) != 0) - nprb += 2; - } - - if ((rb_alloc&1) != 0) - nprb += 1; - } else { - for (i=0; i<11; i++) { - if ((rb_alloc&(1<<(i+2))) != 0) - nprb += 1; - } - } - - break; - - case 50: - if (ra_header == 0) {// Type 0 Allocation - - for (i=0; i<16; i++) { - if ((rb_alloc&(1<<(16-i))) != 0) - nprb += 3; - } - - if ((rb_alloc&1) != 0) - nprb += 2; - - } else { - for (i=0; i<17; i++) { - if ((rb_alloc&(1<<(i+2))) != 0) - nprb += 1; - } - } - - break; - - case 100: - if (ra_header == 0) {// Type 0 Allocation - - for (i=0; i<25; i++) { - if ((rb_alloc&(1<<(24-i))) != 0) - nprb += 4; - } - } else { - for (i=0; i<25; i++) { - if ((rb_alloc&(1<<(i+2))) != 0) - nprb += 1; - } - } - - break; - - default: - LOG_E(PHY,"Invalide N_RB_DL %d\n", N_RB_DL); - DevParam (N_RB_DL, 0, 0); - break; - } - - return(nprb); -} - -uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) -{ - - uint16_t RIV; - - if (Lcrbs<=(1+(N_RB_DL>>1))) - RIV = (N_RB_DL*(Lcrbs-1)) + RBstart; - else - RIV = (N_RB_DL*(N_RB_DL+1-Lcrbs)) + (N_RB_DL-1-RBstart); - - return(RIV); -} - -// Convert a DCI Format 1C RIV to a Format 1A RIV -// This extracts the start and length in PRBs from the 1C rballoc and -// recomputes the RIV as if it were the 1A rballoc - -uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) { - - int NpDLVRB,N_RB_step,LpCRBsm1,RBpstart; - - switch (N_RB_DL) { - - case 6: // N_RB_step = 2, NDLVRB = 6, NpDLVRB = 3 - NpDLVRB = 3; - N_RB_step = 2; - break; - case 25: // N_RB_step = 2, NDLVRB = 24, NpDLVRB = 12 - NpDLVRB = 12; - N_RB_step = 2; - break; - case 50: // N_RB_step = 4, NDLVRB = 46, NpDLVRB = 11 - NpDLVRB = 11; - N_RB_step = 4; - break; - case 100: // N_RB_step = 4, NDLVRB = 96, NpDLVRB = 24 - NpDLVRB = 24; - N_RB_step = 4; - break; - default: - NpDLVRB = 24; - N_RB_step = 4; - break; - } - - // This is the 1C part from 7.1.6.3 in 36.213 - LpCRBsm1 = rballoc/NpDLVRB; - // printf("LpCRBs = %d\n",LpCRBsm1+1); - - if (LpCRBsm1 <= (NpDLVRB/2)) { - RBpstart = rballoc % NpDLVRB; - } - else { - LpCRBsm1 = NpDLVRB-LpCRBsm1; - RBpstart = NpDLVRB-(rballoc%NpDLVRB); - } - // printf("RBpstart %d\n",RBpstart); - return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1))); - -} - -uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { - - int offset; - - switch (N_RB_DL) { - - case 6: - // N_RB_DL = tildeN_RB_DL = 6 - // Ngap = 4 , P=1, Nrow = 2, Nnull = 2 - - switch (vrb) { - case 0: // even: 0->0, 1->2, odd: 0->3, 1->5 - case 1: - return ((3*odd_slot) + 2*(vrb&3))%6; - break; - case 2: // even: 2->3, 3->5, odd: 2->0, 3->2 - case 3: - return ((3*odd_slot) + 2*(vrb&3) + 5)%6; - break; - case 4: // even: 4->1, odd: 4->4 - return ((3*odd_slot) + 1)%6; - case 5: // even: 5->4, odd: 5->1 - return ((3*odd_slot) + 4)%6; - break; - } - break; - - case 15: - if (vrb<12) { - if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11 - return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); - else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13 - return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); - } - if (vrb==12) - return (3+(7*odd_slot)) % 14; - if (vrb==13) - return (10+(7*odd_slot)) % 14; - return 14; - break; - - case 25: - return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); - break; - - case 50: // P=3 - if (Ngap==0) { - // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27 - if (vrb>=23) - offset=4; - else - offset=0; - if (vrb<44) { - if ((vrb&3)>=2) - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; - else - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; - } - if (vrb==44) // even: 44->11, odd: 45->34 - return offset+((23*odd_slot) + 22-12+1); - if (vrb==45) // even: 45->10, odd: 45->33 - return offset+((23*odd_slot) + 22+12); - if (vrb==46) - return offset+46+((23*odd_slot) + 23-12+1) % 46; - if (vrb==47) - return offset+46+((23*odd_slot) + 23+12) % 46; - if (vrb==48) - return offset+46+((23*odd_slot) + 23-12+1) % 46; - if (vrb==49) - return offset+46+((23*odd_slot) + 23+12) % 46; - } - else { - // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27 - if (vrb>=9) - offset=18; - else - offset=0; - - if (vrb<12) { - if ((vrb&3)>=2) - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; - else - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; - } - else { - return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); - } - } - break; - case 75: - // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0 - if (Ngap ==0) { - return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); - } else { - // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); - } - break; - case 100: - // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0 - if (Ngap ==0) { - return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); - } else { - // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); - } - break; - default: - LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL); - return 0; - } - return 0; - -} - - -void generate_RIV_tables() -{ - - // 6RBs localized RIV - uint8_t Lcrbs,RBstart; - uint16_t RIV; - uint32_t alloc0,allocdist0_0_even,allocdist0_0_odd,allocdist0_1_even,allocdist0_1_odd; - uint32_t alloc1,allocdist1_0_even,allocdist1_0_odd,allocdist1_1_even,allocdist1_1_odd; - uint32_t alloc2,allocdist2_0_even,allocdist2_0_odd,allocdist2_1_even,allocdist2_1_odd; - uint32_t alloc3,allocdist3_0_even,allocdist3_0_odd,allocdist3_1_even,allocdist3_1_odd; - uint32_t nVRB,nVRB_even_dist,nVRB_odd_dist; - - for (RBstart=0; RBstart<6; RBstart++) { - alloc0 = 0; - allocdist0_0_even = 0; - allocdist0_0_odd = 0; - for (Lcrbs=1; Lcrbs<=(6-RBstart); Lcrbs++) { - //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); - nVRB = Lcrbs-1+RBstart; - alloc0 |= (1<<nVRB); - allocdist0_0_even |= (1<<get_prb(6,0,nVRB,0)); - allocdist0_0_odd |= (1<<get_prb(6,1,nVRB,0)); - RIV=computeRIV(6,RBstart,Lcrbs); - - if (RIV>RIV_max6) - RIV_max6 = RIV; - - // printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs); - localRIV2alloc_LUT6[RIV] = alloc0; - distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even; - distRIV2alloc_odd_LUT6[RIV] = allocdist0_0_odd; - RIV2nb_rb_LUT6[RIV] = Lcrbs; - RIV2first_rb_LUT6[RIV] = RBstart; - } - } - - - for (RBstart=0; RBstart<25; RBstart++) { - alloc0 = 0; - allocdist0_0_even = 0; - allocdist0_0_odd = 0; - for (Lcrbs=1; Lcrbs<=(25-RBstart); Lcrbs++) { - nVRB = Lcrbs-1+RBstart; - //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); - alloc0 |= (1<<nVRB); - allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0)); - allocdist0_0_odd |= (1<<get_prb(25,1,nVRB,0)); - - //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd); - RIV=computeRIV(25,RBstart,Lcrbs); - - if (RIV>RIV_max25) - RIV_max25 = RIV;; - - - localRIV2alloc_LUT25[RIV] = alloc0; - distRIV2alloc_even_LUT25[RIV] = allocdist0_0_even; - distRIV2alloc_odd_LUT25[RIV] = allocdist0_0_odd; - RIV2nb_rb_LUT25[RIV] = Lcrbs; - RIV2first_rb_LUT25[RIV] = RBstart; - } - } - - - for (RBstart=0; RBstart<50; RBstart++) { - alloc0 = 0; - alloc1 = 0; - allocdist0_0_even=0; - allocdist1_0_even=0; - allocdist0_0_odd=0; - allocdist1_0_odd=0; - allocdist0_1_even=0; - allocdist1_1_even=0; - allocdist0_1_odd=0; - allocdist1_1_odd=0; - - for (Lcrbs=1; Lcrbs<=(50-RBstart); Lcrbs++) { - - nVRB = Lcrbs-1+RBstart; - - - if (nVRB<32) - alloc0 |= (1<<nVRB); - else - alloc1 |= (1<<(nVRB-32)); - - // Distributed Gap1, even slot - nVRB_even_dist = get_prb(50,0,nVRB,0); - if (nVRB_even_dist<32) - allocdist0_0_even |= (1<<nVRB_even_dist); - else - allocdist1_0_even |= (1<<(nVRB_even_dist-32)); - - // Distributed Gap1, odd slot - nVRB_odd_dist = get_prb(50,1,nVRB,0); - if (nVRB_odd_dist<32) - allocdist0_0_odd |= (1<<nVRB_odd_dist); - else - allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); - - // Distributed Gap2, even slot - nVRB_even_dist = get_prb(50,0,nVRB,1); - if (nVRB_even_dist<32) - allocdist0_1_even |= (1<<nVRB_even_dist); - else - allocdist1_1_even |= (1<<(nVRB_even_dist-32)); - - // Distributed Gap2, odd slot - nVRB_odd_dist = get_prb(50,1,nVRB,1); - if (nVRB_odd_dist<32) - allocdist0_1_odd |= (1<<nVRB_odd_dist); - else - allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); - - RIV=computeRIV(50,RBstart,Lcrbs); - - if (RIV>RIV_max50) - RIV_max50 = RIV; - - // printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs); - localRIV2alloc_LUT50_0[RIV] = alloc0; - localRIV2alloc_LUT50_1[RIV] = alloc1; - distRIV2alloc_gap0_even_LUT50_0[RIV] = allocdist0_0_even; - distRIV2alloc_gap0_even_LUT50_1[RIV] = allocdist1_0_even; - distRIV2alloc_gap0_odd_LUT50_0[RIV] = allocdist0_0_odd; - distRIV2alloc_gap0_odd_LUT50_1[RIV] = allocdist1_0_odd; - distRIV2alloc_gap1_even_LUT50_0[RIV] = allocdist0_1_even; - distRIV2alloc_gap1_even_LUT50_1[RIV] = allocdist1_1_even; - distRIV2alloc_gap1_odd_LUT50_0[RIV] = allocdist0_1_odd; - distRIV2alloc_gap1_odd_LUT50_1[RIV] = allocdist1_1_odd; - RIV2nb_rb_LUT50[RIV] = Lcrbs; - RIV2first_rb_LUT50[RIV] = RBstart; - } - } - - - for (RBstart=0; RBstart<100; RBstart++) { - alloc0 = 0; - alloc1 = 0; - alloc2 = 0; - alloc3 = 0; - allocdist0_0_even=0; - allocdist1_0_even=0; - allocdist2_0_even=0; - allocdist3_0_even=0; - allocdist0_0_odd=0; - allocdist1_0_odd=0; - allocdist2_0_odd=0; - allocdist3_0_odd=0; - allocdist0_1_even=0; - allocdist1_1_even=0; - allocdist2_1_even=0; - allocdist3_1_even=0; - allocdist0_1_odd=0; - allocdist1_1_odd=0; - allocdist2_1_odd=0; - allocdist3_1_odd=0; - - for (Lcrbs=1; Lcrbs<=(100-RBstart); Lcrbs++) { - - nVRB = Lcrbs-1+RBstart; - - if (nVRB<32) - alloc0 |= (1<<nVRB); - else if (nVRB<64) - alloc1 |= (1<<(nVRB-32)); - else if (nVRB<96) - alloc2 |= (1<<(nVRB-64)); - else - alloc3 |= (1<<(nVRB-96)); - - // Distributed Gap1, even slot - nVRB_even_dist = get_prb(100,0,nVRB,0); - -// if ((RBstart==0) && (Lcrbs<=8)) -// printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist); - - - if (nVRB_even_dist<32) - allocdist0_0_even |= (1<<nVRB_even_dist); - else if (nVRB_even_dist<64) - allocdist1_0_even |= (1<<(nVRB_even_dist-32)); - else if (nVRB_even_dist<96) - allocdist2_0_even |= (1<<(nVRB_even_dist-64)); - else - allocdist3_0_even |= (1<<(nVRB_even_dist-96)); -/* if ((RBstart==0) && (Lcrbs<=8)) - printf("rballoc =>(%08x.%08x.%08x.%08x)\n", - allocdist0_0_even, - allocdist1_0_even, - allocdist2_0_even, - allocdist3_0_even - ); -*/ - // Distributed Gap1, odd slot - nVRB_odd_dist = get_prb(100,1,nVRB,0); - if (nVRB_odd_dist<32) - allocdist0_0_odd |= (1<<nVRB_odd_dist); - else if (nVRB_odd_dist<64) - allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); - else if (nVRB_odd_dist<96) - allocdist2_0_odd |= (1<<(nVRB_odd_dist-64)); - else - allocdist3_0_odd |= (1<<(nVRB_odd_dist-96)); - - - // Distributed Gap2, even slot - nVRB_even_dist = get_prb(100,0,nVRB,1); - if (nVRB_even_dist<32) - allocdist0_1_even |= (1<<nVRB_even_dist); - else if (nVRB_even_dist<64) - allocdist1_1_even |= (1<<(nVRB_even_dist-32)); - else if (nVRB_even_dist<96) - allocdist2_1_even |= (1<<(nVRB_even_dist-64)); - else - allocdist3_1_even |= (1<<(nVRB_even_dist-96)); - - - // Distributed Gap2, odd slot - nVRB_odd_dist = get_prb(100,1,nVRB,1); - if (nVRB_odd_dist<32) - allocdist0_1_odd |= (1<<nVRB_odd_dist); - else if (nVRB_odd_dist<64) - allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); - else if (nVRB_odd_dist<96) - allocdist2_1_odd |= (1<<(nVRB_odd_dist-64)); - else - allocdist3_1_odd |= (1<<(nVRB_odd_dist-96)); - - - RIV=computeRIV(100,RBstart,Lcrbs); - - if (RIV>RIV_max100) - RIV_max100 = RIV; - - // printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs); - localRIV2alloc_LUT100_0[RIV] = alloc0; - localRIV2alloc_LUT100_1[RIV] = alloc1; - localRIV2alloc_LUT100_2[RIV] = alloc2; - localRIV2alloc_LUT100_3[RIV] = alloc3; - distRIV2alloc_gap0_even_LUT100_0[RIV] = allocdist0_0_even; - distRIV2alloc_gap0_even_LUT100_1[RIV] = allocdist1_0_even; - distRIV2alloc_gap0_even_LUT100_2[RIV] = allocdist2_0_even; - distRIV2alloc_gap0_even_LUT100_3[RIV] = allocdist3_0_even; - distRIV2alloc_gap0_odd_LUT100_0[RIV] = allocdist0_0_odd; - distRIV2alloc_gap0_odd_LUT100_1[RIV] = allocdist1_0_odd; - distRIV2alloc_gap0_odd_LUT100_2[RIV] = allocdist2_0_odd; - distRIV2alloc_gap0_odd_LUT100_3[RIV] = allocdist3_0_odd; - distRIV2alloc_gap1_even_LUT100_0[RIV] = allocdist0_1_even; - distRIV2alloc_gap1_even_LUT100_1[RIV] = allocdist1_1_even; - distRIV2alloc_gap1_even_LUT100_2[RIV] = allocdist2_1_even; - distRIV2alloc_gap1_even_LUT100_3[RIV] = allocdist3_1_even; - distRIV2alloc_gap1_odd_LUT100_0[RIV] = allocdist0_1_odd; - distRIV2alloc_gap1_odd_LUT100_1[RIV] = allocdist1_1_odd; - distRIV2alloc_gap1_odd_LUT100_2[RIV] = allocdist2_1_odd; - distRIV2alloc_gap1_odd_LUT100_3[RIV] = allocdist3_1_odd; - - RIV2nb_rb_LUT100[RIV] = Lcrbs; - RIV2first_rb_LUT100[RIV] = RBstart; - } - } -} - -// Ngap = 3, N_VRB_DL=6, P=1, N_row=2, N_null=4*2-6=2 -// permutation for even slots : -// n_PRB'(0,2,4) = (0,1,2), n_PRB'(1,3,5) = (4,5,6) -// n_PRB''(0,1,2,3) = (0,2,4,6) -// => n_tilde_PRB(5) = (4) -// n_tilde_PRB(4) = (1) -// n_tilde_PRB(2,3) = (3,5) -// n_tilde_PRB(0,1) = (0,2) +#include "LAYER2/MAC/mac.h" +//#define DEBUG_DCI +#include "dci_tools_common_extern.h" +#include "transport_proto.h" int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) { @@ -840,25 +87,8 @@ int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) } -uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci) -{ - - return(localRIV2alloc_LUT25[rb_alloc_dci]); - -} - -/* -uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti) -{ - unsigned char UE_id; - // find the UE_index corresponding to rnti - UE_id = find_ue(rnti,RC.eNB[Mod_id][CC_id]); - DevAssert( UE_id != (unsigned char)-1 ); - return(RC.eNB[Mod_id][CC_id]->transmission_mode[UE_id]); -} -*/ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) { @@ -2257,6 +1487,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t #endif +//printf("DCI %d.%d rnti %d harq %d TBS %d\n", frame, subframe, rel8->rnti, rel8->harq_process, dlsch0_harq->TBS); #if T_TRACER if (dlsch0->active) T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame), T_INT(subframe), @@ -2767,11 +1998,12 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7) ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; - LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d\n", + LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d ulsch_pdu:rvidx:%d\n", eNB->Mod_id,harq_pid,frame,subframe, ulsch->harq_processes[harq_pid]->n_DMRS2, ulsch->harq_processes[harq_pid]->n_DMRS, - ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status); + ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status, + ulsch_pdu->ulsch_pdu_rel8.redundancy_version); ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version; if(ulsch_pdu->ulsch_pdu_rel8.modulation_type!=0) @@ -2819,6386 +2051,4 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->harq_processes[harq_pid]->round); } -int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) -{ - switch (dci->format) { - - case format0: // This is an UL SCH allocation so nothing here, inform MAC - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config>0)) - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format0 (TDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, - ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); - break; - - case 25: - LOG_D(PHY,"DCI format0 (TDD1-6, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, - ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); - break; - - case 50: - LOG_D(PHY,"DCI format0 (TDD1-6, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, - ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); - break; - - case 100: - LOG_D(PHY,"DCI format0 (TDD1-6, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, - ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - else if (frame_parms->frame_type == FDD) - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format0 (FDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); - break; - - case 25: - LOG_D(PHY,"DCI format0 (FDD, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); - break; - - case 50: - LOG_D(PHY,"DCI format0 (FDD, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); - break; - - case 100: - LOG_D(PHY,"DCI format0 (FDD, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu[0])[0], - ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->hopping, - ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cshift, - ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - else - LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); - - break; - - case format1: - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config>0)) - - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format1 (TDD 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai); - break; - - case 25: - LOG_D(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai); - break; - - case 50: - LOG_D(PHY,"DCI format1 (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->dai); - break; - - case 100: - LOG_D(PHY,"DCI format1 (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->dai); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - else if (frame_parms->frame_type == FDD) { - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format1 (FDD, 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 25: - LOG_D(PHY,"DCI format1 (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 50: - LOG_D(PHY,"DCI format1 (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 100: - LOG_D(PHY,"DCI format1 (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } - - else - LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); - - break; - - case format1A: // This is DLSCH allocation for control traffic - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config>0)) { - switch (frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format1A (TDD1-6, 1_5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); - LOG_D(PHY,"DAI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); - break; - - case 25: - LOG_D(PHY,"DCI format1A (TDD1-6, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %d (NB_RB %d)\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); - LOG_D(PHY,"DAI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); - break; - - case 50: - LOG_D(PHY,"DCI format1A (TDD1-6, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); - LOG_D(PHY,"DAI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); - break; - - case 100: - LOG_D(PHY,"DCI format1A (TDD1-6, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); - LOG_D(PHY,"DAI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - - } else if (frame_parms->frame_type == FDD) { - switch (frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format1A(FDD, 1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 25: - LOG_D(PHY,"DCI format1A(FDD, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 50: - LOG_D(PHY,"DCI format1A(FDD, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 100: - LOG_D(PHY,"DCI format1A(FDD, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); - LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs); - LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); - LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi); - LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rv); - LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } - - break; - - case format1C: // This is DLSCH allocation for control traffic - switch (frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format1C (1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n", - ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]); - LOG_D(PHY,"MCS %d\n",((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->mcs); - break; - - case 25: - LOG_D(PHY,"DCI format1C (5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[conv_1C_RIV(((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,25)]); - LOG_D(PHY,"MCS %d\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->mcs); - break; - - case 50: - LOG_D(PHY,"DCI format1C (10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"Ngap %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->Ngap); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,50)]); - LOG_D(PHY,"MCS %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->mcs); - break; - - case 100: - LOG_D(PHY,"DCI format1C (20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); - LOG_D(PHY,"Ngap %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->Ngap); - LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,100)]); - LOG_D(PHY,"MCS %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->mcs); - break; - - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - - - break; - - case format2: - - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config>0)) { - if (frame_parms->nb_antenna_ports_eNB == 2) { - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi - ); - break; - - case 25: - LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - case 50: - LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - case 100: - LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi - ); - break; - - case 25: - LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - case 50: - LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - case 100: - LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } - } else if (frame_parms->frame_type == FDD) { - if (frame_parms->nb_antenna_ports_eNB == 2) { - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format2 2 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 25: - - LOG_D(PHY,"DCI format2 2 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, swap %d, TPMI %d, TPC %d\n", - - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 50: - LOG_D(PHY,"DCI format2 2 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 100: - LOG_D(PHY,"DCI format2 2 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - switch(frame_parms->N_RB_DL) { - - case 6: - LOG_D(PHY,"DCI format2 4 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 25: - LOG_D(PHY,"DCI format2 4 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 50: - LOG_D(PHY,"DCI format2 4 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 100: - LOG_D(PHY,"DCI format2 4 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } - } - - else - LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); - - break; - - case format2A: - - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config>0)) { - if (frame_parms->nb_antenna_ports_eNB == 2) { - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format2A 2 antennas (FDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap - ); - break; - - case 25: - LOG_D(PHY,"DCI format2A 2 antennas (FDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); - break; - - case 50: - LOG_D(PHY,"DCI format2A 2 antennas (FDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); - break; - - case 100: - LOG_D(PHY,"DCI format2A 2 antennas (FDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format2A 4 antennas (TDD 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi - ); - break; - - case 25: - LOG_D(PHY,"DCI format2A 4 antennas (TDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - case 50: - LOG_D(PHY,"DCI format2A 4 antennas (TDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - case 100: - LOG_D(PHY,"DCI format2A 4 antennas (TDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } - } else if (frame_parms->frame_type == FDD) { - if (frame_parms->nb_antenna_ports_eNB == 2) { - switch(frame_parms->N_RB_DL) { - case 6: - LOG_D(PHY,"DCI format2A 2 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", - dci->rnti, - ((uint32_t*)&dci->dci_pdu)[0], - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 25: - LOG_D(PHY,"DCI format2A 2 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 50: - LOG_D(PHY,"DCI format2A 2 antennas (FDD, 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 100: - LOG_D(PHY,"DCI format2A 2 antennas (FDD, 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - switch(frame_parms->N_RB_DL) { - - case 6: - LOG_D(PHY,"DCI format2A 4 antennas (FDD, 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 25: - LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 50: - LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - case 100: - LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", - dci->rnti, - ((uint64_t*)&dci->dci_pdu)[0], - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - } - } - - else - LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); - - break; - - case format1E_2A_M10PRB: - - LOG_D(PHY,"DCI format1E_2A_M10PRB, rnti %x (%8x): harq_pid %d, rah %d, rb_alloc %x, mcs %d, rv %d, tpmi %d, ndi %d, dl_power_offset %d\n", - dci->rnti, - ((uint32_t *)&dci->dci_pdu)[0], - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->harq_pid, - //((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tb_swap, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rah, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rballoc, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->mcs, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rv, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tpmi, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->ndi, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->dl_power_off - ); - - break; - - default: - LOG_E(PHY,"dci_tools.c: dump_dci, unknown format %d\n",dci->format); - return(-1); - } - - return(0); -} - -void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) -{ - uint8_t harq_pid=0; - uint32_t rballoc=0; - uint8_t vrb_type=0; - uint8_t mcs=0; - uint8_t rv=0; - uint8_t ndi=0; - uint8_t TPC=0; - - uint8_t dai=0; - - switch (N_RB_DL) { - case 6: - if (frame_type == TDD) { - vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; - // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } - break; - - case 25: - - if (frame_type == TDD) { - vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai; - //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } - - break; - - case 50: - if (frame_type == TDD) { - vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai; - // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, vrb_type %d, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,vrb_type,rballoc,ndi,rv,TPC); - } - break; - - case 100: - if (frame_type == TDD) { - vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai; - // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } - break; - } - - pdci_info_extarcted->vrb_type = vrb_type; - pdci_info_extarcted->mcs1 = mcs; - pdci_info_extarcted->rballoc = rballoc; - pdci_info_extarcted->rv1 = rv; - pdci_info_extarcted->ndi1 = ndi; - pdci_info_extarcted->TPC = TPC; - pdci_info_extarcted->harq_pid = harq_pid; - pdci_info_extarcted->dai = dai; -} - -void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) -{ - - uint32_t rballoc=0; - uint8_t mcs=0; - - switch (N_RB_DL) { - case 6: - mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); - - break; - - case 25: - mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); - - break; - - case 50: - mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6); - - break; - - case 100: - mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6); - break; - - default: - AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",N_RB_DL); - break; - } - - pdci_info_extarcted->mcs1 = mcs; - pdci_info_extarcted->rballoc = rballoc; -} - -void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) -{ - - uint32_t rballoc=0; - uint8_t mcs=0; - uint8_t rah=0; - uint8_t rv=0; - uint8_t TPC=0; - uint8_t ndi=0; - uint8_t harq_pid=0; - - switch (N_RB_DL) { - case 6: - if (frame_type == TDD) { - mcs = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - - case 25: - if (frame_type == TDD) { - mcs = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - - case 50: - if (frame_type == TDD) { - mcs = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - - case 100: - if (frame_type == TDD) { - mcs = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - } - - pdci_info_extarcted->mcs1 = mcs; - pdci_info_extarcted->rah = rah; - pdci_info_extarcted->rballoc = rballoc; - pdci_info_extarcted->rv1 = rv; - pdci_info_extarcted->TPC = TPC; - pdci_info_extarcted->ndi1 = ndi; - pdci_info_extarcted->harq_pid = harq_pid; - -} - -void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) -{ - - uint32_t rballoc=0; - uint8_t rah=0; - uint8_t mcs1=0; - uint8_t mcs2=0; - uint8_t rv1=0; - uint8_t rv2=0; - uint8_t ndi1=0; - uint8_t ndi2=0; - uint8_t tbswap=0; - uint8_t tpmi=0; - uint8_t harq_pid=0; - uint8_t TPC=0; - - switch (N_RB_DL) { - - case 6: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - } - } else { - LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); - } - - break; - - case 25: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - } - } else { - LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); - } - - break; - - case 50: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; - } - } else { - LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); - } - - break; - - case 100: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; - } else { - rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; - mcs1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; - harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->TPC; - ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; - } - } else { - LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); - } - - break; - } - - pdci_info_extarcted->rah = rah; - pdci_info_extarcted->mcs1 = mcs1; - pdci_info_extarcted->mcs2 = mcs2; - pdci_info_extarcted->rv1 = rv1; - pdci_info_extarcted->rv2 = rv2; - pdci_info_extarcted->harq_pid = harq_pid; - pdci_info_extarcted->rballoc = rballoc; - pdci_info_extarcted->tb_swap = tbswap; - pdci_info_extarcted->tpmi = tpmi; - pdci_info_extarcted->TPC = TPC; - pdci_info_extarcted->ndi1 = ndi1; - pdci_info_extarcted->ndi2 = ndi2; - -} - -void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) -{ - - uint32_t rballoc=0; - uint8_t rah=0; - uint8_t mcs1=0; - uint8_t mcs2=0; - uint8_t rv1=0; - uint8_t rv2=0; - uint8_t ndi1=0; - uint8_t ndi2=0; - uint8_t tbswap=0; - uint8_t tpmi=0; - uint8_t harq_pid=0; - uint8_t TPC=0; - - AssertFatal( (nb_antenna_ports_eNB == 2) || (nb_antenna_ports_eNB == 4), "unsupported nb_antenna_ports_eNB %d\n", nb_antenna_ports_eNB); - switch (N_RB_DL) { - - case 6: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->TPC; - } - } - - break; - - case 25: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->TPC; - } - } - break; - - case 50: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->TPC; - } - } - - break; - - case 100: - if (nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; - TPC = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC; - } - } else if (nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->TPC; - } else { - mcs1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi; - TPC = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->TPC; - } - } - - break; - } - - pdci_info_extarcted->mcs1 = mcs1; - pdci_info_extarcted->mcs2 = mcs2; - pdci_info_extarcted->rballoc = rballoc; - pdci_info_extarcted->rah = rah; - pdci_info_extarcted->rv1 = rv1; - pdci_info_extarcted->rv2 = rv2; - pdci_info_extarcted->ndi1 = ndi1; - pdci_info_extarcted->ndi2 = ndi2; - pdci_info_extarcted->harq_pid = harq_pid; - pdci_info_extarcted->tb_swap = tbswap; - pdci_info_extarcted->TPC = TPC; - pdci_info_extarcted->tpmi = tpmi; -} - -int check_dci_format1_1a_coherency(DCI_format_t dci_format, - uint8_t N_RB_DL, - uint16_t rnti, - uint16_t tc_rnti, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint32_t frame, - uint8_t subframe, - DCI_INFO_EXTRACTED_t *pdci_info_extarcted, - LTE_DL_UE_HARQ_t *pdlsch0_harq) -{ - uint8_t harq_pid = pdci_info_extarcted->harq_pid; - uint32_t rballoc = pdci_info_extarcted->rballoc; - uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t TPC = pdci_info_extarcted->TPC; - uint8_t rah = pdci_info_extarcted->rah; -#ifdef DEBUG_DCI - uint8_t rv1 = pdci_info_extarcted->rv1; - uint8_t ndi1 = pdci_info_extarcted->ndi1; -#endif - - uint8_t NPRB = 0; - long long int RIV_max = 0; - -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, subframe, dci_format); - LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti %x\n", rnti); - LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid %d\n", harq_pid); - LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); - LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); - LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); - LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); - LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); - LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); -#endif - - - // I- check dci content minimum coherency - if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0) - { - return(0); - } - - if(harq_pid>=8) - { - LOG_I(PHY,"bad harq id \n"); - return(0); - } - - if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) ) - { - LOG_I(PHY,"bad dci format \n"); - return(0); - } - - - if( mcs1 > 28) - { - if(pdlsch0_harq->round == 0) - { - LOG_I(PHY,"bad dci mcs + round \n"); - return(0); - } - - if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) - { - LOG_I(PHY,"bad dci mcs + rnti \n"); - return(0); - } - } - - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) - { - NPRB = (TPC&1) + 2; - switch (N_RB_DL) { - case 6: - RIV_max = RIV_max6; - break; - case 25: - RIV_max = RIV_max25; - break; - case 50: - RIV_max = RIV_max50; - break; - case 100: - RIV_max = RIV_max100; - break; - } - } - else - { - switch (N_RB_DL) { - case 6: - NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; - if(rah) - RIV_max = RIV_max6; - else - RIV_max = 0x3F; - break; - case 25: - NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; - if(rah) - RIV_max = RIV_max25; - else - RIV_max = 0x1FFF; - break; - case 50: - NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; - if(rah) - RIV_max = RIV_max50; - else - RIV_max = 0x1FFFF; - break; - case 100: - NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; - if(rah) - RIV_max = RIV_max100; - else - RIV_max = 0x1FFFFFF; - break; - } - } - - - if(dci_format == format1) - { - NPRB = conv_nprb(rah, rballoc, N_RB_DL); - } - - - if(rballoc > RIV_max) - { - LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); - // DCI false detection - return(0); - } - - if(NPRB == 0) - { - // DCI false detection - LOG_I(PHY,"bad NPRB = 0 \n"); - return(0); - } - - // this a retransmission - if(pdlsch0_harq->round>0) - { - // compare old TBS to new TBS - if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1])) - { - // this is an eNB issue - // retransmisison but old and new TBS are different !!! - // work around, consider it as a new transmission - LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n"); - pdlsch0_harq->round = 0; - //return(0); // ?? to cross check - } - } - - return(1); -} - -int check_dci_format1c_coherency(uint8_t N_RB_DL, - DCI_INFO_EXTRACTED_t *pdci_info_extarcted, - uint16_t rnti, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - LTE_DL_UE_HARQ_t *pdlsch0_harq) -{ - uint32_t rballoc = pdci_info_extarcted->rballoc; - - uint8_t NPRB = 0; - uint32_t RIV_max = 0; - - // I- check dci content minimum coherency - - if((rnti!=si_rnti) && (rnti!=p_rnti) && (rnti!=ra_rnti)) - return(0); - - switch (N_RB_DL) { - case 6: - NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; - RIV_max = RIV_max6; - break; - case 25: - NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; - RIV_max = RIV_max25; - break; - case 50: - NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; - RIV_max = RIV_max50; - break; - case 100: - NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; - RIV_max = RIV_max100; - break; - } - - if(rballoc > RIV_max) - { - // DCI false detection - return(0); - } - - if(NPRB == 0) - { - // DCI false detection - return(0); - } - - return(1); -} - -int check_dci_format2_2a_coherency(DCI_format_t dci_format, - uint8_t N_RB_DL, - DCI_INFO_EXTRACTED_t *pdci_info_extarcted, - uint16_t rnti, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - LTE_DL_UE_HARQ_t *pdlsch0_harq, - LTE_DL_UE_HARQ_t *pdlsch1_harq) -{ - uint8_t rah = pdci_info_extarcted->rah; - uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t mcs2 = pdci_info_extarcted->mcs2; - uint8_t rv1 = pdci_info_extarcted->rv1; - uint8_t rv2 = pdci_info_extarcted->rv2; - uint8_t harq_pid = pdci_info_extarcted->harq_pid; - uint32_t rballoc = pdci_info_extarcted->rballoc; - -#ifdef DEBUG_DCI - uint8_t ndi1 = pdci_info_extarcted->ndi1; - uint8_t ndi2 = pdci_info_extarcted->ndi2; -#endif - - uint8_t NPRB = 0; - long long RIV_max = 0; - -#ifdef DEBUG_DCI - LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format); - LOG_I(PHY, "extarcted dci - rnti %d \n", rnti); - LOG_I(PHY, "extarcted dci - rah %d \n", rah); - LOG_I(PHY, "extarcted dci - mcs1 %d \n", mcs1); - LOG_I(PHY, "extarcted dci - mcs2 %d \n", mcs2); - LOG_I(PHY, "extarcted dci - rv1 %d \n", rv1); - LOG_I(PHY, "extarcted dci - rv2 %d \n", rv2); - //LOG_I(PHY, "extarcted dci - ndi1 %d \n", ndi1); - //LOG_I(PHY, "extarcted dci - ndi2 %d \n", ndi2); - LOG_I(PHY, "extarcted dci - rballoc %x \n", rballoc); - LOG_I(PHY, "extarcted dci - harq pid %d \n", harq_pid); - LOG_I(PHY, "extarcted dci - round0 %d \n", pdlsch0_harq->round); - LOG_I(PHY, "extarcted dci - round1 %d \n", pdlsch1_harq->round); -#endif - - // I- check dci content minimum coherency - if(harq_pid>=8) - { - LOG_I(PHY,"bad harq pid\n"); - return(0); - } - - if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) ) - { - LOG_I(PHY,"bad rnti\n"); - return(0); - } - - - if( mcs1 > 28) - { - if(pdlsch0_harq->round == 0) - { - LOG_I(PHY,"bad mcs1\n"); - return(0); - } - } - - if( mcs2 > 28) - { - if(pdlsch1_harq->round == 0) - { - LOG_I(PHY,"bad mcs2\n"); - return(0); - } - } - - - if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0)) - { - // DCI false detection - LOG_I(PHY,"bad rv1\n"); - return(0); - } - - if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0)) - { - // DCI false detection - LOG_I(PHY,"bad rv2\n"); - return(0); - } - - - switch (N_RB_DL) { - case 6: - if (rah == 0) - { - //RBG = 1; - RIV_max = 0x3F; - } - else - { - RIV_max = RIV_max6; - } - break; - case 25: - if (rah == 0) - { - //RBG = 2; - RIV_max = 0x1FFF; - } - else - { - RIV_max = RIV_max25; - } - break; - case 50: - if (rah == 0) - { - //RBG = 3; - RIV_max = 0x1FFFF; - } - else - { - RIV_max = RIV_max50; - } - break; - case 100: - if (rah == 0) - { - //RBG = 4; - RIV_max = 0x1FFFFFF; - } - else - { - RIV_max = RIV_max100; - } - break; - } - - NPRB = conv_nprb(rah, - rballoc, - N_RB_DL); - - - - if( (rballoc > RIV_max) && (rah == 1) ) - { - // DCI false detection - LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); - return(0); - } - - if(NPRB == 0) - { - // DCI false detection - LOG_I(PHY,"bad NPRB\n"); - return(0); - } - - return(1); -} - -void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDCCH *pdcch_vars, - LTE_UE_PDSCH *pdsch_vars, - LTE_DL_UE_HARQ_t *dlsch0_harq, - uint8_t nb_rb_alloc, - uint8_t subframe) -{ - uint32_t pbch_pss_sss_re; - uint32_t crs_re; - uint32_t granted_re; - uint32_t data_re; - uint32_t llr_offset; - uint8_t symbol; - uint8_t symbol_mod; - - pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0; - - //LOG_I(PHY,"compute_llr_offset: nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm); - - //dlsch0_harq->rb_alloc_even; - //dlsch0_harq->rb_alloc_odd; - - for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++) - { - symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; - if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp)) - { - if (frame_parms->nb_antennas_tx == 2) - crs_re = 4; - else - crs_re = 2; - } - else - { - crs_re = 0; - } - - granted_re = nb_rb_alloc * (12-crs_re); - pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol); - pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12); - data_re = granted_re - pbch_pss_sss_re; - llr_offset = data_re * dlsch0_harq->Qm * 2; - - pdsch_vars->llr_length[symbol] = data_re; - if(symbol < (frame_parms->symbols_per_tti-1)) - pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset; - - //LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb); - //LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re); - //LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re); - //LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re); - - - - //LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol, - // pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]); - } -} -void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, - uint8_t N_RB_DL, - DCI_INFO_EXTRACTED_t *pdci_info_extarcted, - LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDCCH *pdcch_vars, - LTE_UE_PDSCH *pdsch_vars, - uint8_t subframe, - uint16_t rnti, - uint16_t tc_rnti, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - LTE_DL_UE_HARQ_t *pdlsch0_harq, - LTE_UE_DLSCH_t *pdlsch0) -{ - - uint8_t harq_pid = pdci_info_extarcted->harq_pid; - uint8_t vrb_type = pdci_info_extarcted->vrb_type; - uint32_t rballoc = pdci_info_extarcted->rballoc; - uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t rv1 = pdci_info_extarcted->rv1; - uint8_t ndi1 = pdci_info_extarcted->ndi1; - uint8_t TPC = pdci_info_extarcted->TPC; - uint8_t rah = pdci_info_extarcted->rah; - uint8_t dai = pdci_info_extarcted->dai; - - - uint8_t NPRB = 0; - uint8_t NPRB4TBS = 0; - uint8_t nb_rb_alloc = 0; - - if(dci_format == format1A) - { - switch (N_RB_DL) { - case 6: - NPRB = RIV2nb_rb_LUT6[rballoc]; - break; - case 25: - NPRB = RIV2nb_rb_LUT25[rballoc]; - break; - case 50: - NPRB = RIV2nb_rb_LUT50[rballoc]; - break; - case 100: - NPRB = RIV2nb_rb_LUT100[rballoc]; - break; - } - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) - { - NPRB4TBS = (TPC&1) + 2; - } - else - { - NPRB4TBS = NPRB; - /* - switch (N_RB_DL) { - case 6: - NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; - break; - case 25: - NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; - break; - case 50: - NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; - break; - case 100: - NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; - break; - } - - */ - nb_rb_alloc = NPRB; - } - } - else // format1 - { - NPRB = conv_nprb(rah, rballoc, N_RB_DL); - NPRB4TBS=NPRB; - nb_rb_alloc = NPRB; - } - - pdlsch0->current_harq_pid = harq_pid; - pdlsch0->active = 1; - pdlsch0->rnti = rnti; - if(dci_format == format1A) - pdlsch0->harq_ack[subframe].vDAI_DL = dai+1; - - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) - { - pdlsch0_harq->round = 0; - pdlsch0_harq->status = ACTIVE; - } - else //CRNTI - { - if (rnti == tc_rnti) { - //fix for standalone Contention Resolution Id - pdlsch0_harq->DCINdi = (uint8_t)-1; - LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n", - rnti,harq_pid,pdlsch0_harq->DCINdi); - } - - // NDI has been toggled or this is the first transmission - if ((ndi1!=pdlsch0_harq->DCINdi) || (pdlsch0_harq->first_tx==1)) - { - pdlsch0_harq->round = 0; - pdlsch0_harq->first_tx = 0; - pdlsch0_harq->status = ACTIVE; - - }else if (rv1 != 0 ) - //NDI has not been toggled but rv was increased by eNB: retransmission - { - if (pdlsch0_harq->status == SCH_IDLE) - //packet was actually decoded in previous transmission (ACK was missed by eNB) - //However, the round is not a good check as it might have been decoded in a retransmission prior to this one. - { - LOG_D(PHY,"skip pdsch decoding and report ack\n"); - // skip pdsch decoding and report ack - //pdlsch0_harq->status = SCH_IDLE; - pdlsch0->active = 0; - pdlsch0->harq_ack[subframe].ack = 1; - pdlsch0->harq_ack[subframe].harq_id = harq_pid; - pdlsch0->harq_ack[subframe].send_harq_status = 1; - - //pdlsch0_harq->first_tx = 0; - } - else //normal retransmission - { - // nothing special to do - } - } - else - { - pdlsch0_harq->status = ACTIVE; - } - } - - pdlsch0_harq->DCINdi = ndi1; - pdlsch0_harq->mcs = mcs1; - pdlsch0_harq->rvidx = rv1; - pdlsch0_harq->nb_rb = NPRB; - - pdlsch0_harq->codeword = 0; - pdlsch0_harq->Nl = 1; - pdlsch0_harq->mimo_mode = frame_parms->nb_antenna_ports_eNB == 1 ?SISO : ALAMOUTI; - pdlsch0_harq->dl_power_off = 1; //no power offset - pdlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC &3]; - - // compute resource allocation - if(dci_format == format1A) - { - switch (N_RB_DL) { - case 6: - if (vrb_type == LOCALIZED) { - pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc]; - } - else { - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; - } - break; - - case 25: - if (vrb_type == LOCALIZED) { - pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc]; - } - else { - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; - } - break; - - case 50: - if (vrb_type == LOCALIZED) { - pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; - printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]); - } else { // DISTRIBUTED - if ((rballoc&(1<<10)) == 0) { - rballoc = rballoc&(~(1<<10)); - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } - else { - rballoc = rballoc&(~(1<<10)); - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } - } - break; - - case 100: - if (vrb_type == LOCALIZED) { - pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; - } else { - if ((rballoc&(1<<10)) == 0) { //Gap 1 - rballoc = rballoc&(~(1<<12)); - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; - } - else { //Gap 2 - rballoc = rballoc&(~(1<<12)); - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; - } - } - break; - } - } - else // format1 - { - conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,pdlsch0_harq->rb_alloc_even); - pdlsch0_harq->rb_alloc_odd[0]= pdlsch0_harq->rb_alloc_even[0]; - pdlsch0_harq->rb_alloc_odd[1]= pdlsch0_harq->rb_alloc_even[1]; - pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2]; - pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3]; - } - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) - { - pdlsch0_harq->TBS = TBStable[mcs1][NPRB4TBS-1]; - pdlsch0_harq->Qm = 2; - } - else - { - if(mcs1 < 29) - { - pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB4TBS-1]; - pdlsch0_harq->Qm = get_Qm(mcs1); - } - } - - compute_llr_offset(frame_parms, - pdcch_vars, - pdsch_vars, - pdlsch0_harq, - nb_rb_alloc, - subframe); -} - -void prepare_dl_decoding_format1C(uint8_t N_RB_DL, - DCI_INFO_EXTRACTED_t *pdci_info_extarcted, - LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDCCH *pdcch_vars, - LTE_UE_PDSCH *pdsch_vars, - uint32_t rnti, - uint32_t si_rnti, - uint32_t ra_rnti, - uint32_t p_rnti, - uint32_t frame, - uint8_t subframe, - LTE_DL_UE_HARQ_t *pdlsch0_harq, - LTE_UE_DLSCH_t *pdlsch0) -{ - - uint8_t harq_pid = pdci_info_extarcted->harq_pid; - uint32_t rballoc = pdci_info_extarcted->rballoc; - uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t Ngap = pdci_info_extarcted->Ngap; - - pdlsch0_harq->round = 0; - pdlsch0_harq->first_tx = 1; - pdlsch0_harq->vrb_type = DISTRIBUTED; - - if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321 - if (((frame&1) == 0) && (subframe == 5)) - pdlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 - else - pdlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs - } - else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3 - pdlsch0_harq->rvidx = 0; - } - - - pdlsch0_harq->Nl = 1; - pdlsch0_harq->mimo_mode = frame_parms->nb_antenna_ports_eNB == 1 ?SISO : ALAMOUTI; - pdlsch0_harq->dl_power_off = 1; //no power offset - - pdlsch0_harq->codeword = 0; - pdlsch0_harq->mcs = mcs1; - pdlsch0_harq->TBS = TBStable1C[mcs1]; - pdlsch0_harq->Qm = 2; - - - pdlsch0->current_harq_pid = harq_pid; - pdlsch0->active = 1; - pdlsch0->rnti = rnti; - - switch (N_RB_DL) { - case 6: - pdlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc]; - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; - - break; - - case 25: - pdlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc]; - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; - break; - - case 50: - pdlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc]; - if (Ngap == 0) { - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } - else { - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; - } - break; - - case 100: - pdlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc]; - if (Ngap==0) { - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; - } - else { - pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; - pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; - pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; - } - break; - - default: - AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL); - break; - } - - compute_llr_offset(frame_parms, - pdcch_vars, - pdsch_vars, - pdlsch0_harq, - pdlsch0_harq->nb_rb, - subframe); - -} - -void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq) -{ - -switch (tpmi) { - case 0: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - break; - case 1: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); - break; - case 2: // PUSCH precoding - dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - if (tbswap==0){ - dlsch0_harq->pmi_alloc = pmi_alloc; - dlsch1_harq->pmi_alloc = pmi_alloc^0x1555; - } else { - dlsch1_harq->pmi_alloc = pmi_alloc; - dlsch0_harq->pmi_alloc = pmi_alloc^0x1555; - } -#ifdef DEBUG_HARQ - printf ("\n \n compute_precoding_info_2cw pmi_alloc_new = %d\n", dlsch0_harq->pmi_alloc); - #endif - break; - default: - break; - } -} - -void compute_precoding_info_1cw(uint8_t tpmi, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch_harq) -{ - -switch (tpmi) { - case 0 : - dlsch_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); - break; - case 2: - dlsch_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; - case 3: - dlsch_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; - case 4: - dlsch_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; - case 5: - dlsch_harq->mimo_mode = PUSCH_PRECODING0; - dlsch_harq->pmi_alloc = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); - break; - case 6: - dlsch_harq->mimo_mode = PUSCH_PRECODING1; - dlsch_harq->pmi_alloc = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); - break; - } - #ifdef DEBUG_HARQ - printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi); - #endif - } - -void compute_precoding_info_format2A(uint8_t tpmi, - uint8_t nb_antenna_ports_eNB, - uint8_t tb0_active, - uint8_t tb1_active, - LTE_DL_UE_HARQ_t *dlsch0_harq, - LTE_DL_UE_HARQ_t *dlsch1_harq) -{ - - dlsch0_harq->dl_power_off = 0; - dlsch1_harq->dl_power_off = 0; - - if (nb_antenna_ports_eNB == 2) { - if ((tb0_active==1) && (tb1_active==1)) { - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; - } else { - dlsch0_harq->mimo_mode = ALAMOUTI; - dlsch1_harq->mimo_mode = ALAMOUTI; - } - } else if (nb_antenna_ports_eNB == 4) { // 4 antenna case - if ((tb0_active==1) && (tb1_active==1)) { - switch (tpmi) { - case 0: // one layer per transport block - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; - break; - - case 1: // one-layers on TB 0, two on TB 1 - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->Nl = 2; - dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; - break; - - case 2: // two-layers on TB 0, two on TB 1 - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->Nl = 2; - dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; - break; - - case 3: // - LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n"); - break; - } - } else if (tb0_active == 1) { - switch (tpmi) { - case 0: // one layer per transport block - dlsch0_harq->mimo_mode = ALAMOUTI; - dlsch1_harq->mimo_mode = ALAMOUTI; - break; - - case 1: // two-layers on TB 0 - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->Nl = 2; - dlsch0_harq->dl_power_off = 1; - break; - - case 2: // two-layers on TB 0, two on TB 1 - case 3: // - LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); - break; - } - } else if (tb1_active == 1) { - switch (tpmi) { - case 0: // one layer per transport block - dlsch0_harq->mimo_mode = ALAMOUTI; - dlsch1_harq->mimo_mode = ALAMOUTI; - break; - - case 1: // two-layers on TB 0 - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->Nl = 2; - dlsch0_harq->dl_power_off = 1; - break; - - case 2: // two-layers on TB 0, two on TB 1 - case 3: // - LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); - break; - } - } - } - // printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active); - //printf("UE (%x/%d): Subframe %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, - // dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status); - //printf("TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS); - -} - -void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, - DCI_INFO_EXTRACTED_t *pdci_info_extarcted, - LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDCCH *pdcch_vars, - LTE_UE_PDSCH *pdsch_vars, - uint16_t rnti, - uint8_t subframe, - LTE_DL_UE_HARQ_t *dlsch0_harq, - LTE_DL_UE_HARQ_t *dlsch1_harq, - LTE_UE_DLSCH_t *pdlsch0, - LTE_UE_DLSCH_t *pdlsch1) -{ - - uint8_t rah = pdci_info_extarcted->rah; - uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t mcs2 = pdci_info_extarcted->mcs2; - uint8_t rv1 = pdci_info_extarcted->rv1; - uint8_t rv2 = pdci_info_extarcted->rv2; - uint8_t harq_pid = pdci_info_extarcted->harq_pid; - uint32_t rballoc = pdci_info_extarcted->rballoc; - uint8_t tbswap = pdci_info_extarcted->tb_swap; - uint8_t tpmi = pdci_info_extarcted->tpmi; - uint8_t TPC = pdci_info_extarcted->TPC; - uint8_t ndi1 = pdci_info_extarcted->ndi1; - uint8_t ndi2 = pdci_info_extarcted->ndi2; - - uint8_t TB0_active = 1; - uint8_t TB1_active = 1; - - // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc); - - - if ((rv1 == 1) && (mcs1 == 0)) { - TB0_active=0; - } - if ((rv2 == 1) && (mcs2 == 0)) { - TB1_active=0; - } - -#ifdef DEBUG_HARQ - printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active); -#endif - - dlsch0_harq->mcs = mcs1; - dlsch1_harq->mcs = mcs2; - dlsch0_harq->rvidx = rv1; - dlsch1_harq->rvidx = rv2; - dlsch0_harq->DCINdi = ndi1; - dlsch1_harq->DCINdi = ndi2; - - dlsch0_harq->codeword = 0; - dlsch1_harq->codeword = 1; - dlsch0_harq->Nl = 1; - dlsch1_harq->Nl = 1; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; - - pdlsch0->current_harq_pid = harq_pid; - pdlsch0->harq_ack[subframe].harq_id = harq_pid; - pdlsch1->current_harq_pid = harq_pid; - pdlsch1->harq_ack[subframe].harq_id = harq_pid; - - // assume two CW are active - dlsch0_harq->status = ACTIVE; - dlsch1_harq->status = ACTIVE; - pdlsch0->active = 1; - pdlsch1->active = 1; - pdlsch0->rnti = rnti; - pdlsch1->rnti = rnti; - - - if (TB0_active && TB1_active && tbswap==1) { - dlsch0_harq->codeword = 1; - dlsch1_harq->codeword = 0; - } - - - if (!TB0_active && TB1_active){ - dlsch1_harq->codeword = 0; - } - - if (TB0_active && !TB1_active){ - dlsch0_harq->codeword = 0; - } - - - if (TB0_active==0) { - dlsch0_harq->status = SCH_IDLE; - pdlsch0->active = 0; - #ifdef DEBUG_HARQ - printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); - #endif - } - - if (TB1_active==0) { - dlsch1_harq->status = SCH_IDLE; - pdlsch1->active = 0; - } - -#ifdef DEBUG_HARQ - printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); -#endif - - // compute resource allocation - if (TB0_active == 1){ - - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - conv_rballoc(rah, - rballoc, - frame_parms->N_RB_DL, - dlsch0_harq->rb_alloc_even); - - dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; - - if (TB1_active == 1){ - dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; - dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0]; - dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1]; - dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; - dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; - - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; - - //dlsch0_harq->Nl = 1; - //dlsch1_harq->Nl = 1; - } - } else if ((TB0_active == 0) && (TB1_active == 1)){ - - conv_rballoc(rah, - rballoc, - frame_parms->N_RB_DL, - dlsch1_harq->rb_alloc_even); - - dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3]; - dlsch1_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - } - - - // compute precoding matrix + mimo mode - if(dci_format == format2) - { - if ((TB0_active) && (TB1_active)){ //two CW active - compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq); - - // printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); - } else if ((TB0_active) && (!TB1_active)) { // only CW 0 active - compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq); - } else { - compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq); - // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi); - } - //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); - if ((frame_parms->nb_antenna_ports_eNB == 1) && (TB0_active)) - dlsch0_harq->mimo_mode = SISO; - } - else - { - compute_precoding_info_format2A( tpmi, - frame_parms->nb_antenna_ports_eNB, - TB0_active, - TB1_active, - dlsch0_harq, - dlsch1_harq); - } - // printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); - // reset round + compute Qm - if (TB0_active) { - // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx); - if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { - dlsch0_harq->round = 0; - dlsch0_harq->status = ACTIVE; - dlsch0_harq->DCINdi = ndi1; - - //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n", - // subframe,harq_pid,dlsch0_harq->round); - if ( dlsch0_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); - dlsch0_harq->first_tx = 0; - } - } - /*else if (rv1 != 0 ) - //NDI has not been toggled but rv was increased by eNB: retransmission - { - if(dlsch0_harq->status == SCH_IDLE) { - // skip pdsch decoding and report ack - //dlsch0_harq->status = SCH_IDLE; - pdlsch0->active = 0; - pdlsch0->harq_ack[subframe].ack = 1; - pdlsch0->harq_ack[subframe].harq_id = harq_pid; - pdlsch0->harq_ack[subframe].send_harq_status = 1; - }*/ - - // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest - // PDCCH for the same trasport block using Imcs in [0 .. 28] - if(dlsch0_harq->mcs <= 28) - { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - LOG_D(PHY,"[UE] DLSCH: New TBS CW0 subframe %d (pid %d, round %d) TBS %d \n", - subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); - } - else - { - LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW0 subframe %d (pid %d, round %d) TBS %d \n", - subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); - } - //if(dlsch0_harq->Nl == 2) - //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; - if (mcs1 <= 28) - dlsch0_harq->Qm = get_Qm(mcs1); - else if (mcs1<=31) - dlsch0_harq->Qm = (mcs1-28)<<1; - } - - // printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); - - if (TB1_active) { - // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx); - if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { - dlsch1_harq->round = 0; - dlsch1_harq->status = ACTIVE; - dlsch1_harq->DCINdi = ndi2; - //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n", - // subframe,harq_pid,dlsch0_harq->round); - if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); - dlsch1_harq->first_tx = 0; - } - } - /*else if (rv1 != 0 ) - //NDI has not been toggled but rv was increased by eNB: retransmission - { - if(dlsch1_harq->status == SCH_IDLE) { - // skip pdsch decoding and report ack - //dlsch1_harq->status = SCH_IDLE; - pdlsch1->active = 0; - pdlsch1->harq_ack[subframe].ack = 1; - pdlsch1->harq_ack[subframe].harq_id = harq_pid; - pdlsch1->harq_ack[subframe].send_harq_status = 1; - } - }*/ - - // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest - // PDCCH for the same trasport block using Imcs in [0 .. 28] - if(dlsch1_harq->mcs <= 28) - { - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - LOG_D(PHY,"[UE] DLSCH: New TBS CW1 subframe %d (pid %d, round %d) TBS %d \n", - subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); - } - else - { - LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW1 subframe %d (pid %d, round %d) TBS %d \n", - subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); - } - if (mcs2 <= 28) - dlsch1_harq->Qm = get_Qm(mcs2); - else if (mcs1<=31) - dlsch1_harq->Qm = (mcs2-28)<<1; - } - - - compute_llr_offset(frame_parms, - pdcch_vars, - pdsch_vars, - dlsch0_harq, - dlsch0_harq->nb_rb, - subframe); - - - /* #ifdef DEBUG_HARQ - printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); - printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active); - if (dlsch0 != NULL && dlsch1 != NULL) - printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status); - else if (dlsch0 == NULL && dlsch1 != NULL) - printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status); - else if (dlsch0 != NULL && dlsch1 == NULL) - printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status); - #endif*/ -} - -int generate_ue_dlsch_params_from_dci(int frame, - uint8_t subframe, - void *dci_pdu, - uint16_t rnti, - DCI_format_t dci_format, - LTE_UE_PDCCH *pdcch_vars, - LTE_UE_PDSCH *pdsch_vars, - LTE_UE_DLSCH_t **dlsch, - LTE_DL_FRAME_PARMS *frame_parms, - PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint8_t beamforming_mode, - uint16_t tc_rnti) -{ - - uint8_t harq_pid=0; - uint8_t frame_type=frame_parms->frame_type; - uint8_t tpmi=0; - LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; - LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; - - DCI_INFO_EXTRACTED_t dci_info_extarcted; - uint8_t status=0; - - 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, - frame%1024, - subframe, - (dci_format==format0? "Format 0":( - dci_format==format1? "format 1":( - dci_format==format1A? "format 1A":( - dci_format==format1B? "format 1B":( - dci_format==format1C? "format 1C":( - dci_format==format1D? "format 1D":( - dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":( - dci_format==format2? "format 2":( - dci_format==format2A? "format 2A":( - dci_format==format2B? "format 2B":( - dci_format==format2C? "format 2C":( - dci_format==format2D? "format 2D":( - dci_format==format3? "format 3": "UNKNOWN" - )))))))))))))); - #endif - - memset(&dci_info_extarcted,0,sizeof(dci_info_extarcted)); - switch (dci_format) { - - case format0: // This is an ULSCH allocation so nothing here, inform MAC - LOG_E(PHY,"format0 not possible\n"); - return(-1); - break; - - case format1A: - { - // extract dci infomation -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d extarct dci info \n", frame, subframe); -#endif - extract_dci1A_info(frame_parms->N_RB_DL, - frame_type, - dci_pdu, - &dci_info_extarcted); - - - // check dci content - dlsch0 = dlsch[0]; - dlsch0->active = 0; - dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d check dci coherency \n", frame, subframe); -#endif - status = check_dci_format1_1a_coherency(format1A, - frame_parms->N_RB_DL, - rnti, - tc_rnti, - si_rnti, - ra_rnti, - p_rnti,frame,subframe, - &dci_info_extarcted, - dlsch0_harq); - if(status == 0) - { - printf("bad DCI 1A !!! \n"); - return(-1); - } - - // dci is correct ==> update internal structure and prepare dl decoding -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe); -#endif - prepare_dl_decoding_format1_1A(format1A, - frame_parms->N_RB_DL, - &dci_info_extarcted, - frame_parms, - pdcch_vars, - pdsch_vars, - subframe, - rnti, - tc_rnti, - si_rnti, - ra_rnti, - p_rnti, - dlsch0_harq, - dlsch0); - - - - break; - } - case format1C: - { - // extract dci infomation -#ifdef DEBUG_DL_DECODING - LOG_I(PHY,"[DCI Format-1C] extact dci information \n"); -#endif - extract_dci1C_info(frame_parms->N_RB_DL, - frame_type, - dci_pdu, - &dci_info_extarcted); - - - // check dci content -#ifdef DEBUG_DL_DECODING - LOG_I(PHY,"[DCI Format-1C] check dci content \n"); -#endif - dlsch0 = dlsch[0]; - dlsch0->active = 0; - dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; - - status = check_dci_format1c_coherency(frame_parms->N_RB_DL, - &dci_info_extarcted, - rnti, - si_rnti, - ra_rnti, - p_rnti, - dlsch0_harq); - if(status == 0) - return(-1); - - // dci is correct ==> update internal structure and prepare dl decoding -#ifdef DEBUG_DL_DECODING - LOG_I(PHY,"[DCI Format-1C] prepare downlink decoding \n"); -#endif - prepare_dl_decoding_format1C(frame_parms->N_RB_DL, - &dci_info_extarcted, - frame_parms, - pdcch_vars, - pdsch_vars, - rnti, - si_rnti, - ra_rnti, - p_rnti, - frame, - subframe, - dlsch0_harq, - dlsch0); - - break; - } - - case format1: - { - // extract dci infomation -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d extarct dci info \n", frame, subframe); -#endif - extract_dci1_info(frame_parms->N_RB_DL, - frame_type, - dci_pdu, - &dci_info_extarcted); - - // check dci content - dlsch0 = dlsch[0]; - dlsch0->active = 0; - dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; - -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d check dci coherency \n", frame, subframe); -#endif - status = check_dci_format1_1a_coherency(format1, - frame_parms->N_RB_DL, - rnti, - tc_rnti, - si_rnti, - ra_rnti, - p_rnti,frame,subframe, - &dci_info_extarcted, - dlsch0_harq); - if(status == 0) - { - printf("bad DCI 1 !!! \n"); - return(-1); - } - - - // dci is correct ==> update internal structure and prepare dl decoding -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe); -#endif - prepare_dl_decoding_format1_1A(format1, - frame_parms->N_RB_DL, - &dci_info_extarcted, - frame_parms, - pdcch_vars, - pdsch_vars, - subframe, - rnti, - tc_rnti, - si_rnti, - ra_rnti, - p_rnti, - dlsch0_harq, - dlsch0); - break; - } - - case format2: - { - // extract dci infomation - //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame, subframe); - extract_dci2_info(frame_parms->N_RB_DL, - frame_type, - frame_parms->nb_antenna_ports_eNB, - dci_pdu, - &dci_info_extarcted); - - - // check dci content - dlsch[0]->active = 1; - dlsch[1]->active = 1; - - dlsch0 = dlsch[0]; - dlsch1 = dlsch[1]; - - dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; - dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; - // printf("before coherency dlsch[1]->pmi_alloc %d\n",dlsch[1]->pmi_alloc); - // printf("before coherency dlsch1->pmi_alloc %d\n",dlsch1->pmi_alloc); - // printf("before coherency dlsch1_harq->pmi_alloc %d\n",dlsch1_harq->pmi_alloc); - - //LOG_I(PHY,"[DCI-format2] check dci content \n"); - status = check_dci_format2_2a_coherency(format2, - frame_parms->N_RB_DL, - &dci_info_extarcted, - rnti, - si_rnti, - ra_rnti, - p_rnti, - dlsch0_harq, - dlsch1_harq); - if(status == 0) - return(-1); - - - // dci is correct ==> update internal structure and prepare dl decoding - //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n"); - prepare_dl_decoding_format2_2A(format2, - &dci_info_extarcted, - frame_parms, - pdcch_vars, - pdsch_vars, - rnti, - subframe, - dlsch0_harq, - dlsch1_harq, - dlsch0, - dlsch1); - } - break; - - case format2A: - { - // extract dci infomation - LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe); - extract_dci2A_info(frame_parms->N_RB_DL, - frame_type, - frame_parms->nb_antenna_ports_eNB, - dci_pdu, - &dci_info_extarcted); - - // check dci content - //LOG_I(PHY,"[DCI-format2A] check dci content \n"); - //LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid); - //dlsch[0]->active = 0; - //dlsch[1]->active = 0; - - if (dci_info_extarcted.tb_swap == 0) { - dlsch0 = dlsch[0]; - dlsch1 = dlsch[1]; - } else { - dlsch0 = dlsch[1]; - dlsch1 = dlsch[0]; - } - dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; - dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; - - //LOG_I(PHY,"[DCI-format2A] check dci content \n"); - status = check_dci_format2_2a_coherency(format2A, - frame_parms->N_RB_DL, - &dci_info_extarcted, - rnti, - si_rnti, - ra_rnti, - p_rnti, - dlsch0_harq, - dlsch1_harq); - if(status == 0) - return(-1); - - // dci is correct ==> update internal structure and prepare dl decoding - //LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n"); - prepare_dl_decoding_format2_2A(format2A, - &dci_info_extarcted, - frame_parms, - pdcch_vars, - pdsch_vars, - rnti, - subframe, - dlsch0_harq, - dlsch1_harq, - dlsch0, - dlsch1); - } - break; - - case format1E_2A_M10PRB: - if (!dlsch[0]) return -1; - - harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; - - if (harq_pid>=8) { - LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - dlsch[0]->current_harq_pid = harq_pid; - dlsch[0]->harq_ack[subframe].harq_id = harq_pid; - - /* - tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap; - if (tbswap == 0) { - dlsch0 = dlsch[0]; - dlsch1 = dlsch[1]; - } - else{ - dlsch0 = dlsch[1]; - dlsch1 = dlsch[0]; - } - */ - dlsch0 = dlsch[0]; - - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - // Needs to be checked - dlsch0_harq->codeword=0; - conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL, - dlsch0_harq->rb_alloc_even); - - dlsch0_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_even[0]; - dlsch0_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_even[1]; - dlsch0_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_even[2]; - dlsch0_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_even[3]; - /* - dlsch1_harq->rb_alloc_even[0] = dlsch0_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_even[1] = dlsch0_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_even[2] = dlsch0_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_even[3] = dlsch0_harq->rb_alloc_even[3]; - */ - dlsch0_harq->nb_rb = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc, - frame_parms->N_RB_DL); - //dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; - - dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->TPC&3]; - - - - /* - if (dlsch0_harq->mcs>20) { - printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs); - return(-1); - } - */ - - //dlsch1_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2; - dlsch0_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv; - //dlsch1_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2; - - // check if either TB is disabled (see 36-213 V8.6 p. 26) - - if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { - dlsch0_harq->status = DISABLED; - } - - //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { - //dlsch1_harq->status = DISABLED; - //} - dlsch0_harq->Nl = 1; - - //dlsch0->layer_index = tbswap; - //dlsch1->layer_index = 1-tbswap; - - - // Fix this - tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi; - // printf("ue: tpmi %d\n",tpmi); - - switch (tpmi) { - case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; - - case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); - break; - - case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; - - case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - - break; - - case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; - - case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; - - - case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - LOG_E(PHY,"Unsupported TPMI\n"); - return(-1); - break; - } - - - if (frame_parms->nb_antenna_ports_eNB == 1) - dlsch0_harq->mimo_mode = SISO; - - - if ((dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) || - (dlsch0_harq->first_tx==1)) { - - dlsch0_harq->round = 0; - dlsch0_harq->first_tx = 0; - dlsch0_harq->status = ACTIVE; - } - /* - else if (dlsch0_harq->status == SCH_IDLE) { // we got same ndi for a previously decoded process, - // this happens if either another harq process in the same - // is NAK or an ACK was not received - - dlsch0->harq_ack[subframe].ack = 1; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch0->harq_ack[subframe].send_harq_status = 1; - dlsch0->active = 0; - return(0); - } - */ - - dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi; - dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; - - if (dlsch0_harq->nb_rb>1) { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - } else - dlsch0_harq->TBS =0; - - dlsch0->rnti = rnti; - //dlsch1->rnti = rnti; - - dlsch0->active = 1; - //dlsch1->active = 1; - - dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; - //dlsch1_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; - - - break; - - default: - LOG_E(PHY,"format %d not yet implemented\n",dci_format); - return(-1); - break; - } - -#ifdef UE_DEBUG_TRACE - - if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { - LOG_I(PHY,"dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe); - LOG_I(PHY,"PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti); - LOG_D(PHY,"PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb); - LOG_D(PHY,"PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); - LOG_I(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",dci_info_extarcted.harq_pid); - LOG_I(PHY,"PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); - LOG_D(PHY,"PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); - LOG_D(PHY,"PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); - LOG_D(PHY,"PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx); - LOG_D(PHY,"PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS); - LOG_D(PHY,"PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); - LOG_D(PHY,"PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); - } -#endif - -#if T_TRACER - if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) - { - T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe), - T_INT(dlsch[0]->rnti), T_INT(dci_format), - T_INT(harq_pid), - T_INT(dlsch0_harq->mcs), - T_INT(dlsch0_harq->TBS)); - } -#endif - - - // compute DL power control parameters - if (dlsch0_harq != NULL){ - computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); - computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off); - } - - if (dlsch1_harq != NULL) { - computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); - computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off); - } - - - return(0); -} - - -uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe) -{ - uint8_t ret = 255; - - if (frame_parms->frame_type == FDD) { - ret = (((frame*10)+subframe)&7); - } else { - - switch (frame_parms->tdd_config) { - case 1: - switch (subframe) { - case 2: - case 3: - ret = (subframe-2); - break; - - case 7: - case 8: - ret = (subframe-5); - break; - - default: - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - ret = (255); - break; - } - - break; - - case 2: - if ((subframe!=2) && (subframe!=7)) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - ret=255; - } - else ret = (subframe/7); - break; - - case 3: - if ((subframe<2) || (subframe>4)) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - ret = (255); - } - else ret = (subframe-2); - break; - - case 4: - if ((subframe<2) || (subframe>3)) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - ret = (255); - } - else ret = (subframe-2); - break; - - case 5: - if (subframe!=2) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - ret = (255); - } - else ret = (subframe-2); - break; - - default: - LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config); - ret = (255); - } - } - - AssertFatal(ret!=255, - "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t)ret, frame, subframe); - return ret; -} - -uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n) -{ - uint8_t ul_subframe = 255; - - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 1)) { - if ((n==1)||(n==6)) { // tdd_config 0,1 SF 1,5 - ul_subframe = ((n+6)%10); - } else if ((n==4)||(n==9)) { - ul_subframe = ((n+4)%10); - } - } else if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 6) && - ((n==0)||(n==1)||(n==5)||(n==6))) - ul_subframe = ((n+7)%10); - else if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 6) && - (n==9)) // tdd_config 6 SF 9 - ul_subframe = ((n+5)%10); - else - ul_subframe = ((n+4)%10); - - if ( (subframe_select(frame_parms,ul_subframe) != SF_UL) && (frame_parms->frame_type == TDD)) return(255); - - LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); - return ul_subframe; -} - -uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n) -{ - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 1)) { - if ((n==7)||(n==2)) { // tdd_config 0,1 SF 1,5 - return((n==7)? 1 : 6); - } else if ((n==3)||(n==8)) { - return((n==3)? 9 : 4); - } - } else if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 6) && - ((n==7)||(n==8)||(n==2)||(n==3))) - return((n+3)%10); - else if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 6) && - (n==4)) // tdd_config 6 SF 9 - return(9); - else - return((n+6)%10); -} - -uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n) -{ - uint32_t ul_frame = frame; - - if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 1)) { - if ((n==1)||(n==6)||(n==4)||(n==9)) { // tdd_config 0,1 SF 1,5 - ul_frame = (frame + (n < 5 ? 0 : 1)); - } - } else if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 6) && - ((n==0)||(n==1)||(n==5)||(n==6))) - ul_frame = (frame + (n>=5 ? 1 : 0)); - else if ((frame_parms->frame_type == TDD) && - (frame_parms->tdd_config == 6) && - (n==9)) // tdd_config 6 SF 9 - ul_frame = (frame+1); - else - ul_frame = (frame+(n>=6 ? 1 : 0)); - - LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame); - return ul_frame % 1024; -} - -int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb) -{ - int nb_subbands = 0; - int32_t pmi_alloc_new = 0, pmi_new = 0, pmi_old = 0; - int i; - - switch (nb_rb) { - case 6: - nb_subbands = 6; - break; - default: - case 25: - nb_subbands = 7; - break; - case 50: - nb_subbands = 9; - break; - case 100: - nb_subbands = 13; - break; - } - - for (i = 0; i < nb_subbands; i++) { - pmi_old = (pmi_alloc >> i)&1; - - if (pmi_old == 0) - if (tpmi == 5) - pmi_new = 0; - else - pmi_new = 1; - else - if (tpmi == 5) - pmi_new = 2; - else - pmi_new = 3; - - pmi_alloc_new|=pmi_new<<(2*i); - - } -#ifdef DEBUG_HARQ -printf(" [DCI UE] pmi_alloc_old %d, pmi_alloc_new %d pmi_old %d , pmi_new %d\n", pmi_alloc, pmi_alloc_new,pmi_old, pmi_new ); -#endif -return(pmi_alloc_new); - -} - -uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) -{ - - int i, aarx; - uint16_t pmiq=0; - uint32_t pmivect = 0; - uint8_t rank = meas->rank[eNB_id]; - int pmi_re,pmi_im; - int nb_subbands=0; - - - switch (nb_rb) { - case 6: - nb_subbands = 6; - break; - default: - case 25: - nb_subbands = 7; - break; - case 50: - nb_subbands = 9; - break; - case 100: - nb_subbands = 13; - break; - } - - - for (i=0; i<nb_subbands; i++) { - pmi_re = 0; - pmi_im = 0; - - if (rank == 0) { - for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) { - pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; - pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; - } - - // pmi_re = meas->subband_pmi_re[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]]; - // pmi_im = meas->subband_pmi_im[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]]; - - // printf("pmi => (%d,%d)\n",pmi_re,pmi_im); - if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) - pmiq = PMI_2A_11; - else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) - pmiq = PMI_2A_1j; - else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) - pmiq = PMI_2A_1m1; - else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) - pmiq = PMI_2A_1mj; - - // printf("subband %d, pmi%d \n",i,pmiq); - pmivect |= (pmiq<<(2*i)); - } - - else if (rank==1) { - for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) { - pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; - //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]); - pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; - //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); - } - if (pmi_re >= pmi_im) // this is not orthogonal - // this is orthogonal - //if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im))) - pmiq = PMI_2A_R1_11; - else - pmiq = PMI_2A_R1_1j; - - // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); - // printf("subband %d, pmi%d \n",i,pmiq); - //According to Section 7.2.4 of 36.213 - - pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit - } - else { - LOG_E(PHY,"PMI feedback for rank>1 not supported!\n"); - pmivect = 0; - } - - } -#ifdef DEBUG_HARQ - printf( "quantize_subband_pmi pmivect %d \n", pmivect); -#endif - return(pmivect); -} - -uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands) -{ - - uint8_t i; - uint16_t pmiq=0; - uint16_t pmivect = 0; - uint8_t rank = meas->rank[eNB_id]; - int pmi_re,pmi_im; - - for (i=0; i<nb_subbands; i++) { - - if (rank == 0) { - pmi_re = meas->subband_pmi_re[eNB_id][i][a_id]; - pmi_im = meas->subband_pmi_im[eNB_id][i][a_id]; - - if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) - pmiq = PMI_2A_11; - else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) - pmiq = PMI_2A_1j; - else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) - pmiq = PMI_2A_1m1; - else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) - pmiq = PMI_2A_1mj; - - pmivect |= (pmiq<<(2*i)); - } else { - // This needs to be done properly!!! - pmivect = 0; - } - } - - return(pmivect); -} - -uint16_t quantize_wideband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) -{ - - uint16_t pmiq=0; - uint8_t rank = meas->rank[eNB_id]; - //int pmi; - int pmi_re,pmi_im; - - if (rank == 1) { - //pmi = - pmi_re = meas->wideband_pmi_re[eNB_id][meas->selected_rx_antennas[eNB_id][0]]; - pmi_im = meas->wideband_pmi_im[eNB_id][meas->selected_rx_antennas[eNB_id][0]]; - - if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) - pmiq = PMI_2A_11; - else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) - pmiq = PMI_2A_1j; - else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) - pmiq = PMI_2A_1m1; - else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) - pmiq = PMI_2A_1mj; - - } else { - // This needs to be done properly! - pmiq = PMI_2A_11; - } - - - return(pmiq); -} -/* - uint8_t sinr2cqi(int sinr) { - if (sinr<-3) - return(0); - if (sinr>14) - return(10); - else - return(3+(sinr>>1)); - } -*/ - -uint8_t sinr2cqi(double sinr,uint8_t trans_mode) -{ - // int flag_LA=0; - - uint8_t retValue = 0; - - if(flag_LA==0) { - // Ideal Channel Estimation - if (sinr<=-4.89) - retValue = (0); - else if (sinr < -3.53) - retValue = (3); - else if (sinr <= -1.93) - retValue = (4); - else if (sinr <= -0.43) - retValue = (5); - else if (sinr <= 1.11) - retValue = (6); - else if (sinr <= 3.26) - retValue = (7); - else if (sinr <= 5.0) - retValue = (8); - else if (sinr <= 7.0) - retValue = (9); - else if (sinr <= 9.0) - retValue = (10); - else if (sinr <= 11.0) - retValue = (11); - else if (sinr <= 13.0) - retValue = (12); - else if (sinr <= 15.5) - retValue = (13); - else if (sinr <= 17.5) - retValue = (14); - else - retValue = (15); - } else { - int h=0; - int trans_mode_tmp; - - if (trans_mode ==5) - trans_mode_tmp=2; - else if(trans_mode ==6) - trans_mode_tmp=3; - else - trans_mode_tmp = trans_mode-1; - - for(h=0; h<16; h++) { - if(sinr<=sinr_to_cqi[trans_mode_tmp][h]) - retValue = (h); - } - } - - LOG_D(PHY, "sinr=%f trans_mode=%d cqi=%d\n", sinr, trans_mode, retValue); - return retValue; -} -//uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) { -// -// uint8_t i; -//// uint16_t cqivect = 0; -// uint32_t cqivect = 0; -// -//// char diff_cqi; -// int diff_cqi=0; -// -// for (i=0;i<NUMBER_OF_SUBBANDS;i++) { -// -// diff_cqi = -sinr2cqi(meas->wideband_cqi_dB[eNB_id][0]) + sinr2cqi(meas->subband_cqi_dB[eNB_id][0][i]); -// -// // Note, this is Table 7.2.1-2 from 36.213 -// if (diff_cqi<=-1) -// diff_cqi = 3; -// else if (diff_cqi>2) -// diff_cqi = 2; -// cqivect |= (diff_cqi<<(2*i)); -// -// } -// -// return(cqivect); -//} - - -uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t trans_mode,int nb_subbands) -{ - - uint8_t i; - - uint32_t cqivect = 0,offset=0; - - - int diff_cqi=0; - - for (i=0; i<nb_subbands; i++) { - - diff_cqi = -sinr2cqi(meas->wideband_cqi_avg[eNB_id],trans_mode) + sinr2cqi(meas->subband_cqi_tot_dB[eNB_id][i],trans_mode); - - // Note, this is Table 7.2.1-2 from 36.213 - if (diff_cqi<=-1) - offset = 3; - else if (diff_cqi>=2) - offset = 2; - else - offset=(uint32_t)diff_cqi; - - cqivect |= (offset<<(2*i)); - - } - - return(cqivect); -} - -void fill_CQI(LTE_UE_ULSCH_t *ulsch,PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t harq_pid,int N_RB_DL,uint16_t rnti, uint8_t trans_mode, double sinr_eff) -{ - - // printf("[PHY][UE] Filling CQI for eNB %d, meas->wideband_cqi_tot[%d] %d\n", - // eNB_id,eNB_id,meas->wideband_cqi_tot[eNB_id]); - double sinr_tmp; - uint8_t *o = ulsch->o; - UCI_format_t uci_format = ulsch->uci_format; - - if(flag_LA==1) - sinr_tmp = sinr_eff; - else - sinr_tmp = (double) meas->wideband_cqi_avg[eNB_id]; - - - - //LOG_I(PHY,"[UE][UCI] Filling CQI format %d for eNB %d N_RB_DL %d\n",uci_format,eNB_id,N_RB_DL); - - switch (N_RB_DL) { - - case 6: - switch (uci_format) { - case wideband_cqi_rank1_2A: - ((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); - break; - - case wideband_cqi_rank2_2A: - ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); - break; - - case HLC_subband_cqi_nopmi: - ((HLC_subband_cqi_nopmi_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_nopmi_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); - break; - - case HLC_subband_cqi_rank1_2A: - ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); - ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); - break; - - case HLC_subband_cqi_rank2_2A: - // This has to be improved!!! - ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); - ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,6); - ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); - break; - - case HLC_subband_cqi_mcs_CBA: - // this is the cba mcs uci for cba transmission - ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; - ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti = rnti; - LOG_D(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); - break; - - case ue_selected: - LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); - AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); - break; - - default: - LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); - AssertFatal(1==0,"unsupported CQI mode !!!"); - break; - - } - - break; - - case 25: - switch (uci_format) { - case wideband_cqi_rank1_2A: - ((wideband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((wideband_cqi_rank1_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); - break; - - case wideband_cqi_rank2_2A: - ((wideband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); - break; - - case HLC_subband_cqi_nopmi: - ((HLC_subband_cqi_nopmi_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_nopmi_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); - break; - - case HLC_subband_cqi_rank1_2A: - ((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); - ((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); - break; - - case HLC_subband_cqi_rank2_2A: - // This has to be improved!!! - ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); - ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,7); - ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); - break; - - case HLC_subband_cqi_mcs_CBA: - // this is the cba mcs uci for cba transmission - ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; - ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = rnti; - LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); - break; - - case ue_selected: - LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); - AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); - break; - - default: - LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); - AssertFatal(1==0,"unsupported CQI mode !!!"); - break; - - } - - break; - - case 50: - switch (uci_format) { - case wideband_cqi_rank1_2A: - ((wideband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((wideband_cqi_rank1_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); - break; - - case wideband_cqi_rank2_2A: - ((wideband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); - break; - - case HLC_subband_cqi_nopmi: - ((HLC_subband_cqi_nopmi_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_nopmi_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); - break; - - case HLC_subband_cqi_rank1_2A: - ((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); - ((HLC_subband_cqi_rank1_2A_10MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); - break; - - case HLC_subband_cqi_rank2_2A: - // This has to be improved!!! - ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); - ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,9); - ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); - break; - - case HLC_subband_cqi_mcs_CBA: - // this is the cba mcs uci for cba transmission - ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; - ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti = rnti; - LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); - break; - - case ue_selected: - LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); - AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); - break; - - default: - LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); - AssertFatal(1==0,"unsupported CQI mode !!!"); - break; - - } - - break; - - case 100: - switch (uci_format) { - case wideband_cqi_rank1_2A: - ((wideband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((wideband_cqi_rank1_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); - break; - - case wideband_cqi_rank2_2A: - ((wideband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi - ((wideband_cqi_rank2_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); - break; - - case HLC_subband_cqi_nopmi: - ((HLC_subband_cqi_nopmi_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_nopmi_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); - break; - - case HLC_subband_cqi_rank1_2A: - ((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); - ((HLC_subband_cqi_rank1_2A_20MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); - break; - - case HLC_subband_cqi_rank2_2A: - // This has to be improved!!! - ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); - ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); - ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,13); - ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); - break; - - case HLC_subband_cqi_mcs_CBA: - // this is the cba mcs uci for cba transmission - ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; - ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti = rnti; - LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); - break; - - case ue_selected: - LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); - AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); - break; - - default: - LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); - AssertFatal(1==0,"unsupported CQI mode !!!"); - break; - - } - - break; - - } - - -} - -void reset_cba_uci(void *o) -{ - // this is the cba mcs uci for cba transmission - ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs = 0; //fixme - ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = 0x0; -} - - -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank) -{ - - uint8_t i,wideband_pmi2; - uint32_t pmi_ex = 0; - - if (frame_parms->N_RB_DL!=25) { - LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n"); - return(-1); - } - - if (rank==0) { - wideband_pmi2=wideband_pmi&3; - for (i=0; i<14; i+=2) - pmi_ex|=(wideband_pmi2<<i); - } - else if (rank==1) { - wideband_pmi2=wideband_pmi&1; - for (i=0; i<7; i++) - pmi_ex|=(wideband_pmi2<<i); - } - else { - LOG_E(PHY,"unsupported rank\n"); - return(-1); - } - - return(pmi_ex); -} - - -int generate_ue_ulsch_params_from_dci(void *dci_pdu, - uint16_t rnti, - uint8_t subframe, - DCI_format_t dci_format, - PHY_VARS_UE *ue, - UE_rxtx_proc_t *proc, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint16_t cba_rnti, - uint8_t eNB_id, - uint8_t use_srs) -{ - - uint8_t harq_pid; - uint8_t transmission_mode = ue->transmission_mode[eNB_id]; - ANFBmode_t AckNackFBMode; - LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - LTE_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[subframe]][0]; - PHY_MEASUREMENTS *meas = &ue->measurements; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - // uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; - - if(frame_parms->frame_type == TDD) - { - AckNackFBMode = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode; - } - else - { - AckNackFBMode = 1; // 1: multiplexing for FDD - } - - uint32_t cqi_req; - uint32_t dai=3; - uint32_t cshift; - uint32_t TPC; - uint32_t ndi; - uint32_t mcs; - uint32_t rballoc,RIV_max; - uint16_t* RIV2first_rb_LUT; - uint16_t* RIV2nb_rb_LUT; - - // uint32_t hopping; - // uint32_t type; - - if (dci_format == format0) { - - if (!ulsch) - return -1; - - if (rnti == ra_rnti) - harq_pid = 0; - else - harq_pid = subframe2harq_pid(frame_parms, - pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,subframe), - pdcch_alloc2ul_subframe(frame_parms,subframe)); - - if (harq_pid == 255) { - LOG_E(PHY, "frame %d, subframe %d, rnti %x, format %d: illegal harq_pid!\n", - proc->frame_rx, subframe, rnti, dci_format); - return(-1); - } - - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - ndi = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; - mcs = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi; - mcs = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max6; - RIV2first_rb_LUT = RIV2first_rb_LUT6; - RIV2nb_rb_LUT = RIV2nb_rb_LUT6; - - break; - - case 25: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - ndi = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi; - mcs = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi; - mcs = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_5MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max25; - RIV2first_rb_LUT = RIV2first_rb_LUT25; - RIV2nb_rb_LUT = RIV2nb_rb_LUT25; - // printf("***********rballoc %d, first_rb %d, nb_rb %d (dci %p)\n",rballoc,ulsch->harq_processes[harq_pid]->first_rb,ulsch->harq_processes[harq_pid]->nb_rb,dci_pdu); - break; - - case 50: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC; - ndi = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi; - mcs = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi; - mcs = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_10MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max50; - RIV2first_rb_LUT = RIV2first_rb_LUT50; - RIV2nb_rb_LUT = RIV2nb_rb_LUT50; - - break; - - case 100: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC; - ndi = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi; - mcs = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi; - mcs = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_20MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max100; - RIV2first_rb_LUT = RIV2first_rb_LUT100; - RIV2nb_rb_LUT = RIV2nb_rb_LUT100; - - // printf("rb_alloc (20 MHz dci) %d\n",rballoc); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - - - if (rballoc > RIV_max) { - LOG_E(PHY,"frame %d, subframe %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[%d] > RIV_max[%d]\n", - proc->frame_rx, subframe, rnti, dci_format,rballoc,RIV_max); - LOG_E(PHY,"Wrong DCI0 detection, do not transmit PUSCH for HARQID: %d\n",harq_pid); - ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - return(-1); - } - - - // indicate that this process is to be serviced in subframe n+4 - if ((rnti >= cba_rnti) && (rnti < p_rnti)) - ulsch->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; //+=1 this indicates the number of dci / cba group: not supported in the data struct - else - { - ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; - //LOG_I(PHY,"[HARQ-UL harqId: %d] DCI0 ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); - - } - - ulsch->harq_processes[harq_pid]->TPC = TPC; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT[rballoc]; - - if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n", - ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch, - delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC], - ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC); - ulsch->f_pusch += delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC]; - } else { - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ABS) %d, adjusting to %d (TPC %d)\n", - ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch, - delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC], - ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC); - ulsch->f_pusch = delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC]; - } - - if (ulsch->harq_processes[harq_pid]->first_tx==1) { - // ulsch->harq_processes[harq_pid]->Ndi = 1; - ulsch->harq_processes[harq_pid]->first_tx=0; - ulsch->harq_processes[harq_pid]->DCINdi= ndi; - ulsch->harq_processes[harq_pid]->round = 0; - } else { - if (ulsch->harq_processes[harq_pid]->DCINdi!=ndi) { // new SDU opportunity - // ulsch->harq_processes[harq_pid]->Ndi = 1; - ulsch->harq_processes[harq_pid]->DCINdi= ndi; - ulsch->harq_processes[harq_pid]->round = 0; - } else { - // ulsch->harq_processes[harq_pid]->Ndi = 0; - //ulsch->harq_processes[harq_pid]->round++; // This is done in phich RX - - //#ifdef DEBUG_PHICH - //LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d Adaptative Retrans, NDI not toggled => Nack. maxHARQ_Tx %d \n", - // ue->Mod_id,harq_pid, - // proc->frame_rx, - // subframe, - // ulsch->Mlimit); - //#endif -/* - if (ulsch->harq_processes[harq_pid]->round > 0) // NACK detected on phich - { - // ulsch->harq_processes[harq_pid]->round++; already done on phich_rx - // ulsch->harq_processes[harq_pid] = ulsch->harq_processes[8]; - // LOG_I(PHY," Adaptative retransmission - copy temporary harq Process to current harq process. [harqId %d round %d] \n",harq_pid, ulsch->harq_processes[8]->round); - - if (ulsch->harq_processes[harq_pid]->round >= ulsch->Mlimit) //UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx) - { - ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - ulsch->harq_processes[harq_pid]->round = 0; - ulsch->harq_processes[harq_pid]->status = IDLE; - //LOG_I(PHY," PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid); - //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); - } - else - { - // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; - uint8_t rv_table[4] = {0, 2, 3, 1}; - ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; - ulsch->O_RI = 0; - ulsch->O = 0; - ulsch->uci_format = HLC_subband_cqi_nopmi; - //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round); - } - } -*/ - } - } - - ulsch->harq_processes[harq_pid]->n_DMRS = cshift; - - //printf("nb_rb %d, first_rb %d (RIV %d)\n",ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,rballoc); - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - // ulsch->cba_rnti[0]=rnti; - } else { - ulsch->rnti = rnti; - } - - // printf("[PHY][UE] DCI format 0: harq_pid %d nb_rb %d, rballoc %d\n",harq_pid,ulsch->harq_processes[harq_pid]->nb_rb, - // ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc); - //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) - if(cshift == 0) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; - else if(cshift == 1) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 6; - else if(cshift == 2) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 3; - else if(cshift == 3) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 4; - else if(cshift == 4) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 2; - else if(cshift == 5) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 8; - else if(cshift == 6) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; - else if(cshift == 7) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; - - - //reserved for cooperative communication - /* - if(ulsch->n_DMRS2 == 6) - ulsch->cooperation_flag = 2; - else - ulsch->cooperation_flag = 0; - */ - - if ((ulsch->harq_processes[harq_pid]->nb_rb>0) && (ulsch->harq_processes[harq_pid]->nb_rb < 25)) - ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb-1]; - - // if (ulsch->harq_processes[harq_pid]->Ndi == 1) - // ulsch->harq_processes[harq_pid]->status = ACTIVE; - - - if (cqi_req == 1) { - - if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) ) - { - ulsch->O_RI = 1; - } - else - { - ulsch->O_RI = 0; - } - //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table - - switch(transmission_mode) { - // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling - case 1: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - case 2: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - case 3: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - case 4: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank1_2A; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank2_2A; - ulsch->o_RI[0] = 1; - } - - break; - - case 5: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank1_2A; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank2_2A; - ulsch->o_RI[0] = 1; - } - - break; - - case 6: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank1_2A; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank2_2A; - ulsch->o_RI[0] = 1; - } - - break; - - case 7: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - default: - LOG_E(PHY,"Incorrect Transmission Mode \n"); - break; - } - } else { - ulsch->O_RI = 0; - ulsch->O = 0; - ulsch->uci_format = HLC_subband_cqi_nopmi; - } - - print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL); - - ulsch->bundling = 1-AckNackFBMode; - - if (frame_parms->frame_type == FDD) { - //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); - int dl_subframe = subframe; - - if (ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission - ulsch->harq_processes[harq_pid]->O_ACK = 1; - } else { - ulsch->harq_processes[harq_pid]->O_ACK = 0; - } - /*LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe, - ue->dlsch[0][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, - ue->dlsch[1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, - harq_pid, - ulsch->harq_processes[harq_pid]->O_ACK);*/ - - } else { - if (ulsch->bundling) - ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1; - else - ulsch->harq_processes[harq_pid]->O_ACK = (dai >= 2)? 2 : (dai+1)&3; //(dai+1)&3; - - // ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1; - } - - dlsch[0]->harq_ack[subframe].vDAI_UL = dai+1; - - - /*LOG_I(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d" - " ulsch->bundling %d, O_ACK %d \n", - harq_pid, - (frame_parms->frame_type == TDD? "TDD" : "FDD"), - cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc, - ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb, - ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, - ulsch->bundling, - ulsch->harq_processes[harq_pid]->O_ACK);*/ - LOG_D(PHY,"Setting beta_offset_cqi_times8 to %d, index %d\n", - beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index], - ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index); - - ulsch->beta_offset_cqi_times8 = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18; - ulsch->beta_offset_ri_times8 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10; - ulsch->beta_offset_harqack_times8 = beta_ack[ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index];//16; - - ulsch->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); - ulsch->srs_active = use_srs; - - if ((rnti >= cba_rnti) && (rnti < p_rnti)) - ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; - else - ulsch->harq_processes[harq_pid]->status = ACTIVE; - - ulsch->harq_processes[harq_pid]->rvidx = 0; - - // ulsch->harq_processes[harq_pid]->calibration_flag =0; - if (mcs < 29) { - ulsch->harq_processes[harq_pid]->mcs = mcs; - // ulsch->harq_processes[harq_pid]->round = 0; - } else { - ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; - if (ulsch->harq_processes[harq_pid]->round == 0) { - LOG_W(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); - } else { - LOG_D(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); - } - //LOG_E(PHY,"Fatal: mcs(%d) > 28!!! and round == 0\n", mcs); - } - ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; - - /* - else if (ulsch->harq_processes[harq_pid]->mcs == 29) { - ulsch->harq_processes[harq_pid]->mcs = 4; - ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; - // ulsch->harq_processes[harq_pid]->calibration_flag =1; - // printf("Auto-Calibration (UE): mcs %d, TBS %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->TBS,ulsch->harq_processes[harq_pid]->nb_rb); - }*/ - ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; - ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->Nsymb_pusch; - - // a Ndi=1 automatically acknowledges previous PUSCH transmission - if (ue->ulsch_Msg3_active[eNB_id] == 1) - ue->ulsch_Msg3_active[eNB_id] = 0; - - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d, cqi_req %d => O %d\n", - ue->Mod_id,harq_pid, - proc->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb, - ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id],cqi_req,ulsch->O); - - // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; - -#ifdef UE_DEBUG_TRACE - - LOG_I(PHY,"Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe); - LOG_D(PHY,"Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): rballoc %d\n",rballoc); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): harq_pid %d\n",harq_pid); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_tx %d\n",ulsch->harq_processes[harq_pid]->first_tx); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): DCINdi %d\n",ulsch->harq_processes[harq_pid]->DCINdi); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): round %d\n",ulsch->harq_processes[harq_pid]->round); - //LOG_I(PHY,"Format 0 DCI :ulsch (ue): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); - //LOG_I(PHY,"Format 0 DCI :ulsch (ue): O %d\n",ulsch->O); - //LOG_I(PHY,"Format 0 DCI :ulsch (ue): cqiReq %d\n",cqi_req); - //if (frame_parms->frame_type == TDD) - // LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK/DAI %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai); - //else - // LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK %d\n",ulsch->harq_processes[harq_pid]->O_ACK); - - LOG_D(PHY,"Format 0 DCI :ulsch (ue): Nsymb_pusch %d\n",ulsch->Nsymb_pusch); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); - LOG_D(PHY,"Format 0 DCI :ulsch (ue): phich status %d\n",ulsch->harq_processes[harq_pid]->status); -#else - UNUSED_VARIABLE(dai); -#endif - return(0); - } else { - LOG_E(PHY,"frame %d, subframe %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n", - proc->frame_rx, subframe,dci_format); - return(-1); - } - -} - -/* -int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, - void *dci_pdu, - uint16_t rnti, - DCI_format_t dci_format, - uint8_t UE_id, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint16_t cba_rnti, - uint8_t use_srs) -{ - - uint8_t harq_pid; - uint32_t rb_alloc; - uint8_t transmission_mode=eNB->transmission_mode[UE_id]; - ANFBmode_t AckNackFBMode = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode; - LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; - int subframe = proc->subframe_tx; - - uint32_t cqi_req = 0; - uint32_t dai = 0; - uint32_t cshift = 0; - uint32_t TPC = 0; - uint32_t mcs = 0; - uint32_t rballoc = UINT32_MAX; - uint32_t RIV_max = 0; - // uint32_t hopping; - // uint32_t type; - -#ifdef DEBUG_DCI - printf("filling eNB ulsch params for rnti %x, dci format %d, dci %x, subframe %d\n", - rnti,dci_format,*(uint32_t*)dci_pdu,subframe); -#endif - - if (dci_format == format0) { - - harq_pid = subframe2harq_pid(frame_parms, - pdcch_alloc2ul_frame(frame_parms, - proc->frame_tx, - subframe), - pdcch_alloc2ul_subframe(frame_parms,subframe)); - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - mcs = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC; - mcs = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping; - // type = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max6; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT6[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT6[rballoc]; - - break; - - case 25: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - mcs = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping; - // type = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC; - mcs = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping; - // type = ((DCI0_5MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max25; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT25[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT25[rballoc]; - - break; - - case 50: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC; - mcs = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping; - // type = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC; - mcs = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping; - // type = ((DCI0_10MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max50; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT50[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT50[rballoc]; - - break; - - case 100: - if (frame_parms->frame_type == TDD) { - cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req; - dai = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai; - cshift = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift; - TPC = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC; - mcs = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping; - // type = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type; - } else { - cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req; - cshift = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift; - TPC = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC; - mcs = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc; - // hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping; - // type = ((DCI0_20MHz_FDD_t *)dci_pdu)->type; - } - - RIV_max = RIV_max100; - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT100[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT100[rballoc]; - - //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc); - break; - - default: - LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); - DevParam (frame_parms->N_RB_DL, 0, 0); - break; - } - - - rb_alloc = rballoc; - AssertFatal(rb_alloc>RIV_max, - "Format 0: rb_alloc (%d) > RIV_max (%d)\n",rb_alloc,RIV_max); -#ifdef DEBUG_DCI - printf("generate_eNB_ulsch_params_from_dci: subframe %d, rnti %x,harq_pid %d,cqi_req %d\n",subframe,rnti,harq_pid,cqi_req); -#endif - - ulsch->harq_processes[harq_pid]->dci_alloc = 1; - ulsch->harq_processes[harq_pid]->rar_alloc = 0; - ulsch->harq_processes[harq_pid]->TPC = TPC; - ulsch->harq_processes[harq_pid]->n_DMRS = cshift; - - - if (cqi_req == 1) { - // 36.213 7.2.1 (release 10) says: - // "RI is only reported for transmission modes 3 and 4, - // as well as transmission modes 8 and 9 with PMI/RI reporting" - // This is for aperiodic reporting. - // TODO: deal with TM 8&9 correctly when they are implemented. - // TODO: deal with periodic reporting if we implement it. - // - if (transmission_mode == 3 || transmission_mode == 4) - ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table - else - ulsch->harq_processes[harq_pid]->O_RI = 0; - - switch(transmission_mode) { - // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling - case 1: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; - } else { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; - } - - break; - - case 2: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; - } else { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; - } - - break; - - case 3: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; - } else { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; - } - - break; - - case 4: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; - } else { - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - - } - - ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; - } - - break; - - case 5: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; - } else { - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; - } - - break; - - case 6: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; - } else { - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; - ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; - } - - break; - - case 7: - ulsch->harq_processes[harq_pid]->Or2 = 0; - - switch (frame_parms->N_RB_DL) { - case 6: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; - break; - - default: - LOG_E(PHY,"Incorrect Transmission Mode \n"); - break; - } - } else { - ulsch->harq_processes[harq_pid]->O_RI = 0; - ulsch->harq_processes[harq_pid]->Or2 = 0; - ulsch->harq_processes[harq_pid]->Or1 = 0; - ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; - } - - ulsch->bundling = 1-AckNackFBMode; - - if (frame_parms->frame_type == FDD) { - int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); - - if (eNB->dlsch[UE_id][0]->subframe_tx[dl_subframe]>0) { // we have downlink transmission - ulsch->harq_processes[harq_pid]->O_ACK = 1; - } else { - ulsch->harq_processes[harq_pid]->O_ACK = 0; - } - } else { - if (ulsch->bundling) - ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1; - else - ulsch->harq_processes[harq_pid]->O_ACK = (dai+1)&3; - - ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1; - } - - ulsch->beta_offset_cqi_times8 = beta_cqi[eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index];//18; - ulsch->beta_offset_ri_times8 = beta_ri[eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index];//10; - ulsch->beta_offset_harqack_times8 = beta_ack[eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index];//16; - - ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); - ulsch->harq_processes[harq_pid]->srs_active = use_srs; - - //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) - if(cshift == 0) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; - else if(cshift == 1) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 6; - else if(cshift == 2) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 3; - else if(cshift == 3) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 4; - else if(cshift == 4) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 2; - else if(cshift == 5) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 8; - else if(cshift == 6) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; - else if(cshift == 7) - ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; - - - LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d)\n", - eNB->Mod_id,harq_pid,proc->frame_tx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift); - - - - if (ulsch->harq_processes[harq_pid]->round == 0) { - if ((rnti >= cba_rnti) && (rnti < p_rnti)) - ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; - else - ulsch->harq_processes[harq_pid]->status = ACTIVE; - - ulsch->harq_processes[harq_pid]->rvidx = 0; - ulsch->harq_processes[harq_pid]->mcs = mcs; - // ulsch->harq_processes[harq_pid]->calibration_flag = 0; - //if (ulsch->harq_processes[harq_pid]->mcs) - // - //if (ulsch->harq_processes[harq_pid]->mcs == 29) { - //ulsch->harq_processes[harq_pid]->mcs = 4; - // ulsch->harq_processes[harq_pid]->calibration_flag = 1; - // printf("Auto-Calibration (eNB): mcs %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->nb_rb); - //} - - ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; - - ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; - ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch; - ulsch->harq_processes[harq_pid]->round = 0; - } else { - if (mcs>28) - ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; - else { - ulsch->harq_processes[harq_pid]->rvidx = 0; - ulsch->harq_processes[harq_pid]->mcs = mcs; - } - - // ulsch->harq_processes[harq_pid]->round++; - } - - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - ulsch->cba_rnti[0] = rnti; - } else { - ulsch->rnti = rnti; - } - - //ulsch->n_DMRS2 = cshift; - -#ifdef DEBUG_DCI - printf("ulsch (eNB): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); - printf("ulsch (eNB): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb); - printf("ulsch (eNB): harq_pid %d\n",harq_pid); - printf("ulsch (eNB): round %d\n",ulsch->harq_processes[harq_pid]->round); - printf("ulsch (eNB): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); - printf("ulsch (eNB): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); - printf("ulsch (eNB): Or1 %d\n",ulsch->harq_processes[harq_pid]->Or1); - printf("ulsch (eNB): Nsymb_pusch %d\n",ulsch->harq_processes[harq_pid]->Nsymb_pusch); - printf("ulsch (eNB): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); -#else - UNUSED_VARIABLE(dai); -#endif - return(0); - } else { - LOG_E(PHY,"generate_eNB_ulsch_params_from_dci, Illegal dci_format %d\n",dci_format); - return(-1); - } - -} -*/ - -double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe) -{ - uint8_t transmission_mode = ue->transmission_mode[eNB_id]; - PHY_MEASUREMENTS *meas = &ue->measurements; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; - double *s_dB; - s_dB = ue->sinr_CQI_dB; - // LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - //for the calculation of SINR_eff for CQI calculation - int count,a_rx,a_tx; - double abs_channel=0; - double channelx=0; - double channely=0; - double channelx_i=0; - double channely_i=0; - uint16_t q = quantize_subband_pmi(meas,eNB_id,7); - uint8_t qq; - - switch(transmission_mode) { - case 1: - for (count=0; count<frame_parms->N_RB_DL*12; count++) { - for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { - for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { - s_dB[count] = 10*log10(pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2], - 2)) - meas->n0_power_avg_dB; - } - } - } - - break; - - case 2: - for (count=0; count<frame_parms->N_RB_DL*12; count++) { - abs_channel=0; - - for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { - for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { - abs_channel += (pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],2)); - } - } - - s_dB[count] = 10*log10(abs_channel/2) - meas->n0_power_avg_dB; - } - - break; - - case 5: - for (count=0; count<frame_parms->N_RB_DL*12; count++) { - channelx=0; - channely=0; - channelx_i=0; - channely_i=0; - qq = (q>>(((count/12)>>2)<<1))&3; - - //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq); - for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { - for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { - switch(qq) { - case 0: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - case 1: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - case 2: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - case 3: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - default: - printf("Problem in SINR Calculation for TM5 \n"); - break; - }//switch(qq) - }//a_rx - }//a_tx - - s_dB[count] = 10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - 10 * log10 ((pow(channelx_i,2) + pow(channely_i,2))/2) - meas->n0_power_avg_dB; - }//count - - break; - - case 6: - for (count=0; count<frame_parms->N_RB_DL*12; count++) { - channelx=0; - channely=0; - qq = (q>>(((count/12)>>2)<<1))&3; - - //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq); - for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { - for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { - switch(qq) { - case 0: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - case 1: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - case 2: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - case 3: - if (channelx==0 || channely==0) { - channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - } else { - channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; - channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; - } - - break; - - default: - printf("Problem in SINR Calculation for TM6 \n"); - break; - }//switch(qq) - }//a_rx - }//a_tx - - s_dB[count] = 10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - meas->n0_power_avg_dB; - }//count - - break; - - default: - printf("Problem in SINR Calculation for CQI \n"); - break; - } - - int ii; - double sinr_eff = 0; - double sinr_eff_qpsk=0; - double sinr_eff_qam16=0; - double sinr_eff_qam64=0; - double x = 0; - double I_qpsk=0; - double I_qam16=0; - double I_qam64=0; - double I_qpsk_avg=0; - double I_qam16_avg=0; - double I_qam64_avg=0; - double qpsk_max=12.2; - double qam16_max=19.2; - double qam64_max=25.2; - double sinr_min = -20; - int offset=0; - - - for (offset = 0; offset <= 24; offset++) { - for(ii=0; ii<12; ii++) { - //x is the sinr_dB in dB - x = s_dB[(offset*12)+ii]; - - if(x<sinr_min) { - I_qpsk +=0; - I_qam16 +=0; - I_qam64 +=0; - } else { - if(x>qpsk_max) - I_qpsk += 1; - else - I_qpsk += (q_qpsk[0]*pow(x,7) + q_qpsk[1]*pow(x,6) + q_qpsk[2]*pow(x,5) + q_qpsk[3]*pow(x,4) + q_qpsk[4]*pow(x,3) + q_qpsk[5]*pow(x,2) + q_qpsk[6]*x + q_qpsk[7]); - - if(x>qam16_max) - I_qam16 += 1; - else - I_qam16 += (q_qam16[0]*pow(x,7) + q_qam16[1]*pow(x,6) + q_qam16[2]*pow(x,5) + q_qam16[3]*pow(x,4) + q_qam16[4]*pow(x,3) + q_qam16[5]*pow(x,2) + q_qam16[6]*x + q_qam16[7]); - - if(x>qam64_max) - I_qam64 += 1; - else - I_qam64 += (q_qam64[0]*pow(x,7) + q_qam64[1]*pow(x,6) + q_qam64[2]*pow(x,5) + q_qam64[3]*pow(x,4) + q_qam64[4]*pow(x,3) + q_qam64[5]*pow(x,2) + q_qam64[6]*x + q_qam64[7]); - - } - } - } - - // averaging of accumulated MI - I_qpsk_avg = I_qpsk/(12*frame_parms->N_RB_DL); - I_qam16_avg = I_qam16/(12*frame_parms->N_RB_DL); - I_qam64_avg = I_qam64/(12*frame_parms->N_RB_DL); - - // I->SINR_effective Mapping - - sinr_eff_qpsk = (p_qpsk[0]*pow(I_qpsk_avg,7) + p_qpsk[1]*pow(I_qpsk_avg,6) + p_qpsk[2]*pow(I_qpsk_avg,5) + p_qpsk[3]*pow(I_qpsk_avg,4) + p_qpsk[4]*pow(I_qpsk_avg,3) + p_qpsk[5]*pow(I_qpsk_avg, - 2) + p_qpsk[6]*I_qpsk_avg + p_qpsk[7]); - - sinr_eff_qam16 = (p_qam16[0]*pow(I_qam16_avg,7) + p_qam16[1]*pow(I_qam16_avg,6) + p_qam16[2]*pow(I_qam16_avg,5) + p_qam16[3]*pow(I_qam16_avg,4) + p_qam16[4]*pow(I_qam16_avg, - 3) + p_qam16[5]*pow(I_qam16_avg,2) + p_qam16[6]*I_qam16_avg + p_qam16[7]); - - sinr_eff_qam64 = (p_qam64[0]*pow(I_qam64_avg,7) + p_qam64[1]*pow(I_qam64_avg,6) + p_qam64[2]*pow(I_qam64_avg,5) + p_qam64[3]*pow(I_qam64_avg,4) + p_qam64[4]*pow(I_qam64_avg, - 3) + p_qam64[5]*pow(I_qam64_avg,2) + p_qam64[6]*I_qam64_avg + p_qam64[7]); - sinr_eff = cmax3(sinr_eff_qpsk,sinr_eff_qam16,sinr_eff_qam64); - - //printf("SINR_Eff = %e\n",sinr_eff); - - return(sinr_eff); -} -// - - - -#ifdef DEBUG_DLSCH_TOOLS -main() -{ - - int i; - uint8_t rah; - uint32_t rballoc; - - generate_RIV_tables(); - - rah = 0; - rballoc = 0x1fff; - printf("rballoc 0 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); - rah = 1; - - rballoc = 0x1678; - printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); - - rballoc = 0xfffc; - printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); - rballoc = 0xfffd; - printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); - rballoc = 0xffff; - printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); - rballoc = 0xfffe; - printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); -} - -#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c new file mode 100644 index 0000000000000000000000000000000000000000..1b5773320071d8d11eb975575ce27f25eee9bbe0 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c @@ -0,0 +1,2278 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/dci_tools.c + * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler. + * \author R. Knopp + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ + +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" +#ifdef DEBUG_DCI_TOOLS +#include "PHY/phy_vars.h" +#endif +#include "assertions.h" +#include "nfapi_interface.h" +#include "transport_common_proto.h" +#include "SCHED/sched_common.h" +//#define DEBUG_HARQ + + +#include "LAYER2/MAC/mac.h" + +//#define DEBUG_DCI + +uint32_t localRIV2alloc_LUT6[32]; +uint32_t distRIV2alloc_even_LUT6[32]; +uint32_t distRIV2alloc_odd_LUT6[32]; +uint16_t RIV2nb_rb_LUT6[32]; +uint16_t RIV2first_rb_LUT6[32]; +uint16_t RIV_max6=0; + +uint32_t localRIV2alloc_LUT25[512]; +uint32_t distRIV2alloc_even_LUT25[512]; +uint32_t distRIV2alloc_odd_LUT25[512]; +uint16_t RIV2nb_rb_LUT25[512]; +uint16_t RIV2first_rb_LUT25[512]; +uint16_t RIV_max25=0; + + +uint32_t localRIV2alloc_LUT50_0[1600]; +uint32_t localRIV2alloc_LUT50_1[1600]; +uint32_t distRIV2alloc_gap0_even_LUT50_0[1600]; +uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600]; +uint32_t distRIV2alloc_gap0_even_LUT50_1[1600]; +uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600]; +uint32_t distRIV2alloc_gap1_even_LUT50_0[1600]; +uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600]; +uint32_t distRIV2alloc_gap1_even_LUT50_1[1600]; +uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600]; +uint16_t RIV2nb_rb_LUT50[1600]; +uint16_t RIV2first_rb_LUT50[1600]; +uint16_t RIV_max50=0; + +uint32_t localRIV2alloc_LUT100_0[6000]; +uint32_t localRIV2alloc_LUT100_1[6000]; +uint32_t localRIV2alloc_LUT100_2[6000]; +uint32_t localRIV2alloc_LUT100_3[6000]; +uint32_t distRIV2alloc_gap0_even_LUT100_0[6000]; +uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000]; +uint32_t distRIV2alloc_gap0_even_LUT100_1[6000]; +uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000]; +uint32_t distRIV2alloc_gap0_even_LUT100_2[6000]; +uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000]; +uint32_t distRIV2alloc_gap0_even_LUT100_3[6000]; +uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000]; +uint32_t distRIV2alloc_gap1_even_LUT100_0[6000]; +uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000]; +uint32_t distRIV2alloc_gap1_even_LUT100_1[6000]; +uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000]; +uint32_t distRIV2alloc_gap1_even_LUT100_2[6000]; +uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000]; +uint32_t distRIV2alloc_gap1_even_LUT100_3[6000]; +uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000]; +uint16_t RIV2nb_rb_LUT100[6000]; +uint16_t RIV2first_rb_LUT100[6000]; +uint16_t RIV_max100=0; + +extern RAN_CONTEXT_t RC; + +extern uint32_t current_dlsch_cqi; + +// Table 8.6.3-3 36.213 +uint16_t beta_cqi[16] = {0, //reserved + 0, //reserved + 9, //1.125 + 10, //1.250 + 11, //1.375 + 13, //1.625 + 14, //1.750 + 16, //2.000 + 18, //2.250 + 20, //2.500 + 23, //2.875 + 25, //3.125 + 28, //3.500 + 32, //4.000 + 40, //5.000 + 50 + }; //6.250 + +// Table 8.6.3-2 36.213 +uint16_t beta_ri[16] = {10, //1.250 + 13, //1.625 + 16, //2.000 + 20, //2.500 + 25, //3.125 + 32, //4.000 + 40, //5.000 + 50, //6.250 + 64, //8.000 + 80, //10.000 + 101, //12.625 + 127, //15.875 + 160, //20.000 + 0, //reserved + 0, //reserved + 0 + }; //reserved + +// Table 8.6.3-2 36.213 +uint16_t beta_ack[16] = {16, //2.000 + 20, //2.500 + 25, //3.125 + 32, //4.000 + 40, //5.000 + 50, //6.250 + 64, //8.000 + 80, //10.000 + 101, //12.625 + 127, //15.875 + 160, //20.000 + 248, //31.000 + 400, //50.000 + 640, //80.000 + 808 + };//126.00 + +int8_t delta_PUSCH_abs[4] = {-4,-1,1,4}; +int8_t delta_PUSCH_acc[4] = {-1,0,1,3}; + +int8_t *delta_PUCCH_lut = delta_PUSCH_acc; + +uint8_t get_pmi(uint8_t N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb) +{ + /* + MIMO_mode_t mode = dlsch_harq->mimo_mode; + uint32_t pmi_alloc = dlsch_harq->pmi_alloc; + */ + + switch (N_RB_DL) { + case 6: // 1 PRB per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>(rb<<1))&3); + else + return((pmi_alloc>>rb)&1); + + break; + + default: + case 25: // 4 PRBs per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>((rb>>2)<<1))&3); + else + return((pmi_alloc>>(rb>>2))&1); + + break; + + case 50: // 6 PRBs per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>((rb/6)<<1))&3); + else + return((pmi_alloc>>(rb/6))&1); + + break; + + case 100: // 8 PRBs per subband + if (mode <= PUSCH_PRECODING1) + return((pmi_alloc>>((rb>>3)<<1))&3); + else + return((pmi_alloc>>(rb>>3))&1); + + break; + } +} + +uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi) +{ + + uint16_t i; + uint16_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; + uint16_t mprime; + uint16_t *pcfich_reg = frame_parms->pcfich_reg; + + if ((lprime>0) && (frame_parms->Ncp==0) ) + return(0); + + // printf("check_phich_reg : mi %d\n",mi); + + // compute REG based on symbol + if ((lprime == 0)|| + ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) + mprime = kprime/6; + else + mprime = kprime>>2; + + // check if PCFICH uses mprime + if ((lprime==0) && + ((mprime == pcfich_reg[0]) || + (mprime == pcfich_reg[1]) || + (mprime == pcfich_reg[2]) || + (mprime == pcfich_reg[3]))) { +#ifdef DEBUG_DCI_ENCODING + printf("[PHY] REG %d allocated to PCFICH\n",mprime); +#endif + return(1); + } + + // handle Special subframe case for TDD !!! + + // printf("Checking phich_reg %d\n",mprime); + if (mi > 0) { + if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) + Ngroup_PHICH++; + + if (frame_parms->Ncp == 1) { + Ngroup_PHICH<<=1; + } + + + + for (i=0; i<Ngroup_PHICH; i++) { + if ((mprime == frame_parms->phich_reg[i][0]) || + (mprime == frame_parms->phich_reg[i][1]) || + (mprime == frame_parms->phich_reg[i][2])) { +#ifdef DEBUG_DCI_ENCODING + printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime); +#endif + return(1); + } + } + } + + return(0); +} + +uint16_t get_nquad(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi) +{ + + uint16_t Nreg=0; + uint8_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; + + if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) + Ngroup_PHICH++; + + if (frame_parms->Ncp == 1) { + Ngroup_PHICH<<=1; + } + + Ngroup_PHICH*=mi; + + if ((num_pdcch_symbols>0) && (num_pdcch_symbols<4)) + switch (frame_parms->N_RB_DL) { + case 6: + Nreg=12+(num_pdcch_symbols-1)*18; + break; + + case 25: + Nreg=50+(num_pdcch_symbols-1)*75; + break; + + case 50: + Nreg=100+(num_pdcch_symbols-1)*150; + break; + + case 100: + Nreg=200+(num_pdcch_symbols-1)*300; + break; + + default: + return(0); + } + + // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); + return(Nreg - 4 - (3*Ngroup_PHICH)); +} + +uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi) +{ + return(get_nquad(num_pdcch_symbols,frame_parms,mi)/9); +} + + + +uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe) +{ + + // check for eNB only ! + return(get_nCCE(num_pdcch_symbols, + &RC.eNB[Mod_id][CC_id]->frame_parms, + get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe))); +} + + +void conv_eMTC_rballoc(uint16_t resource_block_coding, + uint32_t N_RB_DL, + uint32_t *rb_alloc) { + + + int narrowband = resource_block_coding>>5; + int RIV = resource_block_coding&31; + int N_NB_DL = N_RB_DL/6; + int i0 = (N_RB_DL>>1) - (3*N_NB_DL); + int first_rb = (6*narrowband)+i0; + int alloc = localRIV2alloc_LUT6[RIV]; + int ind = first_rb>>5; + int ind_mod = first_rb&31; + + if (((N_RB_DL&1) > 0) && (narrowband>=(N_NB_DL>>1))) first_rb++; + rb_alloc[0] = 0; + rb_alloc[1] = 0; + rb_alloc[2] = 0; + rb_alloc[3] = 0; + rb_alloc[ind] = alloc<<ind_mod; + if (ind_mod > 26) rb_alloc[ind+1] = alloc>>(6-(ind_mod-26)); +} + +void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2) +{ + + uint32_t i,shift,subset; + rb_alloc2[0] = 0; + rb_alloc2[1] = 0; + rb_alloc2[2] = 0; + rb_alloc2[3] = 0; + + // printf("N_RB_DL %d, ra_header %d, rb_alloc %x\n",N_RB_DL,ra_header,rb_alloc); + + switch (N_RB_DL) { + + case 6: + rb_alloc2[0] = rb_alloc&0x3f; + break; + + case 25: + if (ra_header == 0) {// Type 0 Allocation + + for (i=12; i>0; i--) { + if ((rb_alloc&(1<<i)) != 0) + rb_alloc2[0] |= (3<<((2*(12-i)))); + + // printf("rb_alloc2 (type 0) %x\n",rb_alloc2); + } + + if ((rb_alloc&1) != 0) + rb_alloc2[0] |= (1<<24); + } else { + subset = rb_alloc&1; + shift = (rb_alloc>>1)&1; + + for (i=0; i<11; i++) { + if ((rb_alloc&(1<<(i+2))) != 0) + rb_alloc2[0] |= (1<<(2*i)); + + //printf("rb_alloc2 (type 1) %x\n",rb_alloc2); + } + + if ((shift == 0) && (subset == 1)) + rb_alloc2[0]<<=1; + else if ((shift == 1) && (subset == 0)) + rb_alloc2[0]<<=4; + else if ((shift == 1) && (subset == 1)) + rb_alloc2[0]<<=3; + } + + break; + + case 50: + AssertFatal(ra_header==0,"resource type 1 not supported for N_RB_DL=50\n"); + + for (i=16; i>0; i--) { + if ((rb_alloc&(1<<i)) != 0) + rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32)); + } + + // bit mask across + if ((rb_alloc2[0]>>31)==1) + rb_alloc2[1] |= 1; + + if ((rb_alloc&1) != 0) + rb_alloc2[1] |= (3<<16); + break; + + case 100: + AssertFatal(ra_header==0,"resource type 1 not supported for N_RB_DL=100\n"); + for (i=0; i<25; i++) { + if ((rb_alloc&(1<<(24-i))) != 0) + rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32)); + + // printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i)); + } + + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", N_RB_DL); + DevParam (N_RB_DL, 0, 0); + break; + } + +} + + + +uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL) +{ + + uint32_t nprb=0,i; + + switch (N_RB_DL) { + case 6: + for (i=0; i<6; i++) { + if ((rb_alloc&(1<<i)) != 0) + nprb += 1; + } + + break; + + case 25: + if (ra_header == 0) {// Type 0 Allocation + + for (i=12; i>0; i--) { + if ((rb_alloc&(1<<i)) != 0) + nprb += 2; + } + + if ((rb_alloc&1) != 0) + nprb += 1; + } else { + for (i=0; i<11; i++) { + if ((rb_alloc&(1<<(i+2))) != 0) + nprb += 1; + } + } + + break; + + case 50: + if (ra_header == 0) {// Type 0 Allocation + + for (i=0; i<16; i++) { + if ((rb_alloc&(1<<(16-i))) != 0) + nprb += 3; + } + + if ((rb_alloc&1) != 0) + nprb += 2; + + } else { + for (i=0; i<17; i++) { + if ((rb_alloc&(1<<(i+2))) != 0) + nprb += 1; + } + } + + break; + + case 100: + if (ra_header == 0) {// Type 0 Allocation + + for (i=0; i<25; i++) { + if ((rb_alloc&(1<<(24-i))) != 0) + nprb += 4; + } + } else { + for (i=0; i<25; i++) { + if ((rb_alloc&(1<<(i+2))) != 0) + nprb += 1; + } + } + + break; + + default: + LOG_E(PHY,"Invalide N_RB_DL %d\n", N_RB_DL); + DevParam (N_RB_DL, 0, 0); + break; + } + + return(nprb); +} + +uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) +{ + + uint16_t RIV; + + if (Lcrbs<=(1+(N_RB_DL>>1))) + RIV = (N_RB_DL*(Lcrbs-1)) + RBstart; + else + RIV = (N_RB_DL*(N_RB_DL+1-Lcrbs)) + (N_RB_DL-1-RBstart); + + return(RIV); +} + +// Convert a DCI Format 1C RIV to a Format 1A RIV +// This extracts the start and length in PRBs from the 1C rballoc and +// recomputes the RIV as if it were the 1A rballoc + +uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) { + + int NpDLVRB,N_RB_step,LpCRBsm1,RBpstart; + + switch (N_RB_DL) { + + case 6: // N_RB_step = 2, NDLVRB = 6, NpDLVRB = 3 + NpDLVRB = 3; + N_RB_step = 2; + break; + case 25: // N_RB_step = 2, NDLVRB = 24, NpDLVRB = 12 + NpDLVRB = 12; + N_RB_step = 2; + break; + case 50: // N_RB_step = 4, NDLVRB = 46, NpDLVRB = 11 + NpDLVRB = 11; + N_RB_step = 4; + break; + case 100: // N_RB_step = 4, NDLVRB = 96, NpDLVRB = 24 + NpDLVRB = 24; + N_RB_step = 4; + break; + default: + NpDLVRB = 24; + N_RB_step = 4; + break; + } + + // This is the 1C part from 7.1.6.3 in 36.213 + LpCRBsm1 = rballoc/NpDLVRB; + // printf("LpCRBs = %d\n",LpCRBsm1+1); + + if (LpCRBsm1 <= (NpDLVRB/2)) { + RBpstart = rballoc % NpDLVRB; + } + else { + LpCRBsm1 = NpDLVRB-LpCRBsm1; + RBpstart = NpDLVRB-(rballoc%NpDLVRB); + } + // printf("RBpstart %d\n",RBpstart); + return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1))); + +} + +uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { + + int offset; + + switch (N_RB_DL) { + + case 6: + // N_RB_DL = tildeN_RB_DL = 6 + // Ngap = 4 , P=1, Nrow = 2, Nnull = 2 + + switch (vrb) { + case 0: // even: 0->0, 1->2, odd: 0->3, 1->5 + case 1: + return ((3*odd_slot) + 2*(vrb&3))%6; + break; + case 2: // even: 2->3, 3->5, odd: 2->0, 3->2 + case 3: + return ((3*odd_slot) + 2*(vrb&3) + 5)%6; + break; + case 4: // even: 4->1, odd: 4->4 + return ((3*odd_slot) + 1)%6; + case 5: // even: 5->4, odd: 5->1 + return ((3*odd_slot) + 4)%6; + break; + } + break; + + case 15: + if (vrb<12) { + if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11 + return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); + else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13 + return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); + } + if (vrb==12) + return (3+(7*odd_slot)) % 14; + if (vrb==13) + return (10+(7*odd_slot)) % 14; + return 14; + break; + + case 25: + return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); + break; + + case 50: // P=3 + if (Ngap==0) { + // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27 + if (vrb>=23) + offset=4; + else + offset=0; + if (vrb<44) { + if ((vrb&3)>=2) + return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; + else + return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; + } + if (vrb==44) // even: 44->11, odd: 45->34 + return offset+((23*odd_slot) + 22-12+1); + if (vrb==45) // even: 45->10, odd: 45->33 + return offset+((23*odd_slot) + 22+12); + if (vrb==46) + return offset+46+((23*odd_slot) + 23-12+1) % 46; + if (vrb==47) + return offset+46+((23*odd_slot) + 23+12) % 46; + if (vrb==48) + return offset+46+((23*odd_slot) + 23-12+1) % 46; + if (vrb==49) + return offset+46+((23*odd_slot) + 23+12) % 46; + } + else { + // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27 + if (vrb>=9) + offset=18; + else + offset=0; + + if (vrb<12) { + if ((vrb&3)>=2) + return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; + else + return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; + } + else { + return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); + } + } + break; + case 75: + // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0 + if (Ngap ==0) { + return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); + } else { + // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 + return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + } + break; + case 100: + // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0 + if (Ngap ==0) { + return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); + } else { + // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 + return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + } + break; + default: + LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL); + return 0; + } + return 0; + +} + + +void generate_RIV_tables(void) +{ + + // 6RBs localized RIV + uint8_t Lcrbs,RBstart; + uint16_t RIV; + uint32_t alloc0,allocdist0_0_even,allocdist0_0_odd,allocdist0_1_even,allocdist0_1_odd; + uint32_t alloc1,allocdist1_0_even,allocdist1_0_odd,allocdist1_1_even,allocdist1_1_odd; + uint32_t alloc2,allocdist2_0_even,allocdist2_0_odd,allocdist2_1_even,allocdist2_1_odd; + uint32_t alloc3,allocdist3_0_even,allocdist3_0_odd,allocdist3_1_even,allocdist3_1_odd; + uint32_t nVRB,nVRB_even_dist,nVRB_odd_dist; + + for (RBstart=0; RBstart<6; RBstart++) { + alloc0 = 0; + allocdist0_0_even = 0; + allocdist0_0_odd = 0; + for (Lcrbs=1; Lcrbs<=(6-RBstart); Lcrbs++) { + //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); + nVRB = Lcrbs-1+RBstart; + alloc0 |= (1<<nVRB); + allocdist0_0_even |= (1<<get_prb(6,0,nVRB,0)); + allocdist0_0_odd |= (1<<get_prb(6,1,nVRB,0)); + RIV=computeRIV(6,RBstart,Lcrbs); + + if (RIV>RIV_max6) + RIV_max6 = RIV; + + // printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs); + localRIV2alloc_LUT6[RIV] = alloc0; + distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even; + distRIV2alloc_odd_LUT6[RIV] = allocdist0_0_odd; + RIV2nb_rb_LUT6[RIV] = Lcrbs; + RIV2first_rb_LUT6[RIV] = RBstart; + } + } + + + for (RBstart=0; RBstart<25; RBstart++) { + alloc0 = 0; + allocdist0_0_even = 0; + allocdist0_0_odd = 0; + for (Lcrbs=1; Lcrbs<=(25-RBstart); Lcrbs++) { + nVRB = Lcrbs-1+RBstart; + //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); + alloc0 |= (1<<nVRB); + allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0)); + allocdist0_0_odd |= (1<<get_prb(25,1,nVRB,0)); + + //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd); + RIV=computeRIV(25,RBstart,Lcrbs); + + if (RIV>RIV_max25) + RIV_max25 = RIV;; + + + localRIV2alloc_LUT25[RIV] = alloc0; + distRIV2alloc_even_LUT25[RIV] = allocdist0_0_even; + distRIV2alloc_odd_LUT25[RIV] = allocdist0_0_odd; + RIV2nb_rb_LUT25[RIV] = Lcrbs; + RIV2first_rb_LUT25[RIV] = RBstart; + } + } + + + for (RBstart=0; RBstart<50; RBstart++) { + alloc0 = 0; + alloc1 = 0; + allocdist0_0_even=0; + allocdist1_0_even=0; + allocdist0_0_odd=0; + allocdist1_0_odd=0; + allocdist0_1_even=0; + allocdist1_1_even=0; + allocdist0_1_odd=0; + allocdist1_1_odd=0; + + for (Lcrbs=1; Lcrbs<=(50-RBstart); Lcrbs++) { + + nVRB = Lcrbs-1+RBstart; + + + if (nVRB<32) + alloc0 |= (1<<nVRB); + else + alloc1 |= (1<<(nVRB-32)); + + // Distributed Gap1, even slot + nVRB_even_dist = get_prb(50,0,nVRB,0); + if (nVRB_even_dist<32) + allocdist0_0_even |= (1<<nVRB_even_dist); + else + allocdist1_0_even |= (1<<(nVRB_even_dist-32)); + + // Distributed Gap1, odd slot + nVRB_odd_dist = get_prb(50,1,nVRB,0); + if (nVRB_odd_dist<32) + allocdist0_0_odd |= (1<<nVRB_odd_dist); + else + allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); + + // Distributed Gap2, even slot + nVRB_even_dist = get_prb(50,0,nVRB,1); + if (nVRB_even_dist<32) + allocdist0_1_even |= (1<<nVRB_even_dist); + else + allocdist1_1_even |= (1<<(nVRB_even_dist-32)); + + // Distributed Gap2, odd slot + nVRB_odd_dist = get_prb(50,1,nVRB,1); + if (nVRB_odd_dist<32) + allocdist0_1_odd |= (1<<nVRB_odd_dist); + else + allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); + + RIV=computeRIV(50,RBstart,Lcrbs); + + if (RIV>RIV_max50) + RIV_max50 = RIV; + + // printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs); + localRIV2alloc_LUT50_0[RIV] = alloc0; + localRIV2alloc_LUT50_1[RIV] = alloc1; + distRIV2alloc_gap0_even_LUT50_0[RIV] = allocdist0_0_even; + distRIV2alloc_gap0_even_LUT50_1[RIV] = allocdist1_0_even; + distRIV2alloc_gap0_odd_LUT50_0[RIV] = allocdist0_0_odd; + distRIV2alloc_gap0_odd_LUT50_1[RIV] = allocdist1_0_odd; + distRIV2alloc_gap1_even_LUT50_0[RIV] = allocdist0_1_even; + distRIV2alloc_gap1_even_LUT50_1[RIV] = allocdist1_1_even; + distRIV2alloc_gap1_odd_LUT50_0[RIV] = allocdist0_1_odd; + distRIV2alloc_gap1_odd_LUT50_1[RIV] = allocdist1_1_odd; + RIV2nb_rb_LUT50[RIV] = Lcrbs; + RIV2first_rb_LUT50[RIV] = RBstart; + } + } + + + for (RBstart=0; RBstart<100; RBstart++) { + alloc0 = 0; + alloc1 = 0; + alloc2 = 0; + alloc3 = 0; + allocdist0_0_even=0; + allocdist1_0_even=0; + allocdist2_0_even=0; + allocdist3_0_even=0; + allocdist0_0_odd=0; + allocdist1_0_odd=0; + allocdist2_0_odd=0; + allocdist3_0_odd=0; + allocdist0_1_even=0; + allocdist1_1_even=0; + allocdist2_1_even=0; + allocdist3_1_even=0; + allocdist0_1_odd=0; + allocdist1_1_odd=0; + allocdist2_1_odd=0; + allocdist3_1_odd=0; + + for (Lcrbs=1; Lcrbs<=(100-RBstart); Lcrbs++) { + + nVRB = Lcrbs-1+RBstart; + + if (nVRB<32) + alloc0 |= (1<<nVRB); + else if (nVRB<64) + alloc1 |= (1<<(nVRB-32)); + else if (nVRB<96) + alloc2 |= (1<<(nVRB-64)); + else + alloc3 |= (1<<(nVRB-96)); + + // Distributed Gap1, even slot + nVRB_even_dist = get_prb(100,0,nVRB,0); + +// if ((RBstart==0) && (Lcrbs<=8)) +// printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist); + + + if (nVRB_even_dist<32) + allocdist0_0_even |= (1<<nVRB_even_dist); + else if (nVRB_even_dist<64) + allocdist1_0_even |= (1<<(nVRB_even_dist-32)); + else if (nVRB_even_dist<96) + allocdist2_0_even |= (1<<(nVRB_even_dist-64)); + else + allocdist3_0_even |= (1<<(nVRB_even_dist-96)); +/* if ((RBstart==0) && (Lcrbs<=8)) + printf("rballoc =>(%08x.%08x.%08x.%08x)\n", + allocdist0_0_even, + allocdist1_0_even, + allocdist2_0_even, + allocdist3_0_even + ); +*/ + // Distributed Gap1, odd slot + nVRB_odd_dist = get_prb(100,1,nVRB,0); + if (nVRB_odd_dist<32) + allocdist0_0_odd |= (1<<nVRB_odd_dist); + else if (nVRB_odd_dist<64) + allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); + else if (nVRB_odd_dist<96) + allocdist2_0_odd |= (1<<(nVRB_odd_dist-64)); + else + allocdist3_0_odd |= (1<<(nVRB_odd_dist-96)); + + + // Distributed Gap2, even slot + nVRB_even_dist = get_prb(100,0,nVRB,1); + if (nVRB_even_dist<32) + allocdist0_1_even |= (1<<nVRB_even_dist); + else if (nVRB_even_dist<64) + allocdist1_1_even |= (1<<(nVRB_even_dist-32)); + else if (nVRB_even_dist<96) + allocdist2_1_even |= (1<<(nVRB_even_dist-64)); + else + allocdist3_1_even |= (1<<(nVRB_even_dist-96)); + + + // Distributed Gap2, odd slot + nVRB_odd_dist = get_prb(100,1,nVRB,1); + if (nVRB_odd_dist<32) + allocdist0_1_odd |= (1<<nVRB_odd_dist); + else if (nVRB_odd_dist<64) + allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); + else if (nVRB_odd_dist<96) + allocdist2_1_odd |= (1<<(nVRB_odd_dist-64)); + else + allocdist3_1_odd |= (1<<(nVRB_odd_dist-96)); + + + RIV=computeRIV(100,RBstart,Lcrbs); + + if (RIV>RIV_max100) + RIV_max100 = RIV; + + // printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs); + localRIV2alloc_LUT100_0[RIV] = alloc0; + localRIV2alloc_LUT100_1[RIV] = alloc1; + localRIV2alloc_LUT100_2[RIV] = alloc2; + localRIV2alloc_LUT100_3[RIV] = alloc3; + distRIV2alloc_gap0_even_LUT100_0[RIV] = allocdist0_0_even; + distRIV2alloc_gap0_even_LUT100_1[RIV] = allocdist1_0_even; + distRIV2alloc_gap0_even_LUT100_2[RIV] = allocdist2_0_even; + distRIV2alloc_gap0_even_LUT100_3[RIV] = allocdist3_0_even; + distRIV2alloc_gap0_odd_LUT100_0[RIV] = allocdist0_0_odd; + distRIV2alloc_gap0_odd_LUT100_1[RIV] = allocdist1_0_odd; + distRIV2alloc_gap0_odd_LUT100_2[RIV] = allocdist2_0_odd; + distRIV2alloc_gap0_odd_LUT100_3[RIV] = allocdist3_0_odd; + distRIV2alloc_gap1_even_LUT100_0[RIV] = allocdist0_1_even; + distRIV2alloc_gap1_even_LUT100_1[RIV] = allocdist1_1_even; + distRIV2alloc_gap1_even_LUT100_2[RIV] = allocdist2_1_even; + distRIV2alloc_gap1_even_LUT100_3[RIV] = allocdist3_1_even; + distRIV2alloc_gap1_odd_LUT100_0[RIV] = allocdist0_1_odd; + distRIV2alloc_gap1_odd_LUT100_1[RIV] = allocdist1_1_odd; + distRIV2alloc_gap1_odd_LUT100_2[RIV] = allocdist2_1_odd; + distRIV2alloc_gap1_odd_LUT100_3[RIV] = allocdist3_1_odd; + + RIV2nb_rb_LUT100[RIV] = Lcrbs; + RIV2first_rb_LUT100[RIV] = RBstart; + } + } +} + +// Ngap = 3, N_VRB_DL=6, P=1, N_row=2, N_null=4*2-6=2 +// permutation for even slots : +// n_PRB'(0,2,4) = (0,1,2), n_PRB'(1,3,5) = (4,5,6) +// n_PRB''(0,1,2,3) = (0,2,4,6) +// => n_tilde_PRB(5) = (4) +// n_tilde_PRB(4) = (1) +// n_tilde_PRB(2,3) = (3,5) +// n_tilde_PRB(0,1) = (0,2) + +uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci) +{ + + return(localRIV2alloc_LUT25[rb_alloc_dci]); + +} + +uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe) +{ + uint8_t ret = 255; + + if (frame_parms->frame_type == FDD) { + ret = (((frame*10)+subframe)&7); + } else { + + switch (frame_parms->tdd_config) { + case 1: + switch (subframe) { + case 2: + case 3: + ret = (subframe-2); + break; + + case 7: + case 8: + ret = (subframe-5); + break; + + default: + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + break; + } + + break; + + case 2: + if ((subframe!=2) && (subframe!=7)) { + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret=255; + } + else ret = (subframe/7); + break; + + case 3: + if ((subframe<2) || (subframe>4)) { + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + } + else ret = (subframe-2); + break; + + case 4: + if ((subframe<2) || (subframe>3)) { + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + } + else ret = (subframe-2); + break; + + case 5: + if (subframe!=2) { + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + } + else ret = (subframe-2); + break; + + default: + LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config); + ret = (255); + } + } + + AssertFatal(ret!=255, + "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t)ret, frame, subframe); + return ret; +} + +uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n) +{ + uint8_t ul_subframe = 255; + + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 1)) { + if ((n==1)||(n==6)) { // tdd_config 0,1 SF 1,5 + ul_subframe = ((n+6)%10); + } else if ((n==4)||(n==9)) { + ul_subframe = ((n+4)%10); + } + } else if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 6) && + ((n==0)||(n==1)||(n==5)||(n==6))) + ul_subframe = ((n+7)%10); + else if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 6) && + (n==9)) // tdd_config 6 SF 9 + ul_subframe = ((n+5)%10); + else + ul_subframe = ((n+4)%10); + + if ( (subframe_select(frame_parms,ul_subframe) != SF_UL) && (frame_parms->frame_type == TDD)) return(255); + + LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); + return ul_subframe; +} + +uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n) +{ + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 1)) { + if ((n==7)||(n==2)) { // tdd_config 0,1 SF 1,5 + return((n==7)? 1 : 6); + } else if ((n==3)||(n==8)) { + return((n==3)? 9 : 4); + } + } else if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 6) && + ((n==7)||(n==8)||(n==2)||(n==3))) + return((n+3)%10); + else if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 6) && + (n==4)) // tdd_config 6 SF 9 + return(9); + else + return((n+6)%10); +} + +uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n) +{ + uint32_t ul_frame; + + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 1)) { + if ((n==1)||(n==6)||(n==4)||(n==9)) { // tdd_config 0,1 SF 1,5 + ul_frame = (frame + (n < 5 ? 0 : 1)); + } + } else if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 6) && + ((n==0)||(n==1)||(n==5)||(n==6))) + ul_frame = (frame + (n>=5 ? 1 : 0)); + else if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config == 6) && + (n==9)) // tdd_config 6 SF 9 + ul_frame = (frame+1); + else + ul_frame = (frame+(n>=6 ? 1 : 0)); + + LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame); + return ul_frame % 1024; +} + +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank) +{ + + uint8_t i,wideband_pmi2; + uint32_t pmi_ex = 0; + + if (frame_parms->N_RB_DL!=25) { + LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n"); + return(-1); + } + + if (rank==0) { + wideband_pmi2=wideband_pmi&3; + for (i=0; i<14; i+=2) + pmi_ex|=(wideband_pmi2<<i); + } + else if (rank==1) { + wideband_pmi2=wideband_pmi&1; + for (i=0; i<7; i++) + pmi_ex|=(wideband_pmi2<<i); + } + else { + LOG_E(PHY,"unsupported rank\n"); + return(-1); + } + + return(pmi_ex); +} + +uint64_t pmi2hex_2Ar1(uint32_t pmi) +{ + + uint64_t pmil = (uint64_t)pmi; + + return ((pmil&3) + (((pmil>>2)&3)<<4) + (((pmil>>4)&3)<<8) + (((pmil>>6)&3)<<12) + + (((pmil>>8)&3)<<16) + (((pmil>>10)&3)<<20) + (((pmil>>12)&3)<<24) + + (((pmil>>14)&3)<<28) + (((pmil>>16)&3)<<32) + (((pmil>>18)&3)<<36) + + (((pmil>>20)&3)<<40) + (((pmil>>22)&3)<<44) + (((pmil>>24)&3)<<48)); +} + +uint64_t pmi2hex_2Ar2(uint32_t pmi) +{ + + uint64_t pmil = (uint64_t)pmi; + return ((pmil&1) + (((pmil>>1)&1)<<4) + (((pmil>>2)&1)<<8) + (((pmil>>3)&1)<<12) + + (((pmil>>4)&1)<<16) + (((pmil>>5)&1)<<20) + (((pmil>>6)&1)<<24) + + (((pmil>>7)&1)<<28) + (((pmil>>8)&1)<<32) + (((pmil>>9)&1)<<36) + + (((pmil>>10)&1)<<40) + (((pmil>>11)&1)<<44) + (((pmil>>12)&1)<<48)); +} + + +int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) +{ + switch (dci->format) { + + case format0: // This is an UL SCH allocation so nothing here, inform MAC + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config>0)) + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format0 (TDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, + ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); + break; + + case 25: + LOG_D(PHY,"DCI format0 (TDD1-6, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, + ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); + break; + + case 50: + LOG_D(PHY,"DCI format0 (TDD1-6, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, + ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); + break; + + case 100: + LOG_D(PHY,"DCI format0 (TDD1-6, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, + ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + else if (frame_parms->frame_type == FDD) + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format0 (FDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); + break; + + case 25: + LOG_D(PHY,"DCI format0 (FDD, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); + break; + + case 50: + LOG_D(PHY,"DCI format0 (FDD, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); + break; + + case 100: + LOG_D(PHY,"DCI format0 (FDD, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu[0])[0], + ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->hopping, + ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cshift, + ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + else + LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); + + break; + + case format1: + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config>0)) + + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format1 (TDD 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai); + break; + + case 25: + LOG_D(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai); + break; + + case 50: + LOG_D(PHY,"DCI format1 (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->dai); + break; + + case 100: + LOG_D(PHY,"DCI format1 (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->dai); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + else if (frame_parms->frame_type == FDD) { + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format1 (FDD, 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 25: + LOG_D(PHY,"DCI format1 (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 50: + LOG_D(PHY,"DCI format1 (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 100: + LOG_D(PHY,"DCI format1 (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } + + else + LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); + + break; + + case format1A: // This is DLSCH allocation for control traffic + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config>0)) { + switch (frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format1A (TDD1-6, 1_5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); + LOG_D(PHY,"DAI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); + break; + + case 25: + LOG_D(PHY,"DCI format1A (TDD1-6, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %d (NB_RB %d)\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); + LOG_D(PHY,"DAI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); + break; + + case 50: + LOG_D(PHY,"DCI format1A (TDD1-6, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); + LOG_D(PHY,"DAI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); + break; + + case 100: + LOG_D(PHY,"DCI format1A (TDD1-6, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); + LOG_D(PHY,"DAI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + + } else if (frame_parms->frame_type == FDD) { + switch (frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format1A(FDD, 1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 25: + LOG_D(PHY,"DCI format1A(FDD, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 50: + LOG_D(PHY,"DCI format1A(FDD, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 100: + LOG_D(PHY,"DCI format1A(FDD, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); + LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs); + LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); + LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi); + LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rv); + LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } + + break; + + case format1C: // This is DLSCH allocation for control traffic + switch (frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format1C (1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n", + ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]); + LOG_D(PHY,"MCS %d\n",((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->mcs); + break; + + case 25: + LOG_D(PHY,"DCI format1C (5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[conv_1C_RIV(((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,25)]); + LOG_D(PHY,"MCS %d\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->mcs); + break; + + case 50: + LOG_D(PHY,"DCI format1C (10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"Ngap %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->Ngap); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,50)]); + LOG_D(PHY,"MCS %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->mcs); + break; + + case 100: + LOG_D(PHY,"DCI format1C (20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); + LOG_D(PHY,"Ngap %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->Ngap); + LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,100)]); + LOG_D(PHY,"MCS %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->mcs); + break; + + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + + + break; + + case format2: + + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config>0)) { + if (frame_parms->nb_antenna_ports_eNB == 2) { + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi + ); + break; + + case 25: + LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + case 50: + LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + case 100: + LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi + ); + break; + + case 25: + LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + case 50: + LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + case 100: + LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } + } else if (frame_parms->frame_type == FDD) { + if (frame_parms->nb_antenna_ports_eNB == 2) { + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format2 2 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 25: + + LOG_D(PHY,"DCI format2 2 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, swap %d, TPMI %d, TPC %d\n", + + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 50: + LOG_D(PHY,"DCI format2 2 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 100: + LOG_D(PHY,"DCI format2 2 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + switch(frame_parms->N_RB_DL) { + + case 6: + LOG_D(PHY,"DCI format2 4 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 25: + LOG_D(PHY,"DCI format2 4 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 50: + LOG_D(PHY,"DCI format2 4 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 100: + LOG_D(PHY,"DCI format2 4 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } + } + + else + LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); + + break; + + case format2A: + + if ((frame_parms->frame_type == TDD) && + (frame_parms->tdd_config>0)) { + if (frame_parms->nb_antenna_ports_eNB == 2) { + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format2A 2 antennas (FDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap + ); + break; + + case 25: + LOG_D(PHY,"DCI format2A 2 antennas (FDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); + break; + + case 50: + LOG_D(PHY,"DCI format2A 2 antennas (FDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); + break; + + case 100: + LOG_D(PHY,"DCI format2A 2 antennas (FDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format2A 4 antennas (TDD 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi + ); + break; + + case 25: + LOG_D(PHY,"DCI format2A 4 antennas (TDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + case 50: + LOG_D(PHY,"DCI format2A 4 antennas (TDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + case 100: + LOG_D(PHY,"DCI format2A 4 antennas (TDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } + } else if (frame_parms->frame_type == FDD) { + if (frame_parms->nb_antenna_ports_eNB == 2) { + switch(frame_parms->N_RB_DL) { + case 6: + LOG_D(PHY,"DCI format2A 2 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", + dci->rnti, + ((uint32_t*)&dci->dci_pdu)[0], + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 25: + LOG_D(PHY,"DCI format2A 2 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 50: + LOG_D(PHY,"DCI format2A 2 antennas (FDD, 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 100: + LOG_D(PHY,"DCI format2A 2 antennas (FDD, 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + switch(frame_parms->N_RB_DL) { + + case 6: + LOG_D(PHY,"DCI format2A 4 antennas (FDD, 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 25: + LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 50: + LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + case 100: + LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", + dci->rnti, + ((uint64_t*)&dci->dci_pdu)[0], + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + } + } + + else + LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); + + break; + + case format1E_2A_M10PRB: + + LOG_D(PHY,"DCI format1E_2A_M10PRB, rnti %x (%8x): harq_pid %d, rah %d, rb_alloc %x, mcs %d, rv %d, tpmi %d, ndi %d, dl_power_offset %d\n", + dci->rnti, + ((uint32_t *)&dci->dci_pdu)[0], + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->harq_pid, + //((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tb_swap, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rah, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rballoc, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->mcs, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rv, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tpmi, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->ndi, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->dl_power_off + ); + + break; + + default: + LOG_E(PHY,"dci_tools.c: dump_dci, unknown format %d\n",dci->format); + return(-1); + } + + return(0); +} diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common_extern.h b/openair1/PHY/LTE_TRANSPORT/dci_tools_common_extern.h new file mode 100644 index 0000000000000000000000000000000000000000..b0a06fb9f1e2359d0e512eb7a78effd1549d88a9 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common_extern.h @@ -0,0 +1,89 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/dci_tools_common_extern.h + * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler. + * \author R. Knopp + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#include <stdint.h> + +extern uint32_t localRIV2alloc_LUT6[32]; +extern uint32_t distRIV2alloc_even_LUT6[32]; +extern uint32_t distRIV2alloc_odd_LUT6[32]; +extern uint16_t RIV2nb_rb_LUT6[32]; +extern uint16_t RIV2first_rb_LUT6[32]; +extern uint16_t RIV_max6; + +extern uint32_t localRIV2alloc_LUT25[512]; +extern uint32_t distRIV2alloc_even_LUT25[512]; +extern uint32_t distRIV2alloc_odd_LUT25[512]; +extern uint16_t RIV2nb_rb_LUT25[512]; +extern uint16_t RIV2first_rb_LUT25[512]; +extern uint16_t RIV_max25; + + +extern uint32_t localRIV2alloc_LUT50_0[1600]; +extern uint32_t localRIV2alloc_LUT50_1[1600]; +extern uint32_t distRIV2alloc_gap0_even_LUT50_0[1600]; +extern uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600]; +extern uint32_t distRIV2alloc_gap0_even_LUT50_1[1600]; +extern uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600]; +extern uint32_t distRIV2alloc_gap1_even_LUT50_0[1600]; +extern uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600]; +extern uint32_t distRIV2alloc_gap1_even_LUT50_1[1600]; +extern uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600]; +extern uint16_t RIV2nb_rb_LUT50[1600]; +extern uint16_t RIV2first_rb_LUT50[1600]; +extern uint16_t RIV_max50; + +extern uint32_t localRIV2alloc_LUT100_0[6000]; +extern uint32_t localRIV2alloc_LUT100_1[6000]; +extern uint32_t localRIV2alloc_LUT100_2[6000]; +extern uint32_t localRIV2alloc_LUT100_3[6000]; +extern uint32_t distRIV2alloc_gap0_even_LUT100_0[6000]; +extern uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000]; +extern uint32_t distRIV2alloc_gap0_even_LUT100_1[6000]; +extern uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000]; +extern uint32_t distRIV2alloc_gap0_even_LUT100_2[6000]; +extern uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000]; +extern uint32_t distRIV2alloc_gap0_even_LUT100_3[6000]; +extern uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000]; +extern uint32_t distRIV2alloc_gap1_even_LUT100_0[6000]; +extern uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000]; +extern uint32_t distRIV2alloc_gap1_even_LUT100_1[6000]; +extern uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000]; +extern uint32_t distRIV2alloc_gap1_even_LUT100_2[6000]; +extern uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000]; +extern uint32_t distRIV2alloc_gap1_even_LUT100_3[6000]; +extern uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000]; +extern uint16_t RIV2nb_rb_LUT100[6000]; +extern uint16_t RIV2first_rb_LUT100[6000]; +extern uint16_t RIV_max100; + +extern int8_t *delta_PUCCH_lut; +extern int8_t delta_PUSCH_acc[4]; +extern int8_t delta_PUSCH_abs[4]; diff --git a/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..3574ba67405c271fefe0a43d01936fb49010efd6 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h @@ -0,0 +1,787 @@ +/******************************************************************************* + + *******************************************************************************/ +/*! \file PHY/LTE_TRANSPORT/defs_NB_IoT.h +* \brief data structures for NPDSCH/NDLSCH/NPUSCH/NULSCH physical and transport channel descriptors (TX/RX) of NB-IoT +* \author M. KANJ +* \date 2017 +* \version 0.0 +* \company bcom +* \email: matthieu.kanj@b-com.com +* \note +* \warning +*/ +#ifndef __LTE_TRANSPORT_DEFS_NB_IOT__H__ +#define __LTE_TRANSPORT_DEFS_NB_IOT__H__ +////#include "PHY/defs.h" +//#include "PHY/defs_nb_iot.h" +#include "PHY/LTE_TRANSPORT/dci_NB_IoT.h" +#include "PHY/impl_defs_lte_NB_IoT.h" +#include "openair2/COMMON/platform_types.h" +//#include "dci.h" +#include "PHY/LTE_TRANSPORT/uci_NB_IoT.h" +//#include "dci.h" +//#include "uci.h" +//#ifndef STANDALONE_COMPILE +//#include "UTIL/LISTS/list.h" +//#endif + +//#include "dci_nb_iot.h" + +//#define MOD_TABLE_QPSK_OFFSET 1 +//#define MOD_TABLE_16QAM_OFFSET 5 +//#define MOD_TABLE_64QAM_OFFSET 21 +//#define MOD_TABLE_PSS_OFFSET 85 +// +//// structures below implement 36-211 and 36-212 +// +//#define NSOFT 1827072 +#define LTE_NULL_NB_IoT 2 +// +//// maximum of 3 segments before each coding block if data length exceeds 6144 bits. +// +#define MAX_NUM_DLSCH_SEGMENTS_NB_IoT 16 +//#define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS +//#define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768) +//#define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768) +// +//#define MAX_NUM_CHANNEL_BITS_NB_IOT (14*1200*6) // 14 symbols, 1200 REs, 12 bits/RE +//#define MAX_NUM_RE (14*1200) +// +//#if !defined(SI_RNTI) +//#define SI_RNTI (rnti_t)0xffff +//#endif +//#if !defined(M_RNTI) +//#define M_RNTI (rnti_t)0xfffd +//#endif +//#if !defined(P_RNTI) +//#define P_RNTI (rnti_t)0xfffe +//#endif +//#if !defined(CBA_RNTI) +//#define CBA_RNTI (rnti_t)0xfff4 +//#endif +//#if !defined(C_RNTI) +//#define C_RNTI (rnti_t)0x1234 +//#endif +// +//#define PMI_2A_11 0 +//#define PMI_2A_1m1 1 +//#define PMI_2A_1j 2 +//#define PMI_2A_1mj 3 +// +//// for NB-IoT +#define MAX_NUM_CHANNEL_BITS_NB_IoT 3360 //14 symbols * 12 sub-carriers * 10 SF * 2bits/RE // to check during real tests +#define MAX_DL_SIZE_BITS_NB_IoT 680 // in release 13 // in release 14 = 2048 // ??? **** not sure +////#define MAX_NUM_CHANNEL_BITS_NB_IOT 3*680 /// ??? ****not sure +// +//// to be created LTE_eNB_DLSCH_t --> is duplicated for each number of UE and then indexed in the table +// +//typedef struct { // LTE_DL_eNB_HARQ_t +// /// Status Flag indicating for this DLSCH (idle,active,disabled) +// SCH_status_t status; +// /// Transport block size +// uint32_t TBS; +// /// The payload + CRC size in bits, "B" from 36-212 +// uint32_t B; // keep this parameter +// /// Pointer to the payload +// uint8_t *b; // keep this parameter +// /// Pointers to transport block segments +// //uint8_t *c[MAX_NUM_DLSCH_SEGMENTS]; +// /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) +// // uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS]; +// /// Frame where current HARQ round was sent +// uint32_t frame; +// /// Subframe where current HARQ round was sent +// uint32_t subframe; +// /// Index of current HARQ round for this DLSCH +// uint8_t round; +// /// MCS format for this DLSCH +// uint8_t mcs; +// /// Redundancy-version of the current sub-frame +// uint8_t rvidx; +// /// MIMO mode for this DLSCH +// MIMO_mode_t mimo_mode; +// /// Current RB allocation +// uint32_t rb_alloc[4]; +// /// distributed/localized flag +// vrb_t vrb_type; +// /// Current subband PMI allocation +// uint16_t pmi_alloc; +// /// Current subband RI allocation +// uint32_t ri_alloc; +// /// Current subband CQI1 allocation +// uint32_t cqi_alloc1; +// /// Current subband CQI2 allocation +// uint32_t cqi_alloc2; +// /// Current Number of RBs +// uint16_t nb_rb; +// /// downlink power offset field +// uint8_t dl_power_off; +// /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) +// uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IOT]; +// /// data after scrambling +// uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IOT]; +// /// length of the table e +// uint16_t length_e // new parameter +// /// Tail-biting convolutional coding outputs +// uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IOT))]; // new parameter +// /// Sub-block interleaver outputs +// uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IOT+24)]; // new parameter +// /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17, TM3-4) +// uint8_t Nl; +// /// Number of layers for this PDSCH transmission (TM8-10) +// uint8_t Nlayers; +// /// First layer for this PSCH transmission +// uint8_t first_layer; +//} NB_IoT_DL_eNB_HARQ_t; + +typedef enum { + + SCH_IDLE_NB_IoT, + ACTIVE_NB_IoT, + CBA_ACTIVE_NB_IoT, + DISABLED_NB_IoT + +} SCH_status_NB_IoT_t; + + +typedef struct { + /// NB-IoT + SCH_status_NB_IoT_t status; + /// The scheduling the NPDCCH and the NPDSCH transmission TS 36.213 Table 16.4.1-1 + uint8_t scheduling_delay; + /// The number of the subframe to transmit the NPDSCH Table TS 36.213 Table 16.4.1.3-1 (Nsf) (NB. in this case is not the index Isf) + uint8_t resource_assignment; + /// is the index that determined the repeat number of NPDSCH through table TS 36.213 Table 16.4.1.3-2 / for SIB1-NB Table 16.4.1.3-3 + uint8_t repetition_number; + /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2 + uint8_t HARQ_ACK_resource; + /// Determined the repetition number value 0-3 (2 biut carried by the FAPI NPDCCH) + uint8_t dci_subframe_repetitions; + /// modulation always QPSK Qm = 2 + uint8_t modulation; + /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IoT]; + /// data after scrambling + uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IoT]; + //length of the table e + uint16_t length_e; // new parameter + /// Tail-biting convolutional coding outputs + uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IoT))]; // new parameter + /// Sub-block interleaver outputs + uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IoT+24)]; // new parameter + + /// Status Flag indicating for this DLSCH (idle,active,disabled) + //SCH_status_t status; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits, "B" from 36-212 + uint32_t B; + /// Pointer to the payload + uint8_t *b; + ///pdu of the ndlsch message + uint8_t *pdu; + /// Frame where current HARQ round was sent + uint32_t frame; + /// Subframe where current HARQ round was sent + uint32_t subframe; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// MCS format for this NDLSCH , TS 36.213 Table 16.4.1.5 + uint8_t mcs; + // we don't have code block segmentation / crc attachment / concatenation in NB-IoT R13 36.212 6.4.2 + // we don't have beamforming in NB-IoT + //this index will be used mainly for SI message buffer + uint8_t pdu_buffer_index; + +} NB_IoT_DL_eNB_HARQ_t; + + +typedef struct { // LTE_eNB_DLSCH_t + /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) + uint32_t *txdataF[8]; + /// Allocated RNTI (0 means DLSCH_t is not currently used) + uint16_t rnti; + /// Active flag for baseband transmitter processing + uint8_t active; + /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. + uint8_t subframe_tx[10]; + /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. + uint8_t nCCE[10]; + /// Current HARQ process id + uint8_t current_harq_pid; + /// Process ID's per subframe. Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids + uint8_t harq_ids[10]; + /// Window size (in outgoing transport blocks) for fine-grain rate adaptation + uint8_t ra_window_size; + /// First-round error threshold for fine-grain rate adaptation + uint8_t error_threshold; + /// Pointers to 8 HARQ processes for the DLSCH + NB_IoT_DL_eNB_HARQ_t harq_process; + /// circular list of free harq PIDs (the oldest come first) + /// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE) + int harq_pid_freelist[10]; + /// the head position of the free list (if list is free then head=tail) + int head_freelist; + /// the tail position of the free list + int tail_freelist; + /// Number of soft channel bits + uint32_t G; + /// Codebook index for this dlsch (0,1,2,3) + uint8_t codebook_index; + /// Maximum number of HARQ processes (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Mdlharq; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Kmimo; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + +} NB_IoT_eNB_DLSCH_t; + + +typedef struct { + /// HARQ process id + uint8_t harq_id; + /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX + uint8_t ack; + /// send status (for PUCCH) + uint8_t send_harq_status; + /// nCCE (for PUCCH) + uint8_t nCCE; + /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched + uint8_t vDAI_DL; + /// DAI value detected from DCI0/4. 0xff indicates not touched + uint8_t vDAI_UL; +} harq_status_NB_IoT_t; + +typedef struct { + /// UL RSSI per receive antenna + int32_t UL_rssi[NB_ANTENNAS_RX]; + /// PUCCH1a/b power (digital linear) + uint32_t Po_PUCCH; + /// PUCCH1a/b power (dBm) + int32_t Po_PUCCH_dBm; + /// PUCCH1 power (digital linear), conditioned on below threshold + uint32_t Po_PUCCH1_below; + /// PUCCH1 power (digital linear), conditioned on above threshold + uint32_t Po_PUCCH1_above; + /// Indicator that Po_PUCCH has been updated by PHY + int32_t Po_PUCCH_update; + /// DL Wideband CQI index (2 TBs) + uint8_t DL_cqi[2]; + /// DL Subband CQI index (from HLC feedback) + uint8_t DL_subband_cqi[2][13]; + /// DL PMI Single Stream + uint16_t DL_pmi_single; + /// DL PMI Dual Stream + uint16_t DL_pmi_dual; + /// Current RI + uint8_t rank; + /// CRNTI of UE + uint16_t crnti; ///user id (rnti) of connected UEs + /// Initial timing offset estimate from PRACH for RAR + int32_t UE_timing_offset; + /// Timing advance estimate from PUSCH for MAC timing advance signalling + int32_t timing_advance_update; + /// Current mode of UE (NOT SYCHED, RAR, PUSCH) + UE_MODE_NB_IoT_t mode; + /// Current sector where UE is attached + uint8_t sector; + + /// dlsch l2 errors + uint32_t dlsch_l2_errors[8]; + /// dlsch trials per harq and round + uint32_t dlsch_trials[8][8]; + /// dlsch ACK/NACK per hard_pid and round + uint32_t dlsch_ACK[8][8]; + uint32_t dlsch_NAK[8][8]; + + /// ulsch l2 errors per harq_pid + uint32_t ulsch_errors[8]; + /// ulsch l2 consecutive errors per harq_pid + uint32_t ulsch_consecutive_errors; //[8]; + /// ulsch trials/errors/fer per harq and round + uint32_t nulsch_decoding_attempts[8][8]; + uint32_t ulsch_round_errors[8][8]; + uint32_t ulsch_decoding_attempts_last[8][8]; + uint32_t ulsch_round_errors_last[8][8]; + uint32_t ulsch_round_fer[8][8]; + uint32_t sr_received; + uint32_t sr_total; + + /// dlsch sliding count and total errors in round 0 are used to compute the dlsch_mcs_offset + uint32_t dlsch_sliding_cnt; + uint32_t dlsch_NAK_round0; + int8_t dlsch_mcs_offset; + + /// Target mcs1 after rate-adaptation (used by MAC layer scheduler) + uint8_t dlsch_mcs1; + /// Target mcs2 after rate-adaptation (used by MAC layer scheduler) + uint8_t dlsch_mcs2; + /// Total bits received from MAC on PDSCH + int total_TBS_MAC; + /// Total bits acknowledged on PDSCH + int total_TBS; + /// Total bits acknowledged on PDSCH (last interval) + int total_TBS_last; + /// Bitrate on the PDSCH [bps] + unsigned int dlsch_bitrate; + // unsigned int total_transmitted_bits; + +} NB_IoT_eNB_UE_stats; + +typedef struct { + /// Indicator of first transmission + uint8_t first_tx; + /// Last Ndi received for this process on DCI (used for C-RNTI only) + uint8_t DCINdi; + /// DLSCH status flag indicating + //SCH_status_t status; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits + uint32_t B; + /// Pointer to the payload + uint8_t *b; + /// Pointers to transport block segments + uint8_t *c[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) + uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// MCS format for this DLSCH + uint8_t mcs; + /// Qm (modulation order) for this DLSCH + uint8_t Qm; + /// Redundancy-version of the current sub-frame + uint8_t rvidx; + /// MIMO mode for this DLSCH + // MIMO_mode_t mimo_mode; + /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t w[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)]; + /// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + double w_abs[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)]; + /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t *d[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Nl; + /// current delta_pucch + int8_t delta_PUCCH; + /// Number of soft channel bits + uint32_t G; + /// Current Number of RBs + uint16_t nb_rb; + /// Current subband PMI allocation + uint16_t pmi_alloc; + /// Current RB allocation (even slots) + uint32_t rb_alloc_even[4]; + /// Current RB allocation (odd slots) + uint32_t rb_alloc_odd[4]; + /// distributed/localized flag + //vrb_t vrb_type; + /// downlink power offset field + uint8_t dl_power_off; + /// trials per round statistics + uint32_t trials[8]; + /// error statistics per round + uint32_t errors[8]; + /// codeword this transport block is mapped to + uint8_t codeword; + +} NB_IoT_DL_UE_HARQ_t; + +typedef struct { + /// RNTI + uint16_t rnti; + /// Active flag for DLSCH demodulation + uint8_t active; + /// Transmission mode + uint8_t mode1_flag; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + /// Current HARQ process id threadRx Odd and threadRx Even + uint8_t current_harq_pid; + /// Current subband antenna selection + uint32_t antenna_alloc; + /// Current subband RI allocation + uint32_t ri_alloc; + /// Current subband CQI1 allocation + uint32_t cqi_alloc1; + /// Current subband CQI2 allocation + uint32_t cqi_alloc2; + /// saved subband PMI allocation from last PUSCH/PUCCH report + uint16_t pmi_alloc; + /// HARQ-ACKs + harq_status_NB_IoT_t harq_ack; + /// Pointers to up to 8 HARQ processes + NB_IoT_DL_UE_HARQ_t *harq_process; + /// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17 + uint8_t Mdlharq; + /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Kmimo; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// Maximum number of Turbo iterations + uint8_t max_turbo_iterations; + /// number of iterations used in last turbo decoding + uint8_t last_iteration_cnt; + /// accumulated tx power adjustment for PUCCH + int8_t g_pucch; + +} NB_IoT_UE_DLSCH_t; + +//---------------------------------------------------------------------------------------------------------- +// NB-IoT +//---------------------------------------------------------------------------------------------------- + +//enum for distinguish the different type of ndlsch (may in the future will be not needed) +typedef enum +{ + + SIB1, + SI_Message, + RAR, + UE_Data + +}ndlsch_flag_t; + + + +typedef struct { + rnti_t rnti; + //array containing the pdus of DCI + uint8_t *a[2]; + //Array containing encoded DCI data + uint8_t *e[2]; + + //UE specific parameters + uint16_t npdcch_NumRepetitions; + + uint16_t repetition_number; + //indicate the corresponding subframe within the repetition (set to 0 when a new NPDCCH pdu is received) + uint16_t repetition_idx; + + // uint16_t npdcch_Offset_USS; + // uint16_t npdcch_StartSF_USS; + + +}NB_IoT_eNB_NPDCCH_t; + + +typedef struct{ + + //Number of repetitions (R) for common search space (RAR and PAGING) + uint16_t number_repetition_RA; + uint16_t number_repetition_PAg; + //index of the current subframe among the repetition (set to 0 when we receive the new NPDCCH) + uint16_t repetition_idx_RA; + uint16_t repetition_idx_Pag; + +}NB_IoT_eNB_COMMON_NPDCCH_t; + + +typedef struct { + + /// Length of DCI in bits + uint8_t dci_length; + /// Aggregation level only 1,2 in NB-IoT + uint8_t L; + /// Position of first CCE of the dci + int firstCCE; + /// flag to indicate that this is a RA response + boolean_t ra_flag; + /// rnti + rnti_t rnti; + /// Format + DCI_format_NB_IoT_t format; + /// DCI pdu + uint8_t dci_pdu[8]; + +} DCI_ALLOC_NB_IoT_t; + + +typedef struct { + //delete the count for the DCI numbers,NUM_DCI_MAX should set to 2 + uint32_t num_npdcch_symbols; + ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission + /// see FAPI/NFAPI specs Table 4-45 + uint8_t npdcch_start_symbol; + uint8_t Num_dci; + DCI_ALLOC_NB_IoT_t dci_alloc[2] ; + +} DCI_PDU_NB_IoT; + + + + +typedef struct { + /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) + int32_t *txdataF[8]; + /// dl channel estimates (estimated from ul channel estimates) + int32_t **calib_dl_ch_estimates; + /// Allocated RNTI (0 means DLSCH_t is not currently used) + uint16_t rnti; + /// Active flag for baseband transmitter processing + uint8_t active; + /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. + uint8_t subframe_tx[10]; + /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. + uint8_t nCCE[10]; + /*in NB-IoT there is only 1 HARQ process for each UE therefore no pid is required*/ + /// The only HARQ process for the DLSCH + NB_IoT_DL_eNB_HARQ_t *harq_process; + /// Number of soft channel bits + uint32_t G; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + ///NB-IoT + /// may use in the npdsch_procedures + uint16_t scrambling_sequence_intialization; + /// number of cell specific TX antenna ports assumed by the UE + uint8_t nrs_antenna_ports; + + //This indicate the current subframe within the subframe interval between the NPDSCH transmission (Nsf*Nrep) + uint16_t sf_index; + ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDSCH transmission + /// see FAPI/NFAPI specs Table 4-47 + uint8_t npdsch_start_symbol; + /*SIB1-NB related parameters*/ + ///flag for indicate if the current frame is the start of a new SIB1-NB repetition within the SIB1-NB period (0 = FALSE, 1 = TRUE) + uint8_t sib1_rep_start; + ///the number of the frame within the 16 continuous frame in which sib1-NB is transmitted (1-8 = 1st, 2nd ecc..) (0 = not foresees a transmission) + uint8_t relative_sib1_frame; + //Flag used to discern among different NDLSCH structures (SIB1,SI,RA,UE-spec) + //(used inside the ndlsch procedure for distinguish the different type of data to manage also in term of repetitions and transmission over more subframes + ndlsch_flag_t ndlsch_type; + +} NB_IoT_eNB_NDLSCH_t; + +typedef struct { + /// Length of CQI data under RI=1 assumption(bits) + uint8_t Or1; + /// Rank information + uint8_t o_RI[2]; + /// Format of CQI data + UCI_format_NB_IoT_t uci_format; + /// The value of DAI in DCI format 0 + uint8_t V_UL_DAI; + /// Pointer to CQI data + uint8_t o[MAX_CQI_BYTES_NB_IoT]; + /// CQI CRC status + uint8_t cqi_crc_status; + /// PHICH active flag + uint8_t phich_active; + /// PHICH ACK + uint8_t phich_ACK; + /// Length of rank information (bits) + uint8_t O_RI; + /// First Allocated RB + uint16_t first_rb; + /// Current Number of RBs + uint16_t nb_rb; + /// Determined the subcarrier allocation for the NPUSCH.(15, 3.75 KHz) + uint8_t subcarrier_indication; + /// Determined the number of resource unit for the NPUSCH + uint8_t resource_assignment; + /// Determined the scheduling delay for NPUSCH + uint8_t scheduling_delay; + /// The number of the repetition number for NPUSCH Transport block + uint8_t repetition_number; + /// Determined the repetition number value 0-3 + uint8_t dci_subframe_repetitions; + /// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK) + uint8_t dci_alloc; + /// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI) + uint8_t rar_alloc; + /// Status Flag indicating for this ULSCH (idle,active,disabled) + SCH_status_NB_IoT_t status; + /// Subframe scheduling indicator (i.e. Transmission opportunity indicator) + uint8_t subframe_scheduling_flag; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits + uint32_t B; + /// Number of soft channel bits + uint32_t G; + /// Pointer to ACK + uint8_t o_ACK[4]; + /// Length of ACK information (bits) + uint8_t O_ACK; + /// coded ACK bits + int16_t q_ACK[MAX_ACK_PAYLOAD_NB_IoT]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + int16_t e[MAX_NUM_CHANNEL_BITS_NB_IoT] __attribute__((aligned(32))); + /// coded RI bits + int16_t q_RI[MAX_RI_PAYLOAD_NB_IoT]; + /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) + int8_t q[MAX_CQI_PAYLOAD_NB_IoT]; + /// number of coded CQI bits after interleaving + uint8_t o_RCC; + /// coded and interleaved CQI bits + int8_t o_w[(MAX_CQI_BITS_NB_IoT+8)*3]; + /// coded CQI bits + int8_t o_d[96+((MAX_CQI_BITS_NB_IoT+8)*3)]; + /// + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled + //uint8_t h[MAX_NUM_CHANNEL_BITS]; + /// SRS active flag + uint8_t srs_active; + /// Pointer to the payload + uint8_t *b; + /// Current Number of Symbols + uint8_t Nsymb_pusch; + /// Index of current HARQ round for this ULSCH + uint8_t round; + /// MCS format for this ULSCH + uint8_t mcs; + /// Redundancy-version of the current sub-frame (value 0->RV0,value 1 ->RV2) + uint8_t rvidx; + /// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint16_t Msc_initial; + /// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint8_t Nsymb_initial; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) + uint8_t n_DMRS; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling + /// This is needed for PHICH generation which + /// is done after a new scheduling + uint8_t previous_n_DMRS; + /// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1) + uint8_t n_DMRS2; + /// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up) + // int calibration_flag; + /// delta_TF for power control + int32_t delta_TF; + ///////////////////////////////////////////// 4 parameter added by vincent /////////////////////////////////////////////// + // NB_IoT: Nsymb_UL and Nslot_UL are defined in 36.211, Section 10.1.2.3, Table 10.1.2.3-1 + // The number of symbol in a resource unit is given by Nsymb_UL*Nslot_UL + uint8_t Nsymb_UL; + // Number of NPUSCH slots + uint8_t Nslot_UL; + // Number of subcarrier for NPUSH, can be 1, 3, 6, 12 + uint8_t N_sc_RU; + // Index of UL NB_IoT resource block + uint32_t UL_RB_ID_NB_IoT; + // Subcarrier indication fields, obtained through DCI, Section 16.5.1.1 in 36.213 + uint16_t I_sc; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} NB_IoT_UL_eNB_HARQ_t; + + +typedef struct { + /// Pointers to the HARQ processes for the NULSCH + NB_IoT_UL_eNB_HARQ_t *harq_process; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Value 0 = npush format 1 (data) value 1 = npusch format 2 (ACK/NAK) + uint8_t npusch_format; + /// Flag to indicate that eNB awaits UE Msg3 + uint8_t Msg3_active; + /// Flag to indicate that eNB should decode UE Msg3 + uint8_t Msg3_flag; + /// Subframe for Msg3 + uint8_t Msg3_subframe; + /// Frame for Msg3 + uint32_t Msg3_frame; + /// RNTI attributed to this ULSCH + uint16_t rnti; + /// cyclic shift for DM RS + uint8_t cyclicShift; + /// cooperation flag + uint8_t cooperation_flag; + /// (only in-band mode), indicate the resource block overlap the SRS configuration of LTE + uint8_t N_srs; + /// + uint8_t scrambling_re_intialization_batch_index; + /// number of cell specific TX antenna ports assumed by the UE + uint8_t nrs_antenna_ports; + /// + uint16_t scrambling_sequence_intialization; + /// + uint16_t sf_index; + /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2 + uint8_t HARQ_ACK_resource; + + ///////////// kept from LTE /////////////////////////////////////////////////// + + /// Maximum number of iterations used in eNB turbo decoder + uint8_t max_turbo_iterations; + /// ACK/NAK Bundling flag + uint8_t bundling; + /// beta_offset_cqi times 8 + uint16_t beta_offset_cqi_times8; + /// beta_offset_ri times 8 + uint16_t beta_offset_ri_times8; + /// beta_offset_harqack times 8 + uint16_t beta_offset_harqack_times8; + /// num active cba group + uint8_t num_active_cba_groups; + /// allocated CBA RNTI for this ulsch + uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; + #ifdef LOCALIZATION + /// epoch timestamp in millisecond + int32_t reference_timestamp_ms; + /// aggregate physical states every n millisecond + int32_t aggregation_period_ms; + /// a set of lists used for localization + struct list loc_rss_list[10], loc_rssi_list[10], loc_subcarrier_rss_list[10], loc_timing_advance_list[10], loc_timing_update_list[10]; + struct list tot_loc_rss_list, tot_loc_rssi_list, tot_loc_subcarrier_rss_list, tot_loc_timing_advance_list, tot_loc_timing_update_list; + #endif + +} NB_IoT_eNB_NULSCH_t; + +#define NPBCH_A 34 + +typedef struct { + //the 2 LSB of the hsfn (the MSB are indicated by the SIB1-NB) + uint16_t h_sfn_lsb; + + uint8_t npbch_d[96+(3*(16+NPBCH_A))]; + uint8_t npbch_w[3*3*(16+NPBCH_A)]; + uint8_t npbch_e[1600]; + ///pdu of the npbch message + uint8_t *pdu; + +} NB_IoT_eNB_NPBCH_t; + + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index b04a8bb66559b758a7e45f6e35bd60d746ac2959..55795243e933f82f76821c7800b79d7fbb8c4e0b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -30,18 +30,18 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/CODING/defs.h" -#include "PHY/CODING/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/LTE_TRANSPORT/defs.h" -#include "PHY/LTE_TRANSPORT/proto.h" -#include "SCHED/defs.h" -#include "defs.h" +#include "PHY/LTE_TRANSPORT/transport_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "SCHED/sched_eNB.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/LOG/log.h" #include <syscall.h> +#include "targets/RT/USER/rt_wrapper.h" //#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_FREE 1 @@ -52,46 +52,30 @@ ((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \ */ #define is_not_pilot(pilots,first_pilot,re) (1) +/*extern void thread_top_init(char *thread_name, + int affinity, + uint64_t runtime, + uint64_t deadline, + uint64_t period);*/ +extern int codingw; void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { - int i; - int r; + int i, r, aa, layer; if (dlsch) { -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch %p\n",dlsch); -#endif - + for (layer=0; layer<4; layer++) { + for (aa=0; aa<64; aa++) free16(dlsch->ue_spec_bf_weights[layer][aa], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); + free16(dlsch->ue_spec_bf_weights[layer], 64*sizeof(int32_t*)); + } for (i=0; i<dlsch->Mdlharq; i++) { -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d\n",i); -#endif - if (dlsch->harq_processes[i]) { -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]); -#endif - if (dlsch->harq_processes[i]->b) { free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); dlsch->harq_processes[i]->b = NULL; -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b); -#endif } - -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c); -#endif - for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) { - -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d c[%d] (%p)\n",i,r,dlsch->harq_processes[i]->c[r]); -#endif - if (dlsch->harq_processes[i]->c[r]) { free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); dlsch->harq_processes[i]->c[r] = NULL; @@ -100,17 +84,14 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144))); dlsch->harq_processes[i]->d[r] = NULL; } - } free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); dlsch->harq_processes[i] = NULL; } } - free16(dlsch,sizeof(LTE_eNB_DLSCH_t)); dlsch = NULL; - } - + } } LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms) @@ -274,11 +255,15 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) } + + int dlsch_encoding_2threads0(te_params *tep) { LTE_eNB_DLSCH_t *dlsch = tep->dlsch; unsigned int G = tep->G; unsigned char harq_pid = tep->harq_pid; + unsigned int total_worker = tep->total_worker; + unsigned int current_worker = tep->current_worker; unsigned short iind; @@ -291,7 +276,7 @@ int dlsch_encoding_2threads0(te_params *tep) { if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet - for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) { + for (r=(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*current_worker; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) { if (r<dlsch->harq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; @@ -316,13 +301,13 @@ int dlsch_encoding_2threads0(te_params *tep) { - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); dlsch->harq_processes[harq_pid]->RTC[r] = sub_block_interleaving_turbo(4+(Kr_bytes*8), &dlsch->harq_processes[harq_pid]->d[r][96], @@ -334,21 +319,34 @@ int dlsch_encoding_2threads0(te_params *tep) { // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the // outputs for each code segment, see Section 5.1.5 p.20 - for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) { - r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], - G, //G - dlsch->harq_processes[harq_pid]->w[r], - dlsch->harq_processes[harq_pid]->e+r_offset, - dlsch->harq_processes[harq_pid]->C, // C - dlsch->Nsoft, // Nsoft, - dlsch->Mdlharq, - dlsch->Kmimo, - dlsch->harq_processes[harq_pid]->rvidx, - dlsch->harq_processes[harq_pid]->Qm, - dlsch->harq_processes[harq_pid]->Nl, - r, - nb_rb); - // m); // r + for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) { + if(r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker)){ + int Nl=dlsch->harq_processes[harq_pid]->Nl; + int Qm=dlsch->harq_processes[harq_pid]->Qm; + int C = dlsch->harq_processes[harq_pid]->C; + int Gp = G/Nl/Qm; + int GpmodC = Gp%C; + if (r < (C-(GpmodC))) + r_offset += Nl*Qm * (Gp/C); + else + r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); + } + else{ + r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], + G, //G + dlsch->harq_processes[harq_pid]->w[r], + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->C, // C + dlsch->Nsoft, // Nsoft, + dlsch->Mdlharq, + dlsch->Kmimo, + dlsch->harq_processes[harq_pid]->rvidx, + dlsch->harq_processes[harq_pid]->Qm, + dlsch->harq_processes[harq_pid]->Nl, + r, + nb_rb); + // m); // r + } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT); @@ -356,32 +354,46 @@ int dlsch_encoding_2threads0(te_params *tep) { return(0); } + extern int oai_exit; void *te_thread(void *param) { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + thread_top_init("te_thread",1,200000,250000,500000); pthread_setname_np( pthread_self(),"te processing"); - LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid)); + LOG_I(PHY,"thread te created id=%ld\n", syscall(__NR_gettid)); + - eNB_proc_t *proc = &((te_params *)param)->eNB->proc; + te_params *tep = (te_params *)param; + + //wait_sync("te_thread"); + while (!oai_exit) { + if (wait_on_condition(&tep->mutex_te,&tep->cond_te,&tep->instance_cnt_te,"te thread")<0) break; + if(oai_exit) break; - if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break; + dlsch_encoding_2threads0(tep); - dlsch_encoding_2threads0((te_params*)param); + if (release_thread(&tep->mutex_te,&tep->instance_cnt_te,"te thread")<0) break; - - if (release_thread(&proc->mutex_te,&proc->instance_cnt_te,"te thread")<0) break; - - if (pthread_cond_signal(&proc->cond_te) != 0) { + if (pthread_cond_signal(&tep->cond_te) != 0) { printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); return(NULL); } + /*if(opp_enabled == 1 && te_wakeup_stats0->diff_now>50*3000){ + print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr); + printf("te_thread0 delay for waking up in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); + }*/ } return(NULL); } + + int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, unsigned char *a, uint8_t num_pdcch_symbols, @@ -390,9 +402,16 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, uint8_t subframe, time_stats_t *rm_stats, time_stats_t *te_stats, - time_stats_t *i_stats) + time_stats_t *te_wait_stats, + time_stats_t *te_main_stats, + time_stats_t *te_wakeup_stats0, + time_stats_t *te_wakeup_stats1, + time_stats_t *i_stats, + int worker_num) { + //start_meas(&eNB->dlsch_turbo_encoding_preperation_stats); + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; eNB_proc_t *proc = &eNB->proc; unsigned int G; @@ -416,19 +435,22 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, mod_order = dlsch->harq_processes[harq_pid]->Qm; G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0); - if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet + start_meas(&eNB->dlsch_turbo_encoding_preperation_stats); // Add 24-bit crc (polynomial A) to payload crc = crc24a(a, A)>>8; + stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats); a[A>>3] = ((uint8_t*)&crc)[2]; a[1+(A>>3)] = ((uint8_t*)&crc)[1]; a[2+(A>>3)] = ((uint8_t*)&crc)[0]; dlsch->harq_processes[harq_pid]->B = A+24; memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); + //stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats); + start_meas(&eNB->dlsch_turbo_encoding_segmentation_stats); if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, dlsch->harq_processes[harq_pid]->c, dlsch->harq_processes[harq_pid]->B, @@ -440,34 +462,41 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, &dlsch->harq_processes[harq_pid]->F)<0) return(-1); - - - if (proc->instance_cnt_te==0) { - printf("[eNB] TE thread busy\n"); - exit_fun("TE thread busy"); - pthread_mutex_unlock( &proc->mutex_te ); - return(-1); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); - ++proc->instance_cnt_te; - - proc->tep.eNB = eNB; - proc->tep.dlsch = dlsch; - proc->tep.G = G; - proc->tep.harq_pid = harq_pid; - - // wakeup worker to do second half segments - if (pthread_cond_signal(&proc->cond_te) != 0) { - printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return (-1); + stop_meas(&eNB->dlsch_turbo_encoding_segmentation_stats); + + start_meas(&eNB->dlsch_turbo_encoding_signal_stats); + for(int i=0;i<worker_num;i++) + { + proc->tep[i].eNB = eNB; + proc->tep[i].dlsch = dlsch; + proc->tep[i].G = G; + proc->tep[i].harq_pid = harq_pid; + proc->tep[i].total_worker = worker_num; + proc->tep[i].current_worker = i; + + pthread_mutex_lock( &proc->tep[i].mutex_te ); + if (proc->tep[i].instance_cnt_te==0) { + printf("[eNB] TE thread busy\n"); + exit_fun("TE thread busy"); + pthread_mutex_unlock( &proc->tep[i].mutex_te ); + return(-1); + } + + ++proc->tep[i].instance_cnt_te; + + // wakeup worker to do segments + if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) { + printf("[eNB] ERROR pthread_cond_signal for te thread %d exit\n",i); + exit_fun( "ERROR pthread_cond_signal" ); + return (-1); + } + + pthread_mutex_unlock( &proc->tep[i].mutex_te ); } - pthread_mutex_unlock( &proc->mutex_te ); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); - for (r=dlsch->harq_processes[harq_pid]->C>>1; r<dlsch->harq_processes[harq_pid]->C; r++) { + stop_meas(&eNB->dlsch_turbo_encoding_signal_stats); + start_meas(te_main_stats); + for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) { if (r<dlsch->harq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; @@ -492,13 +521,13 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); start_meas(i_stats); @@ -512,15 +541,18 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, } else { - proc->tep.eNB = eNB; - proc->tep.dlsch = dlsch; - proc->tep.G = G; - - // wakeup worker to do second half segments - if (pthread_cond_signal(&proc->cond_te) != 0) { + for(int i=0;i<worker_num;i++) + { + proc->tep[i].eNB = eNB; + proc->tep[i].dlsch = dlsch; + proc->tep[i].G = G; + proc->tep[i].total_worker = worker_num; + proc->tep[i].current_worker = i; + if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) { printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); return (-1); + } } } @@ -530,7 +562,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) { // get information for E for the segments that are handled by the worker thread - if (r<(dlsch->harq_processes[harq_pid]->C>>1)) { + if (r<(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num) { int Nl=dlsch->harq_processes[harq_pid]->Nl; int Qm=dlsch->harq_processes[harq_pid]->Qm; int C = dlsch->harq_processes[harq_pid]->C; @@ -560,16 +592,138 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, stop_meas(rm_stats); } } + stop_meas(te_main_stats); - // wait for worker to finish - - wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread"); + start_meas(te_wait_stats); + if(worker_num == 1) + { + wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0"); + } + else if(worker_num == 2) + { + wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0"); + wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1"); + } + else + { + wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0"); + wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1"); + wait_on_busy_condition(&proc->tep[2].mutex_te,&proc->tep[2].cond_te,&proc->tep[2].instance_cnt_te,"te thread 2"); + } + stop_meas(te_wait_stats); + + /*if(opp_enabled == 1 && te_wait_stats->diff_now>100*3000){ + print_meas_now(te_wait_stats,"coding_wait",stderr); + printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx); + }*/ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); } +int dlsch_encoding_all(PHY_VARS_eNB *eNB, + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *te_wait_stats, + time_stats_t *te_main_stats, + time_stats_t *te_wakeup_stats0, + time_stats_t *te_wakeup_stats1, + time_stats_t *i_stats) +{ + int encoding_return = 0; + unsigned int L,C,B; + B = dlsch->harq_processes[dlsch->harq_ids[frame%2][subframe]]->B; + if(B<=6144) + { + L=0; + C=1; + } + else + { + L=24; + C = B/(6144-L); + if((6144-L)*C < B) + { + C = C+1; + } + } + + if(C >= 8 && get_nprocs()>=16 && codingw)//one main three worker + { + encoding_return = + dlsch_encoding_2threads(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + te_wait_stats, + te_main_stats, + te_wakeup_stats0, + te_wakeup_stats1, + i_stats, + 3); + } + else if(C >= 6 && get_nprocs()>=8 && codingw)//one main two worker + { + encoding_return = + dlsch_encoding_2threads(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + te_wait_stats, + te_main_stats, + te_wakeup_stats0, + te_wakeup_stats1, + i_stats, + 2); + } + else if(C >= 4 && get_nprocs()>=4 && codingw)//one main one worker + { + encoding_return = + dlsch_encoding_2threads(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + te_wait_stats, + te_main_stats, + te_wakeup_stats0, + te_wakeup_stats1, + i_stats, + 1); + } + else + { + encoding_return = + dlsch_encoding(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + i_stats); + } + return encoding_return; +} + int dlsch_encoding(PHY_VARS_eNB *eNB, unsigned char *a, @@ -617,7 +771,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet #ifdef DEBUG_DLSCH_CODING - printf("encoding thinks this is a new packet \n"); + printf("encoding thinks this is a new packet for harq_pid %d (%p) \n",harq_pid,dlsch->harq_processes[harq_pid]->b); #endif /* int i; @@ -627,6 +781,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, printf("\n"); */ // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a, A)>>8; a[A>>3] = ((uint8_t*)&crc)[2]; @@ -688,13 +843,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_DLSCH_CODING @@ -757,186 +912,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, } -int dlsch_encoding_SIC(PHY_VARS_UE *ue, - unsigned char *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *i_stats) -{ - - unsigned int G; - unsigned int crc=1; - unsigned short iind; - - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - unsigned char harq_pid = ue->dlsch[subframe&2][0][0]->rnti; - unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; - unsigned int A; - unsigned char mod_order; - unsigned int Kr=0,Kr_bytes,r,r_offset=0; - // unsigned short m=dlsch->harq_processes[harq_pid]->mcs; - uint8_t beamforming_mode=0; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); - - A = dlsch->harq_processes[harq_pid]->TBS; //6228 - // printf("Encoder: A: %d\n",A); - mod_order = dlsch->harq_processes[harq_pid]->Qm; - - if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7) - beamforming_mode = 7; - else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8) - beamforming_mode = 8; - else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10) - beamforming_mode = 9; - G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode); - - - // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet - if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet -#ifdef DEBUG_DLSCH_CODING - printf("SIC encoding thinks this is a new packet \n"); -#endif - /* - int i; - printf("dlsch (tx): \n"); - for (i=0;i<(A>>3);i++) - printf("%02x.",a[i]); - printf("\n"); - */ - // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a, - A)>>8; - a[A>>3] = ((uint8_t*)&crc)[2]; - a[1+(A>>3)] = ((uint8_t*)&crc)[1]; - a[2+(A>>3)] = ((uint8_t*)&crc)[0]; - // printf("CRC %x (A %d)\n",crc,A); - - dlsch->harq_processes[harq_pid]->B = A+24; - // dlsch->harq_processes[harq_pid]->b = a; - memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); - - if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, - dlsch->harq_processes[harq_pid]->c, - dlsch->harq_processes[harq_pid]->B, - &dlsch->harq_processes[harq_pid]->C, - &dlsch->harq_processes[harq_pid]->Cplus, - &dlsch->harq_processes[harq_pid]->Cminus, - &dlsch->harq_processes[harq_pid]->Kplus, - &dlsch->harq_processes[harq_pid]->Kminus, - &dlsch->harq_processes[harq_pid]->F)<0) - return(-1); - - for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { - - if (r<dlsch->harq_processes[harq_pid]->Cminus) - Kr = dlsch->harq_processes[harq_pid]->Kminus; - else - Kr = dlsch->harq_processes[harq_pid]->Kplus; - - Kr_bytes = Kr>>3; - - // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14) - if (Kr_bytes<=64) - iind = (Kr_bytes-5); - else if (Kr_bytes <=128) - iind = 59 + ((Kr_bytes-64)>>1); - else if (Kr_bytes <= 256) - iind = 91 + ((Kr_bytes-128)>>2); - else if (Kr_bytes <= 768) - iind = 123 + ((Kr_bytes-256)>>3); - else { - printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes); - return(-1); - } - - -#ifdef DEBUG_DLSCH_CODING - printf("Generating Code Segment %d (%d bits)\n",r,Kr); - // generate codewords - - printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A); - printf("N_RB = %d\n",nb_rb); - printf("Ncp %d\n",frame_parms->Ncp); - printf("mod_order %d\n",mod_order); -#endif - - -#ifdef DEBUG_DLSCH_CODING - printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); -#endif - start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); - stop_meas(te_stats); -#ifdef DEBUG_DLSCH_CODING - - if (r==0) - write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4); - -#endif - start_meas(i_stats); - dlsch->harq_processes[harq_pid]->RTC[r] = - sub_block_interleaving_turbo(4+(Kr_bytes*8), - &dlsch->harq_processes[harq_pid]->d[r][96], - dlsch->harq_processes[harq_pid]->w[r]); - stop_meas(i_stats); - } - - } - - // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the - // outputs for each code segment, see Section 5.1.5 p.20 - - for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { -#ifdef DEBUG_DLSCH_CODING - printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", - r, - G, - Kr*3, - mod_order,nb_rb); -#endif - - start_meas(rm_stats); -#ifdef DEBUG_DLSCH_CODING - printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); -#endif - r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], - G, //G - dlsch->harq_processes[harq_pid]->w[r], - dlsch->harq_processes[harq_pid]->e+r_offset, - dlsch->harq_processes[harq_pid]->C, // C - dlsch->Nsoft, // Nsoft, - dlsch->Mdlharq, - dlsch->Kmimo, - dlsch->harq_processes[harq_pid]->rvidx, - dlsch->harq_processes[harq_pid]->Qm, - dlsch->harq_processes[harq_pid]->Nl, - r, - nb_rb); - // m); // r - stop_meas(rm_stats); -#ifdef DEBUG_DLSCH_CODING - - if (r==dlsch->harq_processes[harq_pid]->C-1) - write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4); - -#endif - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); - - return(0); -} diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 219d618170e4875cb539a2e5f5794fe7e6106483..b2de2e00674029b6fbfb8f64df2bd1c32bf68808 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -29,16 +29,17 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/CODING/defs.h" -#include "PHY/CODING/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/LTE_TRANSPORT/defs.h" -#include "defs.h" +#include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "UTIL/LOG/vcd_signal_dumper.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" -//#define DEBUG_DLSCH_MODULATION 1 +//#define DEBUG_DLSCH_MODULATION +#define NEW_ALLOC_RE //#define is_not_pilot(pilots,re,nushift,use2ndpilots) ((pilots==0) || ((re!=nushift) && (re!=nushift+6)&&((re!=nushift+3)||(use2ndpilots==1))&&((re!=nushift+9)||(use2ndpilots==1)))?1:0) @@ -94,32 +95,8 @@ uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, return(0); } -void generate_64qam_table(void) -{ - - int a,b,c,index; - for (a=-1; a<=1; a+=2) - for (b=-1; b<=1; b+=2) - for (c=-1; c<=1; c+=2) { - index = (1+a)*2 + (1+b) + (1+c)/2; - qam64_table[index] = -a*(QAM64_n1 + b*(QAM64_n2 + (c*QAM64_n3))); // 0 1 2 - } -} - -void generate_16qam_table(void) -{ - - int a,b,index; - - for (a=-1; a<=1; a+=2) - for (b=-1; b<=1; b+=2) { - index = (1+a) + (1+b)/2; - qam16_table[index] = -a*(QAM16_n1 + (b*QAM16_n2)); - } -} - @@ -157,6 +134,158 @@ void layer1prec2A(int32_t *antenna0_sample, int32_t *antenna1_sample, uint8_t pr uint32_t FOUR[2]={0,4}; uint32_t TWO[2]={0,2}; +int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, + int **txdataF, + uint32_t *jj, + uint32_t *jj2, + uint16_t re_offset, + uint32_t symbol_offset, + LTE_DL_eNB_HARQ_t *dlsch0_harq, + LTE_DL_eNB_HARQ_t *dlsch1_harq, + uint8_t pilots, + int16_t amp, + uint8_t precoder_index, + int16_t *qam_table_s0, + int16_t *qam_table_s1, + uint32_t *re_allocated, + uint8_t skip_dc, + uint8_t skip_half, + uint8_t lprime, + uint8_t mprime, + uint8_t Ns, + int *P1_SHIFT, + int *P2_SHIFT) +{ + + LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; + uint8_t *x0 = dlsch0_harq->e; + uint32_t qpsk_table_offset_re = 0; + uint32_t qpsk_table_offset_im = 0; + + uint32_t tti_offset; + uint8_t re; + uint8_t *x0p; + + if (skip_dc == 0) { + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; + re<12; + re++,x0p+=2,tti_offset++) { + + qpsk_table_offset_re=x0p[0]; + qpsk_table_offset_im=x0p[1]; + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; + } + } + else { + // 1st half of PRB + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; + re<6; + re++,x0p+=2,tti_offset++) { + + qpsk_table_offset_re=x0p[0]; + qpsk_table_offset_im=x0p[1]; + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; + } + // 2nd half of PRB + for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7; + re<12; + re++,x0p+=2,tti_offset++) { + + qpsk_table_offset_re=x0p[0]; + qpsk_table_offset_im=x0p[1]; + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; + } + } + *re_allocated = *re_allocated + 12; + *jj=*jj + 24; + + return(0); +} + +int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, + int **txdataF, + uint32_t *jj, + uint32_t *jj2, + uint16_t re_offset, + uint32_t symbol_offset, + LTE_DL_eNB_HARQ_t *dlsch0_harq, + LTE_DL_eNB_HARQ_t *dlsch1_harq, + uint8_t pilots, + int16_t amp, + uint8_t precoder_index, + int16_t *qam_table_s0, + int16_t *qam_table_s1, + uint32_t *re_allocated, + uint8_t skip_dc, + uint8_t skip_half, + uint8_t lprime, + uint8_t mprime, + uint8_t Ns, + int *P1_SHIFT, + int *P2_SHIFT) +{ + + + LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms; + + uint8_t *x0 = dlsch0_harq->e; + uint32_t qpsk_table_offset_re = 0; + uint32_t qpsk_table_offset_im = 0; + + uint32_t tti_offset; + uint8_t re; + uint8_t *x0p; + + + if (skip_dc == 0) { + // printf("pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; + re<12; + x0p+=2) { + + qpsk_table_offset_re=x0p[0]; + qpsk_table_offset_im=x0p[1]; + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; + // printf("pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); + tti_offset+=P1_SHIFT[re+1]; + re+=P1_SHIFT[re+1]; + } + } + else { + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; + re<6; + x0p+=2) { + + qpsk_table_offset_re+=x0p[0]; + qpsk_table_offset_im+=x0p[1]; + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; + tti_offset+=P1_SHIFT[re+1]; + re+=P1_SHIFT[re+1]; + } + + for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6]; + re<12; + x0p+=2) { + + qpsk_table_offset_re+=x0p[0]; + qpsk_table_offset_im+=x0p[1]; + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; + tti_offset+=P1_SHIFT[re+1]; + re+=P1_SHIFT[re+1]; + } + } + *re_allocated = *re_allocated + 10; + *jj=*jj + 20; + + return(0); +} + int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, int **txdataF, uint32_t *jj, @@ -1806,48 +1935,6 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, return(0); } -uint8_t get_pmi(uint8_t N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb) -{ - /* - MIMO_mode_t mode = dlsch_harq->mimo_mode; - uint32_t pmi_alloc = dlsch_harq->pmi_alloc; - */ - - switch (N_RB_DL) { - case 6: // 1 PRB per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>(rb<<1))&3); - else - return((pmi_alloc>>rb)&1); - - break; - - default: - case 25: // 4 PRBs per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>((rb>>2)<<1))&3); - else - return((pmi_alloc>>(rb>>2))&1); - - break; - - case 50: // 6 PRBs per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>((rb/6)<<1))&3); - else - return((pmi_alloc>>(rb/6))&1); - - break; - - case 100: // 8 PRBs per subband - if (mode <= PUSCH_PRECODING1) - return((pmi_alloc>>((rb>>3)<<1))&3); - else - return((pmi_alloc>>(rb>>3))&1); - - break; - } -} inline int check_skip(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) __attribute__((always_inline)); @@ -2012,11 +2099,11 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, uint8_t mod_order0 = 0; uint8_t mod_order1 = 0; int16_t amp_rho_a, amp_rho_b; - int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8]; - int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8]; + int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8];//qpsk_table_a0[2],qpsk_table_b0[2] + int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8];//qpsk_table_a1[2],qpsk_table_b1[2] int16_t *qam_table_s0=NULL,*qam_table_s1=NULL; -#if 0 +#ifdef NEW_ALLOC_RE /* TODO: variable to be removed? */ int (*allocate_REs)(PHY_VARS_eNB*, int **, @@ -2138,7 +2225,15 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13); } - if (mod_order0 == 4) + /*if(mod_order0 == 2) + { + for(i=0;i<2;i++) + { + qpsk_table_a0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15); + qpsk_table_b0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15); + } + } + else*/ if (mod_order0 == 4) for (i=0;i<4; i++) { qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); qam16_table_b0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15); @@ -2149,7 +2244,14 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, qam64_table_b0[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_b)>>15); } - if (mod_order1 == 4) + /*if (mod_order1 == 2) + { + for (i=0; i<2; i++) { + qpsk_table_a1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15); + qpsk_table_b1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15); + } + } + else*/ if (mod_order1 == 4) for (i=0; i<4; i++) { qam16_table_a1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); qam16_table_b1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15); @@ -2271,7 +2373,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, re_offset = frame_parms->first_carrier_offset; symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); -#if 0 +#ifdef NEW_ALLOC_RE /* TODO: remove this code? */ allocate_REs = allocate_REs_in_RB; #endif @@ -2279,11 +2381,30 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, switch (mod_order0) { case 2: qam_table_s0 = NULL; + /*if (pilots) { + qam_table_s0 = qpsk_table_b0; +#ifdef NEW_ALLOC_RE + // TODO: remove this code? // + allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? + allocate_REs_in_RB_pilots_QPSK_siso : + allocate_REs_in_RB; +#endif + } + else { + qam_table_s0 = qpsk_table_a0; +#ifdef NEW_ALLOC_RE + // TODO: remove this code? // + allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? + allocate_REs_in_RB_no_pilots_QPSK_siso : + allocate_REs_in_RB; +#endif + + }*/ break; case 4: if (pilots) { qam_table_s0 = qam16_table_b0; -#if 0 +#ifdef NEW_ALLOC_RE /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_pilots_16QAM_siso : @@ -2292,7 +2413,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, } else { qam_table_s0 = qam16_table_a0; -#if 0 +#ifdef NEW_ALLOC_RE /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_no_pilots_16QAM_siso : @@ -2305,7 +2426,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, case 6: if (pilots) { qam_table_s0 = qam64_table_b0; -#if 0 +#ifdef NEW_ALLOC_RE /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_pilots_64QAM_siso : @@ -2314,7 +2435,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, } else { qam_table_s0 = qam64_table_a0; -#if 0 +#ifdef NEW_ALLOC_RE /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_no_pilots_64QAM_siso : @@ -2328,10 +2449,16 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, switch (mod_order1) { case 2: qam_table_s1 = NULL; -#if 0 +#ifdef NEW_ALLOC_RE /* TODO: remove this code? */ allocate_REs = allocate_REs_in_RB; #endif + /*if (pilots) { + qam_table_s1 = qpsk_table_b1; + } + else { + qam_table_s1 = qpsk_table_a1; + }*/ break; case 4: if (pilots) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index 1345f0e404dc6cc4e79dd2c235f60f89d8eb8589..f5f155c52654b124a6fd2aeebf66344c32ff5b07 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -32,12 +32,12 @@ //#define DEBUG_SCRAMBLING 1 -#include "PHY/defs.h" -#include "PHY/CODING/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "defs.h" -#include "extern.h" -#include "PHY/extern.h" +#include "transport_eNB.h" +#include "PHY/phy_extern.h" #include "UTIL/LOG/vcd_signal_dumper.h" static inline unsigned int lte_gold_scram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); @@ -87,7 +87,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Rule for accumulation of subframes for BL/CE UEs uint8_t Nacc=4; uint16_t j0,j,idelta; @@ -124,7 +124,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, // reset = 1; // x1 is set in lte_gold_generic if (mbsfn_flag == 0) { -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #ifdef PHY_TX_THREAD if (dlsch->harq_processes[harq_pid]->i0 != 0xFFFF) { #else @@ -142,14 +142,18 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } #ifdef DEBUG_SCRAMBLING +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); +#else + printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); +#endif #endif s = lte_gold_scram(&x1, &x2, 1); for (n=0; n<(1+(G>>5)); n++) { #ifdef DEBUG_SCRAMBLING - printf("scrambling %d : %d => ",k,e[k]); + for (int k=0;k<32;k++) printf("scrambling %d : %d xor %d = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1)); #endif @@ -189,9 +193,8 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, // This is not faster for some unknown reason // ((__m128i *)e)[0] = _mm_xor_si128(((__m128i *)e)[0],((__m128i *)scrambling_lut)[s&65535]); // ((__m128i *)e)[1] = _mm_xor_si128(((__m128i *)e)[1],((__m128i *)scrambling_lut)[s>>16]); -#ifdef DEBUG_SCRAMBLING - printf("%d\n",e[k]); -#endif + + s = lte_gold_scram(&x1, &x2, 0); @@ -202,6 +205,20 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } + + +void init_scrambling_lut(void) { + + uint32_t s; + int i=0,j; + + for (s=0;s<=65535;s++) { + for (j=0;j<16;j++) { + scrambling_lut[i++] = (uint8_t)((s>>j)&1); + } + } +} + void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, int mbsfn_flag, LTE_UE_DLSCH_t *dlsch, @@ -231,7 +248,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, for (i=0; i<(1+(G>>5)); i++) { for (j=0; j<32; j++,k++) { #ifdef DEBUG_SCRAMBLING - printf("unscrambling %d : %d => ",k,llr[k]); + printf("unscrambling %d : %d xor %d =",k,llr[k],(s>>j)&1); #endif llr[k] = ((2*((s>>j)&1))-1)*llr[k]; #ifdef DEBUG_SCRAMBLING @@ -243,7 +260,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, } } -void init_unscrambling_lut() { +void init_unscrambling_lut(void) { uint32_t s; int i=0,j; @@ -254,15 +271,3 @@ void init_unscrambling_lut() { } } } - -void init_scrambling_lut() { - - uint32_t s; - int i=0,j; - - for (s=0;s<=65535;s++) { - for (j=0;j<16;j++) { - scrambling_lut[i++] = (uint8_t)((s>>j)&1); - } - } -} diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index 37b1c56349f3edbc727482e8301f47bdcbbf0c61..ca60fd40618b7c2b6f7b5458883c3f6b34d717dc 100755 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -32,21 +32,23 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" +#include "SIMULATION/TOOLS/sim.h" // for taus #include "PHY/sse_intrin.h" - +#include "transport_proto.h" +#include "transport_common_proto.h" #include "assertions.h" #include "T.h" #include "UTIL/LOG/log.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" //#define DEBUG_DCI_ENCODING 1 //#define DEBUG_DCI_DECODING 1 //#define DEBUG_PHY -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void generate_edci_top(PHY_VARS_eNB *eNB, int frame, int subframe) { } diff --git a/openair1/PHY/LTE_TRANSPORT/group_hopping.c b/openair1/PHY/LTE_TRANSPORT/group_hopping.c index a7c8921c2ca0c10a76b666c9b79995b0fb8e10c1..6fc1f0a3e44ade5363eeaa05ce409ec711f135ee 100644 --- a/openair1/PHY/LTE_TRANSPORT/group_hopping.c +++ b/openair1/PHY/LTE_TRANSPORT/group_hopping.c @@ -29,7 +29,8 @@ * \note * \warning */ -#include "PHY/defs.h" +#include "PHY/defs_common.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" //#define DEBUG_GROUPHOP 1 diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index 38ced5d717bd1eabf527d5d7c956c9868097eb9d..986f97c23f930141208bb2e56b5b279bd241647c 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -30,10 +30,10 @@ * \warning */ -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" #include "PHY/TOOLS/alaw_lut.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" //#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" @@ -47,7 +47,7 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { int32_t **txdataF = ru->common.txdataF_BF; int32_t **rxdataF = ru->common.rxdataF; int16_t **prach_rxsigF = ru->prach_rxsigF; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br; #endif void *tx_buffer = ru->ifbuffer.tx[subframe&1]; @@ -105,7 +105,7 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { if ((ru->ifdevice.trx_write_func(&ru->ifdevice, symbol_id, &tx_buffer, - db_fulllength, + db_fulllength, 1, IF4p5_PDLFFT)) < 0) { perror("ETHERNET write for IF4p5_PDLFFT\n"); @@ -138,19 +138,18 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { if (packet_type == IF4p5_PULFFT) { - uint16_t *rx0 = (uint16_t*) &rxdataF[0][blockoffsetF]; - uint16_t *rx1 = (uint16_t*) &rxdataF[0][slotoffsetF]; + for (symbol_id=fp->symbols_per_tti-nsym; symbol_id<fp->symbols_per_tti; symbol_id++) { + uint32_t *rx0 = (uint32_t*) &rxdataF[0][blockoffsetF]; + uint32_t *rx1 = (uint32_t*) &rxdataF[0][slotoffsetF]; - for (symbol_id=fp->symbols_per_tti-nsym; symbol_id<fp->symbols_per_tti; symbol_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF4_SYMBOL, symbol_id ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF4_SYMBOL, symbol_id ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); - start_meas(&ru->compression); - for (element_id=0; element_id<db_halflength; element_id+=8) { - i = (uint16_t*) &rx0[element_id]; + for (element_id=0; element_id<db_halflength; element_id+=8) { + i = (uint16_t*) &rx0[element_id]; d = (uint16_t*) &data_block[element_id]; d[0] = ((uint16_t) lin2alaw_if4p5[i[0]]) | ((uint16_t)(lin2alaw_if4p5[i[1]]<<8)); d[1] = ((uint16_t) lin2alaw_if4p5[i[2]]) | ((uint16_t)(lin2alaw_if4p5[i[3]]<<8)); @@ -176,10 +175,10 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { stop_meas(&ru->compression); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); - packet_header->frame_status &= ~(0x000f<<26); - packet_header->frame_status |= (symbol_id&0x000f)<<26; + packet_header->frame_status &= ~(0x000f<<26); + packet_header->frame_status |= (symbol_id&0x000f)<<26; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); - start_meas(&ru->transport); + start_meas(&ru->transport); if ((ru->ifdevice.trx_write_func(&ru->ifdevice, symbol_id, &tx_buffer, @@ -188,7 +187,7 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { IF4p5_PULFFT)) < 0) { perror("ETHERNET write for IF4p5_PULFFT\n"); } - stop_meas(&ru->transport); + stop_meas(&ru->transport); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); slotoffsetF += fp->ofdm_symbol_size; blockoffsetF += fp->ofdm_symbol_size; @@ -222,7 +221,7 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { int16_t *rxF; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (packet_type > IF4p5_PRACH) rxF = &prach_rxsigF_br[packet_type - IF4p5_PRACH - 1][0][0]; else @@ -263,7 +262,7 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint int32_t **txdataF = ru->common.txdataF_BF; int32_t **rxdataF = ru->common.rxdataF; int16_t **prach_rxsigF = ru->prach_rxsigF; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br; #endif void *rx_buffer = ru->ifbuffer.rx; @@ -351,13 +350,16 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint //if (element_id==0) LOG_I(PHY,"recv_if4p5: symbol %d rxdata0 = (%u,%u)\n",*symbol_number,*i,*(i+1)); } + LOG_D(PHY,"PULFFT_IF4p5: CC_id %d : frame %d, subframe %d (symbol %d)=> %d dB\n",ru->idx,*frame,*subframe,*symbol_number, + dB_fixed(signal_energy((int*)&rxdataF[0][slotoffsetF],db_halflength)+ + signal_energy((int*)&rxdataF[0][blockoffsetF],db_halflength))); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); } else if (*packet_type >= IF4p5_PRACH && *packet_type <= IF4p5_PRACH + 4) { int16_t *rxF; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (*packet_type > IF4p5_PRACH) rxF = &prach_rxsigF_br[*packet_type - IF4p5_PRACH - 1][0][0]; else diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.h b/openair1/PHY/LTE_TRANSPORT/if4_tools.h index 0a95e60ead3c7af2bad4c55e73f742fc0308e4f1..4fcf537f832bcbbfb6ffc1a53213f8a1a2bde30f 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.h +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.h @@ -32,7 +32,7 @@ #ifndef __IF4_TOOLS_H__ #define __IF4_TOOLS_H__ -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" /// Macro for IF4 packet type #define IF4p5_PACKET_TYPE 0x080A diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index b160318a6ee9899366430f656c2f300582a53251..06b4a4ad806fd746323c678dc8a568379f73c82a 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -30,7 +30,7 @@ * \warning */ -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" #include "PHY/TOOLS/alaw_lut.h" #include "time_utils.h" diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.h b/openair1/PHY/LTE_TRANSPORT/if5_tools.h index 84ad5305261b2fa29bbc6fb20aec20f9013715c4..0f24f7becee0334c1e2d900a5b79133bb9130ba8 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.h +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.h @@ -34,7 +34,7 @@ #define __IF5_TOOLS_H__ #include <stdint.h> -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" #define IF5_RRH_GW_DL 0x0022 #define IF5_RRH_GW_UL 0x0023 diff --git a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c index 910610b9694c806262928ccd891a5d38f7128150..a66344611b8c61921472f70b3a2766d9e6586cfe 100644 --- a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c +++ b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c @@ -30,9 +30,9 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/LTE_TRANSPORT/proto.h" +#include "PHY/defs_common.h" +#include "PHY/phy_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" unsigned char get_Qm(unsigned char I_MCS) { diff --git a/openair1/PHY/LTE_TRANSPORT/mdci.h b/openair1/PHY/LTE_TRANSPORT/mdci.h index 1e278f8011b7e15201ff2d622b69ef6a44864bf8..7be278530860fc88792c315130f62e84d77d4292 100644 --- a/openair1/PHY/LTE_TRANSPORT/mdci.h +++ b/openair1/PHY/LTE_TRANSPORT/mdci.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -30,6 +30,9 @@ * \warning */ +#ifndef __M_DCI__H__ +#define __M_DCI__H__ + #include <stdint.h> @@ -467,3 +470,4 @@ struct DCI6_2_di_20MHz { typedef struct DCI6_2_di_20MHz DCI6_2_di_20MHz_t; #define sizeof_DCI6_2_20MHz_t 13 +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c index 9e5b6757fc84e9411c32e28fecd2465b575aac0b..eae88a6afeb794deade5d27373be0bebf142a91f 100644 --- a/openair1/PHY/LTE_TRANSPORT/pbch.c +++ b/openair1/PHY/LTE_TRANSPORT/pbch.c @@ -29,13 +29,14 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/CODING/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "defs.h" -#include "extern.h" -#include "PHY/extern.h" +#include "transport_eNB.h" +#include "transport_proto.h" +#include "PHY/phy_extern.h" #include "PHY/sse_intrin.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" //#define DEBUG_PBCH 1 //#define DEBUG_PBCH_ENCODING @@ -138,6 +139,31 @@ int allocate_pbch_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, return(0); } +void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t *pbch_e, + uint32_t length) +{ + int i; + uint8_t reset; + uint32_t x1, x2, s=0; + + reset = 1; + // x1 is set in lte_gold_generic + x2 = frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.6.1 + // msg("pbch_scrambling: Nid_cell = %d\n",x2); + + for (i=0; i<length; i++) { + if ((i&0x1f)==0) { + s = lte_gold_generic(&x1, &x2, reset); + // printf("lte_gold[%d]=%x\n",i,s); + reset = 0; + } + + pbch_e[i] = (pbch_e[i]&1) ^ ((s>>(i&0x1f))&1); + + } +} + //uint8_t pbch_d[96+(3*(16+PBCH_A))], pbch_w[3*3*(16+PBCH_A)],pbch_e[1920]; //one bit per byte int generate_pbch(LTE_eNB_PBCH *eNB_pbch, int32_t **txdataF, @@ -393,623 +419,5 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, return(0); } -int32_t generate_pbch_emul(PHY_VARS_eNB *phy_vars_eNB,uint8_t *pbch_pdu) -{ - - LOG_D(PHY,"[eNB %d] generate_pbch_emul \n",phy_vars_eNB->Mod_id); - eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.pbch_flag=1; - // Copy PBCH payload - eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.pbch_payload=*(uint32_t *)pbch_pdu; - return(0); -} - -uint16_t pbch_extract(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - uint32_t symbol, - uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms) -{ - - - uint16_t rb,nb_rb=6; - uint8_t i,j,aarx,aatx; - int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; - - uint32_t nsymb = (frame_parms->Ncp==0) ? 7:6; - uint32_t symbol_mod = symbol % nsymb; - - int rx_offset = frame_parms->ofdm_symbol_size-3*12; - int ch_offset = frame_parms->N_RB_DL*6-3*12; - int nushiftmod3 = frame_parms->nushift%3; - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - /* - printf("extract_rbs (nushift %d): symbol_mod=%d, rx_offset=%d, ch_offset=%d\n",frame_parms->nushift,symbol_mod, - (rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))*2, - LTE_CE_OFFSET+ch_offset+(symbol_mod*(frame_parms->ofdm_symbol_size))); - */ - - rxF = &rxdataF[aarx][(rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; - rxF_ext = &rxdataF_ext[aarx][symbol_mod*(6*12)]; - - for (rb=0; rb<nb_rb; rb++) { - // skip DC carrier - if (rb==3) { - rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; - } - - if ((symbol_mod==0) || (symbol_mod==1)) { - j=0; - - for (i=0; i<12; i++) { - if ((i!=nushiftmod3) && - (i!=(nushiftmod3+3)) && - (i!=(nushiftmod3+6)) && - (i!=(nushiftmod3+9))) { - rxF_ext[j++]=rxF[i]; - } - } - - rxF+=12; - rxF_ext+=8; - } else { - for (i=0; i<12; i++) { - rxF_ext[i]=rxF[i]; - } - - rxF+=12; - rxF_ext+=12; - } - } - - for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) { - if (high_speed_flag == 1) - dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset+(symbol*(frame_parms->ofdm_symbol_size))]; - else - dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset]; - - dl_ch0_ext = &dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*(6*12)]; - - for (rb=0; rb<nb_rb; rb++) { - // skip DC carrier - // if (rb==3) dl_ch0++; - if (symbol_mod>1) { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - dl_ch0+=12; - dl_ch0_ext+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i!=nushiftmod3) && - (i!=(nushiftmod3+3)) && - (i!=(nushiftmod3+6)) && - (i!=(nushiftmod3+9))) { - // printf("PBCH extract i %d j %d => (%d,%d)\n",i,j,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); - dl_ch0_ext[j++]=dl_ch0[i]; - } - } - - dl_ch0+=12; - dl_ch0_ext+=8; - } - } - } //tx antenna loop - - } - - return(0); -} - -//__m128i avg128; - -//compute average channel_level on each (TX,RX) antenna pair -int pbch_channel_level(int **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - uint32_t symbol) -{ - - int16_t rb, nb_rb=6; - uint8_t aatx,aarx; - -#if defined(__x86_64__) || defined(__i386__) - __m128i avg128; - __m128i *dl_ch128; -#elif defined(__arm__) - int32x4_t avg128; - int16x8_t *dl_ch128; -#endif - int avg1=0,avg2=0; - - uint32_t nsymb = (frame_parms->Ncp==0) ? 7:6; - uint32_t symbol_mod = symbol % nsymb; - - for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antenna_ports_eNB;aatx++) - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - //clear average level - -#if defined(__x86_64__) || defined(__i386__) - avg128 = _mm_setzero_si128(); - dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12]; -#elif defined(__arm__) - avg128 = vdupq_n_s32(0); - dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12]; - -#endif - for (rb=0; rb<nb_rb; rb++) { -#if defined(__x86_64__) || defined(__i386__) - avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); - avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); - avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); -#elif defined(__arm__) -// to be filled in -#endif - dl_ch128+=3; - /* - if (rb==0) { - print_shorts("dl_ch128",&dl_ch128[0]); - print_shorts("dl_ch128",&dl_ch128[1]); - print_shorts("dl_ch128",&dl_ch128[2]); - } - */ - } - - avg1 = (((int*)&avg128)[0] + - ((int*)&avg128)[1] + - ((int*)&avg128)[2] + - ((int*)&avg128)[3])/(nb_rb*12); - - if (avg1>avg2) - avg2 = avg1; - - //msg("Channel level : %d, %d\n",avg1, avg2); - } -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif - return(avg2); - -} - -#if defined(__x86_64__) || defined(__i386__) -__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3; -#elif defined(__arm__) -int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3; -#endif -void pbch_channel_compensation(int **rxdataF_ext, - int **dl_ch_estimates_ext, - int **rxdataF_comp, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t symbol, - uint8_t output_shift) -{ - - uint16_t rb,nb_rb=6; - uint8_t aatx,aarx,symbol_mod; -#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; -#elif defined(__arm__) - -#endif - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antenna_ports_eNB;aatx++) - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - -#if defined(__x86_64__) || defined(__i386__) - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12]; - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol_mod*6*12]; - rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol_mod*6*12]; - -#elif defined(__arm__) -// to be filled in -#endif - - for (rb=0; rb<nb_rb; rb++) { - //printf("rb %d\n",rb); -#if defined(__x86_64__) || defined(__i386__) - // multiply by conjugated channel - mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpP0); - // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) - mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpP1); - mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[0]); - // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); - // print_ints("re(shift)",&mmtmpP0); - mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); - // print_ints("im(shift)",&mmtmpP1); - mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); - mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); - // print_ints("c0",&mmtmpP2); - // print_ints("c1",&mmtmpP3); - rxdataF_comp128[0] = _mm_packs_epi32(mmtmpP2,mmtmpP3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - - // multiply by conjugated channel - mmtmpP0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) - mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); - mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[1]); - // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); - mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); - mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); - mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpP2,mmtmpP3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); - - if (symbol_mod>1) { - // multiply by conjugated channel - mmtmpP0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) - mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); - mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); - mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[2]); - // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); - mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); - mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); - mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpP2,mmtmpP3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - - dl_ch128+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } else { - dl_ch128+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } -#elif defined(__arm__) -// to be filled in -#endif - } - } -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - -void pbch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - uint8_t symbol) -{ - - uint8_t aatx, symbol_mod; - int i, nb_rb=6; -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1; -#elif defined(__arm__) - int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1; -#endif - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - if (frame_parms->nb_antennas_rx>1) { - for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) { -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12]; -#elif defined(__arm__) - rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12]; - rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12]; - -#endif - // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0; i<nb_rb*3; i++) { -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); -#elif defined(__arm__) - rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); - -#endif - } - } - } -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - -void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t *pbch_e, - uint32_t length) -{ - int i; - uint8_t reset; - uint32_t x1, x2, s=0; - - reset = 1; - // x1 is set in lte_gold_generic - x2 = frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.6.1 - // msg("pbch_scrambling: Nid_cell = %d\n",x2); - - for (i=0; i<length; i++) { - if ((i&0x1f)==0) { - s = lte_gold_generic(&x1, &x2, reset); - // printf("lte_gold[%d]=%x\n",i,s); - reset = 0; - } - - pbch_e[i] = (pbch_e[i]&1) ^ ((s>>(i&0x1f))&1); - - } -} - -void pbch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, - int8_t* llr, - uint32_t length, - uint8_t frame_mod4) -{ - int i; - uint8_t reset; - uint32_t x1, x2, s=0; - - reset = 1; - // x1 is set in first call to lte_gold_generic - x2 = frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.6.1 - // msg("pbch_unscrambling: Nid_cell = %d\n",x2); - - for (i=0; i<length; i++) { - if (i%32==0) { - s = lte_gold_generic(&x1, &x2, reset); - // printf("lte_gold[%d]=%x\n",i,s); - reset = 0; - } - - // take the quarter of the PBCH that corresponds to this frame - if ((i>=(frame_mod4*(length>>2))) && (i<((1+frame_mod4)*(length>>2)))) { - - if (((s>>(i%32))&1)==0) - llr[i] = -llr[i]; - } - } -} - -void pbch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - uint8_t symbol) -{ - - int16_t *rxF0,*rxF1; - // __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b; - uint8_t rb,re,symbol_mod; - int jj; - // printf("Doing alamouti\n"); - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - jj = (symbol_mod*6*12); - - rxF0 = (int16_t*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y - rxF1 = (int16_t*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y - - for (rb=0; rb<6; rb++) { - - for (re=0; re<12; re+=2) { - - // Alamouti RX combining - - rxF0[0] = rxF0[0] + rxF1[2]; - rxF0[1] = rxF0[1] - rxF1[3]; - - rxF0[2] = rxF0[2] - rxF1[0]; - rxF0[3] = rxF0[3] + rxF1[1]; - - rxF0+=4; - rxF1+=4; - } - - } - -} - -void pbch_quantize(int8_t *pbch_llr8, - int16_t *pbch_llr, - uint16_t len) -{ - - uint16_t i; - - for (i=0; i<len; i++) { - if (pbch_llr[i]>7) - pbch_llr8[i]=7; - else if (pbch_llr[i]<-8) - pbch_llr8[i]=-8; - else - pbch_llr8[i] = (char)(pbch_llr[i]); - - } -} - -static unsigned char dummy_w_rx[3*3*(16+PBCH_A)]; -static int8_t pbch_w_rx[3*3*(16+PBCH_A)],pbch_d_rx[96+(3*(16+PBCH_A))]; - - -uint16_t rx_pbch(LTE_UE_COMMON *lte_ue_common_vars, - LTE_UE_PBCH *lte_ue_pbch_vars, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t eNB_id, - MIMO_mode_t mimo_mode, - uint32_t high_speed_flag, - uint8_t frame_mod4) -{ - - uint8_t log2_maxh;//,aatx,aarx; - int max_h=0; - - int symbol,i; - uint32_t nsymb = (frame_parms->Ncp==0) ? 14:12; - uint16_t pbch_E; - uint8_t pbch_a[8]; - uint8_t RCC; - - int8_t *pbch_e_rx; - uint8_t *decoded_output = lte_ue_pbch_vars->decoded_output; - uint16_t crc; - - - // pbch_D = 16+PBCH_A; - - pbch_E = (frame_parms->Ncp==0) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK) - pbch_e_rx = <e_ue_pbch_vars->llr[frame_mod4*(pbch_E>>2)]; -#ifdef DEBUG_PBCH - LOG_D(PHY,"[PBCH] starting symbol loop (Ncp %d, frame_mod4 %d,mimo_mode %d\n",frame_parms->Ncp,frame_mod4,mimo_mode); -#endif - - // clear LLR buffer - memset(lte_ue_pbch_vars->llr,0,pbch_E); - - for (symbol=(nsymb>>1); symbol<(nsymb>>1)+4; symbol++) { - -#ifdef DEBUG_PBCH - LOG_D(PHY,"[PBCH] starting extract\n"); -#endif - pbch_extract(lte_ue_common_vars->common_vars_rx_data_per_thread[0].rxdataF, - lte_ue_common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates[eNB_id], - lte_ue_pbch_vars->rxdataF_ext, - lte_ue_pbch_vars->dl_ch_estimates_ext, - symbol, - high_speed_flag, - frame_parms); -#ifdef DEBUG_PBCH - LOG_D(PHY,"[PHY] PBCH Symbol %d\n",symbol); - LOG_D(PHY,"[PHY] PBCH starting channel_level\n"); -#endif - - max_h = pbch_channel_level(lte_ue_pbch_vars->dl_ch_estimates_ext, - frame_parms, - symbol); - log2_maxh = 3+(log2_approx(max_h)/2); - -#ifdef DEBUG_PBCH - LOG_D(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",log2_maxh,max_h); -#endif - - pbch_channel_compensation(lte_ue_pbch_vars->rxdataF_ext, - lte_ue_pbch_vars->dl_ch_estimates_ext, - lte_ue_pbch_vars->rxdataF_comp, - frame_parms, - symbol, - log2_maxh); // log2_maxh+I0_shift - - if (frame_parms->nb_antennas_rx > 1) - pbch_detection_mrc(frame_parms, - lte_ue_pbch_vars->rxdataF_comp, - symbol); - - - if (mimo_mode == ALAMOUTI) { - pbch_alamouti(frame_parms,lte_ue_pbch_vars->rxdataF_comp,symbol); - } else if (mimo_mode != SISO) { - LOG_D(PHY,"[PBCH][RX] Unsupported MIMO mode\n"); - return(-1); - } - - if (symbol>(nsymb>>1)+1) { - pbch_quantize(pbch_e_rx, - (short*)&(lte_ue_pbch_vars->rxdataF_comp[0][(symbol%(nsymb>>1))*72]), - 144); - - pbch_e_rx+=144; - } else { - pbch_quantize(pbch_e_rx, - (short*)&(lte_ue_pbch_vars->rxdataF_comp[0][(symbol%(nsymb>>1))*72]), - 96); - - pbch_e_rx+=96; - } - - - } - - pbch_e_rx = lte_ue_pbch_vars->llr; - - - - //un-scrambling -#ifdef DEBUG_PBCH - LOG_D(PHY,"[PBCH] doing unscrambling\n"); -#endif - - - pbch_unscrambling(frame_parms, - pbch_e_rx, - pbch_E, - frame_mod4); - - - - //un-rate matching -#ifdef DEBUG_PBCH - LOG_D(PHY,"[PBCH] doing un-rate-matching\n"); -#endif - - - memset(dummy_w_rx,0,3*3*(16+PBCH_A)); - RCC = generate_dummy_w_cc(16+PBCH_A, - dummy_w_rx); - - - lte_rate_matching_cc_rx(RCC,pbch_E,pbch_w_rx,dummy_w_rx,pbch_e_rx); - - sub_block_deinterleaving_cc((unsigned int)(PBCH_A+16), - &pbch_d_rx[96], - &pbch_w_rx[0]); - - memset(pbch_a,0,((16+PBCH_A)>>3)); - - - - - phy_viterbi_lte_sse2(pbch_d_rx+96,pbch_a,16+PBCH_A); - - // Fix byte endian of PBCH (bit 23 goes in first) - for (i=0; i<(PBCH_A>>3); i++) - decoded_output[(PBCH_A>>3)-i-1] = pbch_a[i]; - -#ifdef DEBUG_PBCH - - for (i=0; i<(PBCH_A>>3); i++) - LOG_I(PHY,"[PBCH] pbch_a[%d] = %x\n",i,decoded_output[i]); - -#endif //DEBUG_PBCH - -#ifdef DEBUG_PBCH - LOG_I(PHY,"PBCH CRC %x : %x\n", - crc16(pbch_a,PBCH_A), - ((uint16_t)pbch_a[PBCH_A>>3]<<8)+pbch_a[(PBCH_A>>3)+1]); -#endif - - crc = (crc16(pbch_a,PBCH_A)>>16) ^ - (((uint16_t)pbch_a[PBCH_A>>3]<<8)+pbch_a[(PBCH_A>>3)+1]); - - if (crc == 0x0000) - return(1); - else if (crc == 0xffff) - return(2); - else if (crc == 0x5555) - return(4); - else - return(-1); - - -} diff --git a/openair1/PHY/LTE_TRANSPORT/pcfich.c b/openair1/PHY/LTE_TRANSPORT/pcfich.c index b7e24cb87dad212b71f461996a6a6a89f02468fa..18a156c3fbc004f0421c67eb635c08102833d5e8 100644 --- a/openair1/PHY/LTE_TRANSPORT/pcfich.c +++ b/openair1/PHY/LTE_TRANSPORT/pcfich.c @@ -29,48 +29,13 @@ * \note * \warning */ -#include "PHY/defs.h" +#include "PHY/impl_defs_top.h" +#include "PHY/defs_eNB.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" //#define DEBUG_PCFICH +extern uint8_t pcfich_b[4][32]; -void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) -{ - - uint16_t kbar = 6 * (frame_parms->Nid_cell %(2*frame_parms->N_RB_DL)); - uint16_t first_reg; - uint16_t *pcfich_reg = frame_parms->pcfich_reg; - - pcfich_reg[0] = kbar/6; - first_reg = pcfich_reg[0]; - - frame_parms->pcfich_first_reg_idx=0; - - pcfich_reg[1] = ((kbar + (frame_parms->N_RB_DL>>1)*6)%(frame_parms->N_RB_DL*12))/6; - - if (pcfich_reg[1] < pcfich_reg[0]) { - frame_parms->pcfich_first_reg_idx = 1; - first_reg = pcfich_reg[1]; - } - - pcfich_reg[2] = ((kbar + (frame_parms->N_RB_DL)*6)%(frame_parms->N_RB_DL*12))/6; - - if (pcfich_reg[2] < first_reg) { - frame_parms->pcfich_first_reg_idx = 2; - first_reg = pcfich_reg[2]; - } - - pcfich_reg[3] = ((kbar + ((3*frame_parms->N_RB_DL)>>1)*6)%(frame_parms->N_RB_DL*12))/6; - - if (pcfich_reg[3] < first_reg) { - frame_parms->pcfich_first_reg_idx = 3; - first_reg = pcfich_reg[3]; - } - - - //#ifdef DEBUG_PCFICH - printf("pcfich_reg : %d,%d,%d,%d\n",pcfich_reg[0],pcfich_reg[1],pcfich_reg[2],pcfich_reg[3]); - //#endif -} void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, @@ -96,37 +61,7 @@ void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } } -void pcfich_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t subframe, - int16_t *d) -{ - - uint32_t i; - uint8_t reset; - uint32_t x1, x2, s=0; - reset = 1; - // x1 is set in lte_gold_generic - x2 = ((((2*frame_parms->Nid_cell)+1)*(1+subframe))<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.7.1 - - for (i=0; i<32; i++) { - if ((i&0x1f)==0) { - s = lte_gold_generic(&x1, &x2, reset); - //printf("lte_gold[%d]=%x\n",i,s); - reset = 0; - } - - if (((s>>(i&0x1f))&1) == 1) - d[i]=-d[i]; - - } -} - -uint8_t pcfich_b[4][32]= {{0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1}, - {1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0}, - {1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -}; void generate_pcfich(uint8_t num_pdcch_symbols, int16_t amp, @@ -215,98 +150,3 @@ void generate_pcfich(uint8_t num_pdcch_symbols, } -uint8_t rx_pcfich(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t subframe, - LTE_UE_PDCCH *lte_ue_pdcch_vars, - MIMO_mode_t mimo_mode) -{ - - uint8_t pcfich_quad; - uint8_t i,j; - uint16_t reg_offset; - - int32_t **rxdataF_comp = lte_ue_pdcch_vars->rxdataF_comp; - int16_t pcfich_d[32],*pcfich_d_ptr; - int32_t metric,old_metric=-16384; - uint8_t num_pdcch_symbols=3; - uint16_t *pcfich_reg = frame_parms->pcfich_reg; - - // demapping - // loop over 4 quadruplets and lookup REGs - // m=0; - pcfich_d_ptr = pcfich_d; - - for (pcfich_quad=0; pcfich_quad<4; pcfich_quad++) { - reg_offset = (pcfich_reg[pcfich_quad]*4); - - for (i=0; i<4; i++) { - - pcfich_d_ptr[0] = ((int16_t*)&rxdataF_comp[0][reg_offset+i])[0]; // RE component - pcfich_d_ptr[1] = ((int16_t*)&rxdataF_comp[0][reg_offset+i])[1]; // IM component -#ifdef DEBUG_PCFICH - printf("rx_pcfich: quad %d, i %d, offset %d => (%d,%d) => pcfich_d_ptr[0] %d \n",pcfich_quad,i,reg_offset+i, - ((int16_t*)&rxdataF_comp[0][reg_offset+i])[0], - ((int16_t*)&rxdataF_comp[0][reg_offset+i])[1], - pcfich_d_ptr[0]); -#endif - pcfich_d_ptr+=2; - } - - /* - } - else { // ALAMOUTI - for (i=0;i<4;i+=2) { - pcfich_d_ptr[0] = 0; - pcfich_d_ptr[1] = 0; - pcfich_d_ptr[2] = 0; - pcfich_d_ptr[3] = 0; - for (j=0;j<frame_parms->nb_antennas_rx;j++) { - - pcfich_d_ptr[0] += (((int16_t*)&rxdataF_comp[j][reg_offset+i])[0]+ - ((int16_t*)&rxdataF_comp[j+2][reg_offset+i+1])[0]); // RE component - pcfich_d_ptr[1] += (((int16_t*)&rxdataF_comp[j][reg_offset+i])[1] - - ((int16_t*)&rxdataF_comp[j+2][reg_offset+i+1])[1]);// IM component - - pcfich_d_ptr[2] += (((int16_t*)&rxdataF_comp[j][reg_offset+i+1])[0]- - ((int16_t*)&rxdataF_comp[j+2][reg_offset+i])[0]); // RE component - pcfich_d_ptr[3] += (((int16_t*)&rxdataF_comp[j][reg_offset+i+1])[1] + - ((int16_t*)&rxdataF_comp[j+2][reg_offset+i])[1]);// IM component - - - } - - pcfich_d_ptr+=4; - - } - */ - } - - // pcfhich unscrambling - - pcfich_unscrambling(frame_parms,subframe,pcfich_d); - - // pcfich detection - - for (i=0; i<3; i++) { - metric = 0; - - for (j=0; j<32; j++) { - // printf("pcfich_b[%d][%d] %d => pcfich_d[%d] %d\n",i,j,pcfich_b[i][j],j,pcfich_d[j]); - metric += (int32_t)(((pcfich_b[i][j]==0) ? (pcfich_d[j]) : (-pcfich_d[j]))); - } - -#ifdef DEBUG_PCFICH - printf("metric %d : %d\n",i,metric); -#endif - - if (metric > old_metric) { - num_pdcch_symbols = 1+i; - old_metric = metric; - } - } - -#ifdef DEBUG_PCFICH - printf("[PHY] PCFICH detected for %d PDCCH symbols\n",num_pdcch_symbols); -#endif - return(num_pdcch_symbols); -} diff --git a/openair1/PHY/LTE_TRANSPORT/pcfich_common.c b/openair1/PHY/LTE_TRANSPORT/pcfich_common.c new file mode 100644 index 0000000000000000000000000000000000000000..d6466862a79ba02d4187ab74ada21bfc431549b9 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/pcfich_common.c @@ -0,0 +1,72 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/pcfich.c +* \brief Top-level routines for generating and decoding the PCFICH/CFI physical/transport channel V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#include "PHY/impl_defs_top.h" +#include "PHY/defs_eNB.h" + +void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) +{ + + uint16_t kbar = 6 * (frame_parms->Nid_cell %(2*frame_parms->N_RB_DL)); + uint16_t first_reg; + uint16_t *pcfich_reg = frame_parms->pcfich_reg; + + pcfich_reg[0] = kbar/6; + first_reg = pcfich_reg[0]; + + frame_parms->pcfich_first_reg_idx=0; + + pcfich_reg[1] = ((kbar + (frame_parms->N_RB_DL>>1)*6)%(frame_parms->N_RB_DL*12))/6; + + if (pcfich_reg[1] < pcfich_reg[0]) { + frame_parms->pcfich_first_reg_idx = 1; + first_reg = pcfich_reg[1]; + } + + pcfich_reg[2] = ((kbar + (frame_parms->N_RB_DL)*6)%(frame_parms->N_RB_DL*12))/6; + + if (pcfich_reg[2] < first_reg) { + frame_parms->pcfich_first_reg_idx = 2; + first_reg = pcfich_reg[2]; + } + + pcfich_reg[3] = ((kbar + ((3*frame_parms->N_RB_DL)>>1)*6)%(frame_parms->N_RB_DL*12))/6; + + if (pcfich_reg[3] < first_reg) { + frame_parms->pcfich_first_reg_idx = 3; + first_reg = pcfich_reg[3]; + } + + + //#ifdef DEBUG_PCFICH + printf("pcfich_reg : %d,%d,%d,%d\n",pcfich_reg[0],pcfich_reg[1],pcfich_reg[2],pcfich_reg[3]); + //#endif +} diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index 2bd7140c32ccc96524b58d9e489280bae5cf7754..2e8a6e410c3a9804d109fb0c72b22f8a610e9df4 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1,3 +1,4 @@ + /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with @@ -20,7 +21,7 @@ */ /*! \file PHY/LTE_TRANSPORT/phich.c -* \brief Top-level routines for generating and decoding the PHICH/HI physical/transport channel V8.6 2009-03 +* \brief Top-level routines for generating the PHICH/HI physical/transport channel V8.6 2009-03 * \author R. Knopp * \date 2011 * \version 0.1 @@ -30,15 +31,11 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "defs.h" - -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/defs.h" - +#include "PHY/defs_eNB.h" +#include "PHY/impl_defs_top.h" #include "T.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "transport_common_proto.h" //#define DEBUG_PHICH 1 @@ -48,365 +45,6 @@ //unsigned short phich_reg[MAX_NUM_PHICH_GROUPS][3]; -uint8_t rv_table[4] = {0, 2, 3, 1}; - -uint8_t get_mi(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) -{ - - // for FDD - if (frame_parms->frame_type == FDD) - return 1; - - // for TDD - switch (frame_parms->tdd_config) { - - case 0: - if ((subframe==0) || (subframe==5)) - return(2); - else return(1); - - break; - - case 1: - if ((subframe==0) || (subframe==5)) - return(0); - else return(1); - - break; - - case 2: - if ((subframe==3) || (subframe==8)) - return(1); - else return(0); - - break; - - case 3: - if ((subframe==0) || (subframe==8) || (subframe==9)) - return(1); - else return(0); - - break; - - case 4: - if ((subframe==8) || (subframe==9)) - return(1); - else return(0); - - break; - - case 5: - if (subframe==8) - return(1); - else return(0); - - break; - - case 6: - return(1); - break; - - default: - return(0); - } -} - -unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe) -{ - - if (frame_parms->frame_type == FDD) - return(subframe&7); - - switch (frame_parms->tdd_config) { - case 3: - if ( (subframe == 8) || (subframe == 9) ) { - return(subframe-8); - } else if (subframe==0) - return(2); - else { - LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - return(0); - } - - break; - - case 4: - if ( (subframe == 8) || (subframe == 9) ) { - return(subframe-8); - } else { - LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - return(0); - } - - break; - - } - - return(0); -} - -int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe) -{ - int pusch_frame; - - if (frame_parms->frame_type == FDD) { - pusch_frame = subframe<4 ? frame + 1024 - 1 : frame; - } else { - // Note this is not true, but it doesn't matter, the frame number is irrelevant for TDD! - pusch_frame = (frame); - } - - //LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, subframe, pusch_frame); - return pusch_frame % 1024; -} - -uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) -{ - uint8_t pusch_subframe = 255; - - if (frame_parms->frame_type == FDD) - return subframe < 4 ? subframe + 6 : subframe - 4; - - switch (frame_parms->tdd_config) { - case 0: - if (subframe == 0) - pusch_subframe = (3); - else if (subframe == 5) { - pusch_subframe = (8); - } else if (subframe == 6) - pusch_subframe = (2); - else if (subframe == 1) - pusch_subframe = (7); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 1: - if (subframe == 6) - pusch_subframe = (2); - else if (subframe == 9) - pusch_subframe = (3); - else if (subframe == 1) - pusch_subframe = (7); - else if (subframe == 4) - pusch_subframe = (8); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 2: - if (subframe == 8) - pusch_subframe = (2); - else if (subframe == 3) - pusch_subframe = (7); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 3: - if ( (subframe == 8) || (subframe == 9) ) { - pusch_subframe = (subframe-6); - } else if (subframe==0) - pusch_subframe = (4); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 4: - if ( (subframe == 8) || (subframe == 9) ) { - pusch_subframe = (subframe-6); - } else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 5: - if (subframe == 8) { - pusch_subframe = (2); - } else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 6: - if (subframe == 6) { - pusch_subframe = (2); - } else if (subframe == 9) { - pusch_subframe = (3); - } else if (subframe == 0) { - pusch_subframe = (4); - } else if (subframe == 1) { - pusch_subframe = (7); - } else if (subframe == 5) { - pusch_subframe = (8); - } else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - default: - AssertFatal(1==0, "no implementation for TDD UL/DL-config = %d!\n", frame_parms->tdd_config); - pusch_subframe = (0); - } - - LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", subframe, pusch_subframe); - return pusch_subframe; -} - -int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg) -{ - - if ((reg == frame_parms->pcfich_reg[0]) || - (reg == frame_parms->pcfich_reg[1]) || - (reg == frame_parms->pcfich_reg[2]) || - (reg == frame_parms->pcfich_reg[3])) - return(1); - - return(0); -} - -void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) -{ - - unsigned short n0 = (frame_parms->N_RB_DL * 2) - 4; // 2 REG per RB less the 4 used by PCFICH in first symbol - unsigned short n1 = (frame_parms->N_RB_DL * 3); // 3 REG per RB in second and third symbol - unsigned short n2 = n1; - unsigned short mprime = 0; - unsigned short Ngroup_PHICH; - // uint16_t *phich_reg = frame_parms->phich_reg; - uint16_t *pcfich_reg = frame_parms->pcfich_reg; - - // compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211 - Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; - - - if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) - Ngroup_PHICH++; - - // check if Extended prefix - if (frame_parms->Ncp == 1) { - Ngroup_PHICH<<=1; - } - -#ifdef DEBUG_PHICH - LOG_D(PHY,"Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n", - ((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)), - frame_parms->phich_config_common.phich_resource, - frame_parms->phich_config_common.phich_duration==normal?"normal":"extended", - frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type, - pcfich_reg[frame_parms->pcfich_first_reg_idx], - n0, - n1, - ((frame_parms->Nid_cell))%n0); -#endif - - // This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ... - - for (mprime=0; - mprime<((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)); - mprime++) { - - if (frame_parms->phich_config_common.phich_duration==normal) { // normal PHICH duration - - frame_parms->phich_reg[mprime][0] = (frame_parms->Nid_cell + mprime)%n0; - - if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) - frame_parms->phich_reg[mprime][0]++; - - if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3]) - frame_parms->phich_reg[mprime][0]++; - - if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3]) - frame_parms->phich_reg[mprime][0]++; - - if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) - frame_parms->phich_reg[mprime][0]++; - - frame_parms->phich_reg[mprime][1] = (frame_parms->Nid_cell + mprime + (n0/3))%n0; - - - if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) - frame_parms->phich_reg[mprime][1]++; - - if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3]) - frame_parms->phich_reg[mprime][1]++; - - if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3]) - frame_parms->phich_reg[mprime][1]++; - - if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) - frame_parms->phich_reg[mprime][1]++; - - - frame_parms->phich_reg[mprime][2] = (frame_parms->Nid_cell + mprime + (2*n0/3))%n0; - - if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) - frame_parms->phich_reg[mprime][2]++; - - if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3]) - frame_parms->phich_reg[mprime][2]++; - - if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3]) - frame_parms->phich_reg[mprime][2]++; - - if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) - frame_parms->phich_reg[mprime][2]++; - -#ifdef DEBUG_PHICH - printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); -#endif - } else { // extended PHICH duration - frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0; - frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0; - - frame_parms->phich_reg[mprime<<1][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1; - frame_parms->phich_reg[mprime<<1][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2; - - frame_parms->phich_reg[1+(mprime<<1)][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1; - frame_parms->phich_reg[1+(mprime<<1)][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2; - //#ifdef DEBUG_PHICH - printf("phich_reg :%d => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); - printf("phich_reg :%d => %d,%d,%d\n",1+(mprime<<1),frame_parms->phich_reg[1+(mprime<<1)][0],frame_parms->phich_reg[1+(mprime<<1)][1],frame_parms->phich_reg[1+(mprime<<1)][2]); - //#endif - } - } // mprime loop -} // num_pdcch_symbols loop - - -void generate_phich_emul(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t HI, - uint8_t subframe) -{ - - -} int32_t alam_bpsk_perm1[4] = {2,1,4,3}; // -conj(x) 1 (-1-j) -> 2 (1-j), 2->1, 3 (-1+j) -> (4) 1+j, 4->3 int32_t alam_bpsk_perm2[4] = {3,4,2,1}; // conj(x) 1 (-1-j) -> 3 (-1+j), 3->1, 2 (1-j) -> 4 (1+j), 4->2 @@ -1065,436 +703,6 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms, } // normal/extended prefix } -// This routine demodulates the PHICH and updates PUSCH/ULSCH parameters - -void rx_phich(PHY_VARS_UE *ue, - UE_rxtx_proc_t *proc, - uint8_t subframe, - uint8_t eNB_id) -{ - - - LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]; - - // uint8_t HI; - uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,proc->frame_rx,subframe); - LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - int16_t phich_d[24],*phich_d_ptr,HI16; - // unsigned int i,aa; - int8_t d[24],*dp; - uint16_t reg_offset; - - // scrambling - uint32_t x1, x2, s=0; - uint8_t reset = 1; - int16_t cs[12]; - uint32_t i,i2,i3,phich_quad; - int32_t **rxdataF_comp = pdcch_vars[eNB_id]->rxdataF_comp; - uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH; - uint8_t NSF_PHICH = 4; - uint8_t pusch_subframe; - - int8_t delta_PUSCH_acc[4] = {-1,0,1,3}; - - // check if we're expecting a PHICH in this subframe - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe); - - if (!ulsch) - return; - - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX Status: %d \n",ue->Mod_id,harq_pid,proc->frame_rx,subframe, ulsch->harq_processes[harq_pid]->status); - - if (ulsch->harq_processes[harq_pid]->status == ACTIVE) { - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX ACTIVE\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe); - Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; - - if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) - Ngroup_PHICH++; - - if (frame_parms->Ncp == 1) - NSF_PHICH = 2; - - - ngroup_PHICH = (ulsch->harq_processes[harq_pid]->first_rb + - ulsch->harq_processes[harq_pid]->n_DMRS)%Ngroup_PHICH; - - if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) { - pusch_subframe = phich_subframe2_pusch_subframe(frame_parms,subframe); - - if ((pusch_subframe == 4) || (pusch_subframe == 9)) - ngroup_PHICH += Ngroup_PHICH; - } - - nseq_PHICH = ((ulsch->harq_processes[harq_pid]->first_rb/Ngroup_PHICH) + - ulsch->harq_processes[harq_pid]->n_DMRS)%(2*NSF_PHICH); - } else { - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX %s\n", - ue->Mod_id, - harq_pid, - proc->frame_rx, - subframe, - (ulsch->harq_processes[harq_pid]->status==SCH_IDLE? "SCH_IDLE" : - (ulsch->harq_processes[harq_pid]->status==ACTIVE? "ACTIVE" : - (ulsch->harq_processes[harq_pid]->status==CBA_ACTIVE? "CBA_ACTIVE": - (ulsch->harq_processes[harq_pid]->status==DISABLED? "DISABLED" : "UNKNOWN"))))); - - return; - } - - memset(d,0,24*sizeof(int8_t)); - phich_d_ptr = phich_d; - - // x1 is set in lte_gold_generic - x2 = (((subframe+1)*((frame_parms->Nid_cell<<1)+1))<<9) + frame_parms->Nid_cell; - - s = lte_gold_generic(&x1, &x2, reset); - - // compute scrambling sequence - for (i=0; i<12; i++) { - cs[i] = 1-(((s>>(i&0x1f))&1)<<1); - } - - if (frame_parms->Ncp == 0) { // Normal Cyclic Prefix - - - // 12 output symbols (Msymb) - - for (i=0,i2=0,i3=0; i<3; i++,i2+=4,i3+=8) { - switch (nseq_PHICH) { - case 0: // +1 +1 +1 +1 - d[i3] = cs[i2]; - d[1+i3] = cs[i2]; - d[2+i3] = cs[1+i2]; - d[3+i3] = cs[1+i2]; - d[4+i3] = cs[2+i2]; - d[5+i3] = cs[2+i2]; - d[6+i3] = cs[3+i2]; - d[7+i3] = cs[3+i2]; - break; - - case 1: // +1 -1 +1 -1 - d[i3] = cs[i2]; - d[1+i3] = cs[i2]; - d[2+i3] = -cs[1+i2]; - d[3+i3] = -cs[1+i2]; - d[4+i3] = cs[2+i2]; - d[5+i3] = cs[2+i2]; - d[6+i3] = -cs[3+i2]; - d[7+i3] = -cs[3+i2]; - break; - - case 2: // +1 +1 -1 -1 - d[i3] = cs[i2]; - d[1+i3] = cs[i2]; - d[2+i3] = cs[1+i2]; - d[3+i3] = cs[1+i2]; - d[4+i3] = -cs[2+i2]; - d[5+i3] = -cs[2+i2]; - d[6+i3] = -cs[3+i2]; - d[7+i3] = -cs[3+i2]; - break; - - case 3: // +1 -1 -1 +1 - d[i3] = cs[i2]; - d[1+i3] = cs[i2]; - d[2+i3] = -cs[1+i2]; - d[3+i3] = -cs[1+i2]; - d[4+i3] = -cs[2+i2]; - d[5+i3] = -cs[2+i2]; - d[6+i3] = cs[3+i2]; - d[7+i3] = cs[3+i2]; - break; - - case 4: // +j +j +j +j - d[i3] = -cs[i2]; - d[1+i3] = cs[i2]; - d[2+i3] = -cs[1+i2]; - d[3+i3] = cs[1+i2]; - d[4+i3] = -cs[2+i2]; - d[5+i3] = cs[2+i2]; - d[6+i3] = -cs[3+i2]; - d[7+i3] = cs[3+i2]; - break; - - case 5: // +j -j +j -j - d[1+i3] = cs[i2]; - d[3+i3] = -cs[1+i2]; - d[5+i3] = cs[2+i2]; - d[7+i3] = -cs[3+i2]; - d[i3] = -cs[i2]; - d[2+i3] = cs[1+i2]; - d[4+i3] = -cs[2+i2]; - d[6+i3] = cs[3+i2]; - break; - - case 6: // +j +j -j -j - d[1+i3] = cs[i2]; - d[3+i3] = cs[1+i2]; - d[5+i3] = -cs[2+i2]; - d[7+i3] = -cs[3+i2]; - d[i3] = -cs[i2]; - d[2+i3] = -cs[1+i2]; - d[4+i3] = cs[2+i2]; - d[6+i3] = cs[3+i2]; - break; - - case 7: // +j -j -j +j - d[1+i3] = cs[i2]; - d[3+i3] = -cs[1+i2]; - d[5+i3] = -cs[2+i2]; - d[7+i3] = cs[3+i2]; - d[i3] = -cs[i2]; - d[2+i3] = cs[1+i2]; - d[4+i3] = cs[2+i2]; - d[6+i3] = -cs[3+i2]; - break; - - default: - AssertFatal(1==0,"phich_coding.c: Illegal PHICH Number\n"); - } // nseq_PHICH - } - -#ifdef DEBUG_PHICH - LOG_D(PHY,"PHICH =>"); - - for (i=0; i<24; i++) { - LOG_D(PHY,"%2d,",d[i]); - } - - LOG_D(PHY,"\n"); -#endif - // demodulation here - - - } else { // extended prefix - - // 6 output symbols - if ((ngroup_PHICH & 1) == 1) - dp = &d[4]; - else - dp = d; - - switch (nseq_PHICH) { - case 0: // +1 +1 - dp[0] = cs[0]; - dp[2] = cs[1]; - dp[8] = cs[2]; - dp[10] = cs[3]; - dp[16] = cs[4]; - dp[18] = cs[5]; - dp[1] = cs[0]; - dp[3] = cs[1]; - dp[9] = cs[2]; - dp[11] = cs[3]; - dp[17] = cs[4]; - dp[19] = cs[5]; - break; - - case 1: // +1 -1 - dp[0] = cs[0]; - dp[2] = -cs[1]; - dp[8] = cs[2]; - dp[10] = -cs[3]; - dp[16] = cs[4]; - dp[18] = -cs[5]; - dp[1] = cs[0]; - dp[3] = -cs[1]; - dp[9] = cs[2]; - dp[11] = -cs[3]; - dp[17] = cs[4]; - dp[19] = -cs[5]; - break; - - case 2: // +j +j - dp[1] = cs[0]; - dp[3] = cs[1]; - dp[9] = cs[2]; - dp[11] = cs[3]; - dp[17] = cs[4]; - dp[19] = cs[5]; - dp[0] = -cs[0]; - dp[2] = -cs[1]; - dp[8] = -cs[2]; - dp[10] = -cs[3]; - dp[16] = -cs[4]; - dp[18] = -cs[5]; - - break; - - case 3: // +j -j - dp[1] = cs[0]; - dp[3] = -cs[1]; - dp[9] = cs[2]; - dp[11] = -cs[3]; - dp[17] = cs[4]; - dp[19] = -cs[5]; - dp[0] = -cs[0]; - dp[2] = cs[1]; - dp[8] = -cs[2]; - dp[10] = cs[3]; - dp[16] = -cs[4]; - dp[18] = cs[5]; - break; - - default: - AssertFatal(1==0,"phich_coding.c: Illegal PHICH Number\n"); - } - } - - HI16 = 0; - - //#ifdef DEBUG_PHICH - - //#endif - /* - for (i=0;i<200;i++) - printf("re %d: %d %d\n",i,((int16_t*)&rxdataF_comp[0][i])[0],((int16_t*)&rxdataF_comp[0][i])[1]); - */ - for (phich_quad=0; phich_quad<3; phich_quad++) { - if (frame_parms->Ncp == 1) - reg_offset = (frame_parms->phich_reg[ngroup_PHICH][phich_quad]*4)+ (phich_quad*frame_parms->N_RB_DL*12); - else - reg_offset = (frame_parms->phich_reg[ngroup_PHICH][phich_quad]*4); - - // msg("\n[PUSCH 0]PHICH (RX) quad %d (%d)=>",phich_quad,reg_offset); - dp = &d[phich_quad*8];; - - for (i=0; i<8; i++) { - phich_d_ptr[i] = ((int16_t*)&rxdataF_comp[0][reg_offset])[i]; - -#ifdef DEBUG_PHICH - LOG_D(PHY,"%d,",((int16_t*)&rxdataF_comp[0][reg_offset])[i]); -#endif - - HI16 += (phich_d_ptr[i] * dp[i]); - } - } - -#ifdef DEBUG_PHICH - LOG_D(PHY,"\n"); - LOG_D(PHY,"HI16 %d\n",HI16); -#endif - - if (HI16>0) { //NACK - if (ue->ulsch_Msg3_active[eNB_id] == 1) { - LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received NAK (%d) nseq %d, ngroup %d\n", - ue->Mod_id,harq_pid, - proc->frame_rx, - subframe, - HI16, - nseq_PHICH, - ngroup_PHICH); - - ulsch->f_pusch += delta_PUSCH_acc[ulsch->harq_processes[harq_pid]->TPC]; - - LOG_D(PHY,"[PUSCH %d] AbsSubframe %d.%d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n", - harq_pid,proc->frame_rx,subframe,ulsch->f_pusch, - delta_PUSCH_acc[ulsch->harq_processes[harq_pid]->TPC], - ulsch->harq_processes[harq_pid]->TPC); - - - ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; - // ulsch->harq_processes[harq_pid]->Ndi = 0; - ulsch->harq_processes[harq_pid]->round++; - ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; - - if (ulsch->harq_processes[harq_pid]->round>=ue->frame_parms.maxHARQ_Msg3Tx) { - ulsch->harq_processes[harq_pid]->subframe_scheduling_flag =0; - ulsch->harq_processes[harq_pid]->status = SCH_IDLE; - // inform MAC that Msg3 transmission has failed - ue->ulsch_Msg3_active[eNB_id] = 0; - } - } else { -#ifdef UE_DEBUG_TRACE - 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, - HI16, - nseq_PHICH, - ngroup_PHICH, - ulsch->harq_processes[harq_pid]->round, - ulsch->Mlimit); -#endif - - // ulsch->harq_processes[harq_pid]->Ndi = 0; - ulsch->harq_processes[harq_pid]->round++; - - if ( ulsch->harq_processes[harq_pid]->round >= (ulsch->Mlimit - 1) ) - { - // this is last push re transmission - ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; - ulsch->O_RI = 0; - ulsch->O = 0; - ulsch->uci_format = HLC_subband_cqi_nopmi; - - // disable phich decoding since it is the last retransmission - ulsch->harq_processes[harq_pid]->status = SCH_IDLE; - - //ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - //ulsch->harq_processes[harq_pid]->round = 0; - - //LOG_I(PHY,"PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid); - //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->Mlimit, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); - } - else - { - // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; - ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; - ulsch->O_RI = 0; - ulsch->O = 0; - ulsch->uci_format = HLC_subband_cqi_nopmi; - //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round); - } - } -#if T_TRACER - T(T_UE_PHY_ULSCH_UE_NACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ulsch->rnti), - T_INT(harq_pid)); -#endif - - } else { //ACK - if (ue->ulsch_Msg3_active[eNB_id] == 1) { - LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", - ue->Mod_id,harq_pid, - proc->frame_rx, - subframe, - HI16, - nseq_PHICH,ngroup_PHICH); - } else { -#ifdef UE_DEBUG_TRACE - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", - ue->Mod_id,harq_pid, - proc->frame_rx%1024, - subframe, HI16, - nseq_PHICH,ngroup_PHICH); -#endif - } - - // LOG_I(PHY,"[HARQ-UL harqId: %d] subframe_scheduling_flag = %d \n",harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag); - - // Incase of adaptive retransmission, PHICH is always decoded as ACK (at least with OAI-eNB) - // Workaround: - // rely only on DCI0 decoding and check if NDI has toggled - // save current harq_processes content in temporary struct - // harqId-8 corresponds to the temporary struct. In total we have 8 harq process(0 ..7) + 1 temporary harq process() - //ulsch->harq_processes[8] = ulsch->harq_processes[harq_pid]; - - - ulsch->harq_processes[harq_pid]->status = SCH_IDLE; - ulsch->harq_processes[harq_pid]->round = 0; - ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - // inform MAC? - ue->ulsch_Msg3_active[eNB_id] = 0; - -#if T_TRACER - T(T_UE_PHY_ULSCH_UE_ACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ulsch->rnti), - T_INT(harq_pid)); -#endif - - } - -} void generate_phich_top(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, diff --git a/openair1/PHY/LTE_TRANSPORT/phich_common.c b/openair1/PHY/LTE_TRANSPORT/phich_common.c new file mode 100644 index 0000000000000000000000000000000000000000..a3bc5250d5f79699e693cc77fd4855905a946801 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/phich_common.c @@ -0,0 +1,383 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/phich_common.c +* \brief Top-level routines for generating and decoding the PHICH/HI physical/transport channel V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ + +#include "PHY/defs_eNB.h" + + +uint8_t get_mi(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) +{ + + // for FDD + if (frame_parms->frame_type == FDD) + return 1; + + // for TDD + switch (frame_parms->tdd_config) { + + case 0: + if ((subframe==0) || (subframe==5)) + return(2); + else return(1); + + break; + + case 1: + if ((subframe==0) || (subframe==5)) + return(0); + else return(1); + + break; + + case 2: + if ((subframe==3) || (subframe==8)) + return(1); + else return(0); + + break; + + case 3: + if ((subframe==0) || (subframe==8) || (subframe==9)) + return(1); + else return(0); + + break; + + case 4: + if ((subframe==8) || (subframe==9)) + return(1); + else return(0); + + break; + + case 5: + if (subframe==8) + return(1); + else return(0); + + break; + + case 6: + return(1); + break; + + default: + return(0); + } +} + +unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe) +{ + + if (frame_parms->frame_type == FDD) + return(subframe&7); + + switch (frame_parms->tdd_config) { + case 3: + if ( (subframe == 8) || (subframe == 9) ) { + return(subframe-8); + } else if (subframe==0) + return(2); + else { + LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + + case 4: + if ( (subframe == 8) || (subframe == 9) ) { + return(subframe-8); + } else { + LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + + } + + return(0); +} + +int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe) +{ + int pusch_frame; + + if (frame_parms->frame_type == FDD) { + pusch_frame = subframe<4 ? frame + 1024 - 1 : frame; + } else { + // Note this is not true, but it doesn't matter, the frame number is irrelevant for TDD! + pusch_frame = (frame); + } + + //LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, subframe, pusch_frame); + return pusch_frame % 1024; +} + +uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) +{ + uint8_t pusch_subframe = 255; + + if (frame_parms->frame_type == FDD) + return subframe < 4 ? subframe + 6 : subframe - 4; + + switch (frame_parms->tdd_config) { + case 0: + if (subframe == 0) + pusch_subframe = (3); + else if (subframe == 5) { + pusch_subframe = (8); + } else if (subframe == 6) + pusch_subframe = (2); + else if (subframe == 1) + pusch_subframe = (7); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 1: + if (subframe == 6) + pusch_subframe = (2); + else if (subframe == 9) + pusch_subframe = (3); + else if (subframe == 1) + pusch_subframe = (7); + else if (subframe == 4) + pusch_subframe = (8); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 2: + if (subframe == 8) + pusch_subframe = (2); + else if (subframe == 3) + pusch_subframe = (7); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 3: + if ( (subframe == 8) || (subframe == 9) ) { + pusch_subframe = (subframe-6); + } else if (subframe==0) + pusch_subframe = (4); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 4: + if ( (subframe == 8) || (subframe == 9) ) { + pusch_subframe = (subframe-6); + } else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 5: + if (subframe == 8) { + pusch_subframe = (2); + } else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 6: + if (subframe == 6) { + pusch_subframe = (2); + } else if (subframe == 9) { + pusch_subframe = (3); + } else if (subframe == 0) { + pusch_subframe = (4); + } else if (subframe == 1) { + pusch_subframe = (7); + } else if (subframe == 5) { + pusch_subframe = (8); + } else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + default: + AssertFatal(1==0, "no implementation for TDD UL/DL-config = %d!\n", frame_parms->tdd_config); + pusch_subframe = (0); + } + + LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", subframe, pusch_subframe); + return pusch_subframe; +} + +int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg) +{ + + if ((reg == frame_parms->pcfich_reg[0]) || + (reg == frame_parms->pcfich_reg[1]) || + (reg == frame_parms->pcfich_reg[2]) || + (reg == frame_parms->pcfich_reg[3])) + return(1); + + return(0); +} + +void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) +{ + + unsigned short n0 = (frame_parms->N_RB_DL * 2) - 4; // 2 REG per RB less the 4 used by PCFICH in first symbol + unsigned short n1 = (frame_parms->N_RB_DL * 3); // 3 REG per RB in second and third symbol + unsigned short n2 = n1; + unsigned short mprime = 0; + unsigned short Ngroup_PHICH; + // uint16_t *phich_reg = frame_parms->phich_reg; + uint16_t *pcfich_reg = frame_parms->pcfich_reg; + + // compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211 + Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; + + + if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) + Ngroup_PHICH++; + + // check if Extended prefix + if (frame_parms->Ncp == 1) { + Ngroup_PHICH<<=1; + } + +#ifdef DEBUG_PHICH + LOG_D(PHY,"Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n", + ((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)), + frame_parms->phich_config_common.phich_resource, + frame_parms->phich_config_common.phich_duration==normal?"normal":"extended", + frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type, + pcfich_reg[frame_parms->pcfich_first_reg_idx], + n0, + n1, + ((frame_parms->Nid_cell))%n0); +#endif + + // This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ... + + for (mprime=0; + mprime<((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)); + mprime++) { + + if (frame_parms->phich_config_common.phich_duration==normal) { // normal PHICH duration + + frame_parms->phich_reg[mprime][0] = (frame_parms->Nid_cell + mprime)%n0; + + if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) + frame_parms->phich_reg[mprime][0]++; + + if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3]) + frame_parms->phich_reg[mprime][0]++; + + if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3]) + frame_parms->phich_reg[mprime][0]++; + + if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) + frame_parms->phich_reg[mprime][0]++; + + frame_parms->phich_reg[mprime][1] = (frame_parms->Nid_cell + mprime + (n0/3))%n0; + + + if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) + frame_parms->phich_reg[mprime][1]++; + + if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3]) + frame_parms->phich_reg[mprime][1]++; + + if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3]) + frame_parms->phich_reg[mprime][1]++; + + if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) + frame_parms->phich_reg[mprime][1]++; + + + frame_parms->phich_reg[mprime][2] = (frame_parms->Nid_cell + mprime + (2*n0/3))%n0; + + if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) + frame_parms->phich_reg[mprime][2]++; + + if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3]) + frame_parms->phich_reg[mprime][2]++; + + if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+2)&3]) + frame_parms->phich_reg[mprime][2]++; + + if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) + frame_parms->phich_reg[mprime][2]++; + +#ifdef DEBUG_PHICH + printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); +#endif + } else { // extended PHICH duration + frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0; + frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0; + + frame_parms->phich_reg[mprime<<1][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1; + frame_parms->phich_reg[mprime<<1][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2; + + frame_parms->phich_reg[1+(mprime<<1)][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1; + frame_parms->phich_reg[1+(mprime<<1)][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2; + //#ifdef DEBUG_PHICH + printf("phich_reg :%d => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); + printf("phich_reg :%d => %d,%d,%d\n",1+(mprime<<1),frame_parms->phich_reg[1+(mprime<<1)][0],frame_parms->phich_reg[1+(mprime<<1)][1],frame_parms->phich_reg[1+(mprime<<1)][2]); + //#endif + } + } // mprime loop +} // num_pdcch_symbols loop diff --git a/openair1/PHY/LTE_TRANSPORT/pilots.c b/openair1/PHY/LTE_TRANSPORT/pilots.c index 01b4bb7a8ea4e1ec0703e6ff51ce018e51d3da77..921f93ddb103ccf41017644057f97c92137ba320 100644 --- a/openair1/PHY/LTE_TRANSPORT/pilots.c +++ b/openair1/PHY/LTE_TRANSPORT/pilots.c @@ -29,8 +29,8 @@ * \note * \warning */ -//#include "defs.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" void generate_pilots(PHY_VARS_eNB *eNB, int32_t **txdataF, diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c index 90e9ae329caed2bf17853f64ea511e4315ec21d8..fddc29b5242f4d005851fedf1b95b6d639619d24 100644 --- a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c +++ b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c @@ -29,9 +29,9 @@ * \note * \warning */ -//#include "defs.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" int generate_mbsfn_pilot(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c deleted file mode 100644 index 63aac7f091b0288eb172e775ca103e5eec6a80f2..0000000000000000000000000000000000000000 --- a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c +++ /dev/null @@ -1,209 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 -* \author X.JIANG -* \date 2011 -* \version 0.1 -* \company Eurecom -* \email: xiwen.jiangeurecom.fr -* \note -* \warning -*/ -//#include "defs.h" -#include "PHY/defs.h" - -void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB, - uint8_t UE_id, - int32_t **txdataF, - int16_t amp, - uint16_t Ntti, - uint8_t beamforming_mode) -{ - - /*LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms; - - uint32_t tti,tti_offset,slot_offset,Nsymb,samples_per_symbol; - uint8_t second_pilot,aa; - - // printf("Doing TX pilots Nsymb %d, second_pilot %d\n",Nsymb,second_pilot); - - switch(beamforming_mode){ - case 7: - for (tti=0; tti<Ntti; tti++) { - - tti_offset = tti*frame_parms->ofdm_symbol_size*Nsymb; - samples_per_symbol = frame_parms->ofdm_symbol_size; - slot_offset = (tti*2)%20; - - // printf("tti %d : offset %d (slot %d)\n",tti,tti_offset,slot_offset); - //Generate UE specific Pilots - printf("generate_dl_ue_spec:tti_offset=%d\n",tti_offset); - - if(frame_parms->Ncp==0) { - for(aa=0;aa<frame_parms->nb_antennas_tx;aa++){ - //antenna port 5 symbol 0 slot 0 - lte_dl_ue_spec(phy_vars_eNB, - UE_id, - &txdataF[aa][tti_offset+3*samples_per_symbol], - amp, - slot_offset, - 1, - 5, - 0); - - //antenna port 5 symbol 1 slot 0 - lte_dl_ue_spec(phy_vars_eNB, - UE_id, - &txdataF[aa][tti_offset+6*samples_per_symbol], - amp, - slot_offset, - 1, - 5, - 0); - - //antenna port 5 symbol 0 slot 1 - lte_dl_ue_spec(phy_vars_eNB, - UE_id, - &txdataF[aa][tti_offset+9*samples_per_symbol], - amp, - slot_offset+1, - 0, - 5, - 0); - - //antenna port 5 symbol 1 slot 1 - lte_dl_ue_spec(phy_vars_eNB, - UE_id, - &txdataF[aa][tti_offset+12*samples_per_symbol], - amp, - slot_offset+1, - 1, - 5, - 0); - } - } else{ - msg("generate_ue_soec_pilots:Extented Cyclic Prefix for TM7 is not supported yet.\n"); - } - - - } - break; - - case 8: - case 9: - case 10: - default: - msg("[generate_ue_spec_pilots(in uespec_pilots.c)]ERROR:beamforming mode %d is not supported\n",beamforming_mode); - - }*/ -} - -/*int generate_ue_spec_pilots_slot(PHY_VARS_eNB *phy_vars_eNB, - int32_t **txdataF, - int16_t amp, - uint16_t slot, - int first_pilot_only) -{ - - LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms; - uint32_t slot_offset,Nsymb,samples_per_symbol; - uint8_t second_pilot; - - if (slot<0 || slot>= 20) { - msg("generate_pilots_slot: slot not in range (%d)\n",slot); - return(-1); - } - - Nsymb = (frame_parms->Ncp==0)?7:6; - second_pilot = (frame_parms->Ncp==0)?4:3; - - - slot_offset = slot*frame_parms->ofdm_symbol_size*Nsymb; - samples_per_symbol = frame_parms->ofdm_symbol_size; - - // printf("tti %d : offset %d (slot %d)\n",tti,tti_offset,slot_offset); - //Generate Pilots - - //antenna 0 symbol 0 slot 0 - lte_dl_cell_spec(phy_vars_eNB, - &txdataF[0][slot_offset], - amp, - slot, - 0, - 0); - - - if (first_pilot_only==0) { - //antenna 0 symbol 3 slot 0 - lte_dl_cell_spec(phy_vars_eNB, - &txdataF[0][slot_offset+(second_pilot*samples_per_symbol)], - amp, - slot, - 1, - 0); - } - - if (frame_parms->nb_antennas_tx > 1) { - if (frame_parms->mode1_flag) { - // antenna 1 symbol 0 slot 0 - lte_dl_cell_spec(phy_vars_eNB, - &txdataF[1][slot_offset], - amp, - slot, - 0, - 0); - - if (first_pilot_only==0) { - // antenna 1 symbol 3 slot 0 - lte_dl_cell_spec(phy_vars_eNB, - &txdataF[1][slot_offset+(second_pilot*samples_per_symbol)], - amp, - slot, - 1, - 0); - } - } else { - - // antenna 1 symbol 0 slot 0 - lte_dl_cell_spec(phy_vars_eNB, - &txdataF[1][slot_offset], - amp, - slot, - 0, - 1); - - if (first_pilot_only == 0) { - // antenna 1 symbol 3 slot 0 - lte_dl_cell_spec(phy_vars_eNB, - &txdataF[1][slot_offset+(second_pilot*samples_per_symbol)], - amp, - slot, - 1, - 1); - } - } - } - - return(0); -}*/ - diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c index e756df1fe1a5b4fd4612d0f019bca3bd57c7a64f..23bc07f17448806c4c2a8563f47bf86f647fc024 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch.c @@ -19,10 +19,11 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/sse_intrin.h" - +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "transport_eNB.h" +#include "transport_proto.h" +#include "transport_common_proto.h" // Mask for identifying subframe for MBMS #define MBSFN_TDD_SF3 0x80// for TDD #define MBSFN_TDD_SF4 0x40 @@ -30,7 +31,7 @@ #define MBSFN_TDD_SF8 0x10 #define MBSFN_TDD_SF9 0x08 -#include "PHY/defs.h" + #define MBSFN_FDD_SF1 0x80// for FDD #define MBSFN_FDD_SF2 0x40 @@ -41,148 +42,6 @@ -void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe) -{ - - unsigned int nsymb_pmch=12; - char fname[32],vname[32]; - int N_RB_DL=ue->frame_parms.N_RB_DL; - - sprintf(fname,"mch_rxF_ext0.m"); - sprintf(vname,"pmch_rxF_ext0"); - write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb_pmch,1,1); - sprintf(fname,"mch_ch_ext00.m"); - sprintf(vname,"pmch_ch_ext00"); - write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb_pmch,1,1); - /* - write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb_pmch,1,1); - write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb_pmch,1,1); - write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb_pmch,1,1); - write_output("dlsch%d_rho.m","dl_rho",pdsch_vars[eNB_id]->rho[0],12*N_RB_DL*nsymb_pmch,1,1); - */ - sprintf(fname,"mch_rxF_comp0.m"); - sprintf(vname,"pmch_rxF_comp0"); - write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb_pmch,1,1); - sprintf(fname,"mch_rxF_llr.m"); - sprintf(vname,"pmch_llr"); - write_output(fname,vname, ue->pdsch_vars_MCH[eNB_id]->llr[0],coded_bits_per_codeword,1,0); - sprintf(fname,"mch_mag1.m"); - sprintf(vname,"pmch_mag1"); - write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb_pmch,1,1); - sprintf(fname,"mch_mag2.m"); - sprintf(vname,"pmch_mag2"); - write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb_pmch,1,1); - - write_output("mch00_ch0.m","pmch00_ch0", - &(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), - ue->frame_parms.ofdm_symbol_size*12,1,1); - - write_output("rxsig_mch.m","rxs_mch", - &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti], - ue->frame_parms.samples_per_tti,1,1); - - /* - if (PHY_vars_eNB_g) - write_output("txsig_mch.m","txs_mch", - &PHY_vars_eNB_g[0][0]->common_vars.txdata[0][0][subframe*ue->frame_parms.samples_per_tti], - ue->frame_parms.samples_per_tti,1,1);*/ -} - -int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) -{ - - uint32_t period; - uint8_t i; - - // LOG_D(PHY,"is_pmch_subframe: frame %d, subframe %d, num_MBSFN_config %d\n", - // frame,subframe,frame_parms->num_MBSFN_config); - - for (i=0; i<frame_parms->num_MBSFN_config; i++) { // we have at least one MBSFN configuration - period = 1<<frame_parms->MBSFN_config[i].radioframeAllocationPeriod; - - if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) { - if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) { - if (frame_parms->frame_type == FDD) { - switch (subframe) { - - case 1: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF1) > 0) - return(1); - - break; - - case 2: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF2) > 0) - return(1); - - break; - - case 3: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF3) > 0) - return(1); - - break; - - case 6: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF6) > 0) - return(1); - - break; - - case 7: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF7) > 0) - return(1); - - break; - - case 8: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF8) > 0) - return(1); - - break; - } - } else { - switch (subframe) { - case 3: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF3) > 0) - return(1); - - break; - - case 4: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF4) > 0) - return(1); - - break; - - case 7: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF7) > 0) - return(1); - - break; - - case 8: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF8) > 0) - return(1); - - break; - - case 9: - if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF9) > 0) - return(1); - - break; - } - } - - } else { // handle 4 frames case - - } - } - } - - return(0); -} void fill_eNB_dlsch_MCH(PHY_VARS_eNB *eNB,int mcs,int ndi,int rvidx) { @@ -221,64 +80,8 @@ void fill_eNB_dlsch_MCH(PHY_VARS_eNB *eNB,int mcs,int ndi,int rvidx) break; } - if (eNB->abstraction_flag) { - eNB_transport_info[eNB->Mod_id][eNB->CC_id].cntl.pmch_flag=1; - eNB_transport_info[eNB->Mod_id][eNB->CC_id].num_pmch=1; // assumption: there is always one pmch in each SF - eNB_transport_info[eNB->Mod_id][eNB->CC_id].num_common_dci=0; - eNB_transport_info[eNB->Mod_id][eNB->CC_id].num_ue_spec_dci=0; - eNB_transport_info[eNB->Mod_id][eNB->CC_id].dlsch_type[0]=5;// put at the reserved position for PMCH - eNB_transport_info[eNB->Mod_id][eNB->CC_id].harq_pid[0]=0; - eNB_transport_info[eNB->Mod_id][eNB->CC_id].ue_id[0]=255;//broadcast - eNB_transport_info[eNB->Mod_id][eNB->CC_id].tbs[0]=dlsch->harq_processes[0]->TBS>>3; - } - } -void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id) -{ - - LTE_UE_DLSCH_t *dlsch = ue->dlsch_MCH[eNB_id]; - LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - - // dlsch->rnti = M_RNTI; - dlsch->harq_processes[0]->mcs = mcs; - dlsch->harq_processes[0]->rvidx = rvidx; - // dlsch->harq_processes[0]->Ndi = ndi; - dlsch->harq_processes[0]->Nl = 1; - dlsch->harq_processes[0]->TBS = TBStable[get_I_TBS(dlsch->harq_processes[0]->mcs)][frame_parms->N_RB_DL-1]; - dlsch->current_harq_pid = 0; - dlsch->harq_processes[0]->nb_rb = frame_parms->N_RB_DL; - - switch(frame_parms->N_RB_DL) { - case 6: - dlsch->harq_processes[0]->rb_alloc_even[0] = 0x3f; - dlsch->harq_processes[0]->rb_alloc_odd[0] = 0x3f; - break; - - case 25: - dlsch->harq_processes[0]->rb_alloc_even[0] = 0x1ffffff; - dlsch->harq_processes[0]->rb_alloc_odd[0] = 0x1ffffff; - break; - - case 50: - dlsch->harq_processes[0]->rb_alloc_even[0] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_odd[0] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_even[1] = 0x3ffff; - dlsch->harq_processes[0]->rb_alloc_odd[1] = 0x3ffff; - break; - - case 100: - dlsch->harq_processes[0]->rb_alloc_even[0] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_odd[0] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_even[1] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_odd[1] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_even[2] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_odd[2] = 0xffffffff; - dlsch->harq_processes[0]->rb_alloc_even[3] = 0xf; - dlsch->harq_processes[0]->rb_alloc_odd[3] = 0xf; - break; - } -} void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a) { @@ -287,759 +90,36 @@ void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a) int subframe = proc->subframe_tx; int frame = proc->frame_tx; - if (eNB->abstraction_flag != 0) { - if (eNB_transport_info_TB_index[eNB->Mod_id][eNB->CC_id]!=0) - printf("[PHY][EMU] PMCH transport block position is different than zero %d \n", eNB_transport_info_TB_index[eNB->Mod_id][eNB->CC_id]); - - memcpy(eNB->dlsch_MCH->harq_processes[0]->b, - a, - eNB->dlsch_MCH->harq_processes[0]->TBS>>3); - LOG_D(PHY, "[eNB %d] dlsch_encoding_emul pmch , tbs is %d \n", - eNB->Mod_id, - eNB->dlsch_MCH->harq_processes[0]->TBS>>3); - - memcpy(&eNB_transport_info[eNB->Mod_id][eNB->CC_id].transport_blocks[eNB_transport_info_TB_index[eNB->Mod_id][eNB->CC_id]], - a, - eNB->dlsch_MCH->harq_processes[0]->TBS>>3); - eNB_transport_info_TB_index[eNB->Mod_id][eNB->CC_id]+= eNB->dlsch_MCH->harq_processes[0]->TBS>>3;//=eNB_transport_info[eNB->Mod_id].tbs[0]; - } else { - G = get_G(&eNB->frame_parms, - eNB->frame_parms.N_RB_DL, - eNB->dlsch_MCH->harq_processes[0]->rb_alloc, - get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs),1, - 2,proc->frame_tx,subframe,0); - - generate_mbsfn_pilot(eNB,proc, - eNB->common_vars.txdataF, - AMP); - - - AssertFatal(dlsch_encoding(eNB, - a, - 1, - eNB->dlsch_MCH, - proc->frame_tx, - subframe, - &eNB->dlsch_rate_matching_stats, - &eNB->dlsch_turbo_encoding_stats, - &eNB->dlsch_interleaving_stats)==0, - "problem in dlsch_encoding"); - - dlsch_scrambling(&eNB->frame_parms,1,eNB->dlsch_MCH,0,G,0,frame,subframe<<1); - - - mch_modulation(eNB->common_vars.txdataF, - AMP, - subframe, - &eNB->frame_parms, - eNB->dlsch_MCH); - } - -} - -void mch_extract_rbs(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned char symbol, - unsigned char subframe, - LTE_DL_FRAME_PARMS *frame_parms) -{ - - int pilots=0,i,j,offset,aarx; - - // printf("Extracting PMCH: symbol %d\n",symbol); - if ((symbol==2)|| - (symbol==10)) { - pilots = 1; - offset = 1; - } else if (symbol==6) { - pilots = 1; - offset = 0; - } - - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - if (pilots==1) { - for (i=offset,j=0; i<frame_parms->N_RB_DL*6; i+=2,j++) { - /* printf("MCH with pilots: i %d, j %d => %d,%d\n",i,j, - *(int16_t*)&rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)], - *(int16_t*)(1+&rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)])); - */ - rxdataF_ext[aarx][j+symbol*(frame_parms->N_RB_DL*12)] = rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)]; - rxdataF_ext[aarx][(frame_parms->N_RB_DL*3)+j+symbol*(frame_parms->N_RB_DL*12)] = rxdataF[aarx][i+1+ (symbol*frame_parms->ofdm_symbol_size)]; - dl_ch_estimates_ext[aarx][j+symbol*(frame_parms->N_RB_DL*12)] = dl_ch_estimates[aarx][i+(symbol*frame_parms->ofdm_symbol_size)]; - dl_ch_estimates_ext[aarx][(frame_parms->N_RB_DL*3)+j+symbol*(frame_parms->N_RB_DL*12)] = dl_ch_estimates[aarx][i+(frame_parms->N_RB_DL*6)+(symbol*frame_parms->ofdm_symbol_size)]; - } - } else { - - memcpy((void*)&rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)], - (void*)&rxdataF[aarx][frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)], - frame_parms->N_RB_DL*24); - memcpy((void*)&rxdataF_ext[aarx][(frame_parms->N_RB_DL*6) + symbol*(frame_parms->N_RB_DL*12)], - (void*)&rxdataF[aarx][1 + (symbol*frame_parms->ofdm_symbol_size)], - frame_parms->N_RB_DL*24); - memcpy((void*)&dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)], - (void*)&dl_ch_estimates[aarx][(symbol*frame_parms->ofdm_symbol_size)], - frame_parms->N_RB_DL*48); - - } - - } - - - -} - -void mch_channel_level(int **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - int *avg, - uint8_t symbol, - unsigned short nb_rb) -{ - - int i,aarx,nre; -#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch128,avg128; -#elif defined(__arm__) - int32x4_t avg128; -#endif - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { -#if defined(__x86_64__) || defined(__i386__) - //clear average level - avg128 = _mm_setzero_si128(); - // 5 is always a symbol with no pilots for both normal and extended prefix - - dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; -#elif defined(__arm__) - - -#endif - if ((symbol == 2) || (symbol == 6) || (symbol == 10)) - nre = (frame_parms->N_RB_DL*6); - else - nre = (frame_parms->N_RB_DL*12); - - for (i=0; i<(nre>>2); i++) { -#if defined(__x86_64__) || defined(__i386__) - avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); -#elif defined(__arm__) - -#endif - } - - avg[aarx] = (((int*)&avg128)[0] + - ((int*)&avg128)[1] + - ((int*)&avg128)[2] + - ((int*)&avg128)[3])/nre; - - // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); - } - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - -void mch_channel_compensation(int **rxdataF_ext, - int **dl_ch_estimates_ext, - int **dl_ch_mag, - int **dl_ch_magb, - int **rxdataF_comp, - LTE_DL_FRAME_PARMS *frame_parms, - unsigned char symbol, - unsigned char mod_order, - unsigned char output_shift) -{ - - int aarx,nre,i; -#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; -#elif defined(__arm__) - -#endif - if ((symbol == 2) || (symbol == 6) || (symbol == 10)) - nre = frame_parms->N_RB_DL*6; - else - nre = frame_parms->N_RB_DL*12; - -#if defined(__x86_64__) || defined(__i386__) - if (mod_order == 4) { - QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) - QAM_amp128b = _mm_setzero_si128(); - } else if (mod_order == 6) { - QAM_amp128 = _mm_set1_epi16(QAM64_n1); // - QAM_amp128b = _mm_set1_epi16(QAM64_n2); - } -#elif defined(__arm__) - -#endif - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - -#if defined(__x86_64__) || defined(__i386__) - - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128 = (__m128i *)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128b = (__m128i *)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12]; -#elif defined(__arm__) - -#endif - - for (i=0; i<(nre>>2); i+=2) { - if (mod_order>2) { - // get channel amplitude if not QPSK -#if defined(__x86_64__) || defined(__i386__) - - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - - mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - - // store channel magnitude here in a new field of dlsch - - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[0] = dl_ch_mag128[0]; - dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); - dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - - dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[1] = dl_ch_mag128[1]; - dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); - dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - - - dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - - - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); - dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - -#elif defined(__arm__) - -#endif - } - -#if defined(__x86_64__) || defined(__i386__) - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); - - dl_ch128+=2; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - -#elif defined(__arm__) - -#endif - } - } - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif - -} - -void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - int **dl_ch_mag, - int **dl_ch_magb, - unsigned char symbol) -{ - - - int i; -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; -#elif defined(__arm__) - int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; -#endif - if (frame_parms->nb_antennas_rx>1) { - -#if defined(__x86_64__) || defined(__i386__) - - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12]; - -#elif defined(__arm__) - rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0 = (int16x8_t *)&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1 = (int16x8_t *)&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0b = (int16x8_t *)&dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1b = (int16x8_t *)&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12]; - -#endif - // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0; i<frame_parms->N_RB_DL*3; i++) { -#if defined(__x86_64__) || defined(__i386__) - rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); - dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); - dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); -#elif defined(__arm__) - rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); - dl_ch_mag128_0[i] = vhaddq_s16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]); - dl_ch_mag128_0b[i] = vhaddq_s16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]); -#endif - } - } -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - -int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - short *dlsch_llr, - unsigned char symbol, - short **llr32p) -{ - - uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - uint32_t *llr32; - int i,len; - - if (symbol==2) { - llr32 = (uint32_t*)dlsch_llr; - } else { - llr32 = (uint32_t*)(*llr32p); - } - - AssertFatal(llr32!=NULL,"dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32); - - - if ((symbol==2) || (symbol==6) || (symbol==10)) { - len = frame_parms->N_RB_DL*6; - } else { - len = frame_parms->N_RB_DL*12; - } - - // printf("dlsch_qpsk_llr: symbol %d,len %d,pbch_pss_sss_adjust %d\n",symbol,len,pbch_pss_sss_adjust); - for (i=0; i<len; i++) { - *llr32 = *rxF; - rxF++; - llr32++; - } - - *llr32p = (short *)llr32; - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif - - return(0); -} - -//---------------------------------------------------------------------------------------------- -// 16-QAM -//---------------------------------------------------------------------------------------------- - -void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - short *dlsch_llr, - int **dl_ch_mag, - unsigned char symbol, - int16_t **llr32p) -{ - -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - __m128i *ch_mag; - __m128i llr128[2],xmm0; - uint32_t *llr32; -#elif defined(__arm__) - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16x8_t *ch_mag; - int16x8_t llr128[2],xmm0; - int16_t *llr16; -#endif - int i,len; - unsigned char len_mod4=0; - -#if defined(__x86_64__) || defined(__i386__) - if (symbol==2) { - llr32 = (uint32_t*)dlsch_llr; - } else { - llr32 = (uint32_t*)*llr32p; - } -#elif defined(__arm__) - if (symbol==2) { - llr16 = (int16_t*)dlsch_llr; - } else { - llr16 = (int16_t*)*llr32p; - } -#endif -#if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; -#elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; -#endif - if ((symbol==2) || (symbol==6) || (symbol==10)) { - len = frame_parms->N_RB_DL*6; - } else { - len = frame_parms->N_RB_DL*12; - } - - - - // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE) - if (symbol==2) - *llr32p = dlsch_llr + (len<<2); - else - *llr32p += (len<<2); - - len_mod4 = len&3; - len>>=2; // length in quad words (4 REs) - len+=(len_mod4==0 ? 0 : 1); - - for (i=0; i<len; i++) { - -#if defined(__x86_64__) || defined(__i386__) - xmm0 = _mm_abs_epi16(rxF[i]); - xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); - - // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2 - llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); - llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); - llr32[0] = ((uint32_t *)&llr128[0])[0]; - llr32[1] = ((uint32_t *)&llr128[0])[1]; - llr32[2] = ((uint32_t *)&llr128[0])[2]; - llr32[3] = ((uint32_t *)&llr128[0])[3]; - llr32[4] = ((uint32_t *)&llr128[1])[0]; - llr32[5] = ((uint32_t *)&llr128[1])[1]; - llr32[6] = ((uint32_t *)&llr128[1])[2]; - llr32[7] = ((uint32_t *)&llr128[1])[3]; - llr32+=8; - -#elif defined(__arm__) - xmm0 = vabsq_s16(rxF[i]); - xmm0 = vsubq_s16(ch_mag[i],xmm0); - - // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2 - - llr16[0] = vgetq_lane_s16(rxF[i],0); - llr16[1] = vgetq_lane_s16(xmm0,0); - llr16[2] = vgetq_lane_s16(rxF[i],1); - llr16[3] = vgetq_lane_s16(xmm0,1); - llr16[4] = vgetq_lane_s16(rxF[i],2); - llr16[5] = vgetq_lane_s16(xmm0,2); - llr16[6] = vgetq_lane_s16(rxF[i],2); - llr16[7] = vgetq_lane_s16(xmm0,3); - llr16[8] = vgetq_lane_s16(rxF[i],4); - llr16[9] = vgetq_lane_s16(xmm0,4); - llr16[10] = vgetq_lane_s16(rxF[i],5); - llr16[11] = vgetq_lane_s16(xmm0,5); - llr16[12] = vgetq_lane_s16(rxF[i],6); - llr16[13] = vgetq_lane_s16(xmm0,6); - llr16[14] = vgetq_lane_s16(rxF[i],7); - llr16[15] = vgetq_lane_s16(xmm0,7); - llr16+=16; -#endif - - } - -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - -//---------------------------------------------------------------------------------------------- -// 64-QAM -//---------------------------------------------------------------------------------------------- - -void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - short *dlsch_llr, - int **dl_ch_mag, - int **dl_ch_magb, - unsigned char symbol, - short **llr_save) -{ - -#if defined(__x86_64__) || defined(__i386__) - __m128i xmm1,xmm2,*ch_mag,*ch_magb; - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; -#elif defined(__arm__) - int16x8_t xmm1,xmm2,*ch_mag,*ch_magb; - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; -#endif - - int i,len,len2; - // int j=0; - unsigned char len_mod4; - short *llr; - int16_t *llr2; - - if (symbol==2) - llr = dlsch_llr; - else - llr = *llr_save; - -#if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; -#elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; -#endif - if ((symbol==2) || (symbol==6) || (symbol==10)) { - len = frame_parms->N_RB_DL*6; - } else { - len = frame_parms->N_RB_DL*12; - } - - - llr2 = llr; - llr += (len*6); - - len_mod4 =len&3; - len2=len>>2; // length in quad words (4 REs) - len2+=(len_mod4?0:1); - - - for (i=0; i<len2; i++) { -#if defined(__x86_64__) || defined(__i386__) - xmm1 = _mm_abs_epi16(rxF[i]); - xmm1 = _mm_subs_epi16(ch_mag[i],xmm1); - xmm2 = _mm_abs_epi16(xmm1); - xmm2 = _mm_subs_epi16(ch_magb[i],xmm2); -#elif defined(__arm__) - xmm1 = vabsq_s16(rxF[i]); - xmm1 = vsubq_s16(ch_mag[i],xmm1); - xmm2 = vabsq_s16(xmm1); - xmm2 = vsubq_s16(ch_magb[i],xmm2); -#endif - - /* - printf("pmch i: %d => mag (%d,%d) (%d,%d)\n",i,((short *)&ch_mag[i])[0],((short *)&ch_magb[i])[0], - ((short *)&rxF[i])[0],((short *)&rxF[i])[1]); - */ - // loop over all LLRs in quad word (24 coded bits) - /* - for (j=0;j<8;j+=2) { - llr2[0] = ((short *)&rxF[i])[j]; - llr2[1] = ((short *)&rxF[i])[j+1]; - llr2[2] = _mm_extract_epi16(xmm1,j); - llr2[3] = _mm_extract_epi16(xmm1,j+1);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,j);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,j+1);//((short *)&xmm2)[j+1]; - - llr2+=6; - } - */ - llr2[0] = ((short *)&rxF[i])[0]; - llr2[1] = ((short *)&rxF[i])[1]; -#if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,0); - llr2[3] = _mm_extract_epi16(xmm1,1);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,0);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,1);//((short *)&xmm2)[j+1]; -#elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,0); - llr2[3] = vgetq_lane_s16(xmm1,1);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,0);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,1);//((short *)&xmm2)[j+1]; -#endif - - llr2+=6; - llr2[0] = ((short *)&rxF[i])[2]; - llr2[1] = ((short *)&rxF[i])[3]; -#if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,2); - llr2[3] = _mm_extract_epi16(xmm1,3);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,2);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,3);//((short *)&xmm2)[j+1]; -#elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,2); - llr2[3] = vgetq_lane_s16(xmm1,3);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,2);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,3);//((short *)&xmm2)[j+1]; -#endif - llr2+=6; - llr2[0] = ((short *)&rxF[i])[4]; - llr2[1] = ((short *)&rxF[i])[5]; -#if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,4); - llr2[3] = _mm_extract_epi16(xmm1,5);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,4);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,5);//((short *)&xmm2)[j+1]; -#elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,4); - llr2[3] = vgetq_lane_s16(xmm1,5);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,4);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,5);//((short *)&xmm2)[j+1]; -#endif - llr2+=6; - llr2[0] = ((short *)&rxF[i])[6]; - llr2[1] = ((short *)&rxF[i])[7]; -#if defined(__x86_64__) || defined(__i386__) - llr2[2] = _mm_extract_epi16(xmm1,6); - llr2[3] = _mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1]; - llr2[4] = _mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j]; - llr2[5] = _mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1]; -#elif defined(__arm__) - llr2[2] = vgetq_lane_s16(xmm1,6); - llr2[3] = vgetq_lane_s16(xmm1,7);//((short *)&xmm1)[j+1]; - llr2[4] = vgetq_lane_s16(xmm2,6);//((short *)&xmm2)[j]; - llr2[5] = vgetq_lane_s16(xmm2,7);//((short *)&xmm2)[j+1]; -#endif - llr2+=6; - } - - *llr_save = llr; -#if defined(__x86_64__) || defined(__i386__) - _mm_empty(); - _m_empty(); -#endif -} - -int avg_pmch[4]; -int rx_pmch(PHY_VARS_UE *ue, - unsigned char eNB_id, - uint8_t subframe, - unsigned char symbol) -{ - - LTE_UE_COMMON *common_vars = &ue->common_vars; - LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[eNB_id]; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id]; - int avgs,aarx; - - //printf("*********************mch: symbol %d\n",symbol); - - mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, - common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], - pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - symbol, - subframe, - frame_parms); - - if (symbol == 2) { - mch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - avg_pmch, - symbol, - frame_parms->N_RB_DL); - } - - avgs = 0; - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) - avgs = cmax(avgs,avg_pmch[aarx]); - - if (get_Qm(dlsch[0]->harq_processes[0]->mcs)==2) - pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) ;// + 2 - else - pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2); // + 5;// + 2 - - mch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - pdsch_vars[eNB_id]->rxdataF_comp0, - frame_parms, - symbol, - get_Qm(dlsch[0]->harq_processes[0]->mcs), - pdsch_vars[eNB_id]->log2_maxh); - - - if (frame_parms->nb_antennas_rx > 1) - mch_detection_mrc(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol); - - switch (get_Qm(dlsch[0]->harq_processes[0]->mcs)) { - case 2 : - mch_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[0], - symbol, - pdsch_vars[eNB_id]->llr128); - break; - - case 4: - mch_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[0], - pdsch_vars[eNB_id]->dl_ch_mag0, - symbol, - pdsch_vars[eNB_id]->llr128); - break; - - case 6: - mch_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[0], - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol, - pdsch_vars[eNB_id]->llr128); - break; - } + G = get_G(&eNB->frame_parms, + eNB->frame_parms.N_RB_DL, + eNB->dlsch_MCH->harq_processes[0]->rb_alloc, + get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs),1, + 2,proc->frame_tx,subframe,0); + + generate_mbsfn_pilot(eNB,proc, + eNB->common_vars.txdataF, + AMP); + + + AssertFatal(dlsch_encoding(eNB, + a, + 1, + eNB->dlsch_MCH, + proc->frame_tx, + subframe, + &eNB->dlsch_rate_matching_stats, + &eNB->dlsch_turbo_encoding_stats, + &eNB->dlsch_interleaving_stats)==0, + "problem in dlsch_encoding"); + + dlsch_scrambling(&eNB->frame_parms,1,eNB->dlsch_MCH,0,G,0,frame,subframe<<1); + + + mch_modulation(eNB->common_vars.txdataF, + AMP, + subframe, + &eNB->frame_parms, + eNB->dlsch_MCH); - return(0); } diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c new file mode 100644 index 0000000000000000000000000000000000000000..1d12c79621ea403c93c1eaa6389da0fa5065aa8c --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c @@ -0,0 +1,119 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" + +int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) +{ + + uint32_t period; + uint8_t i; + + // LOG_D(PHY,"is_pmch_subframe: frame %d, subframe %d, num_MBSFN_config %d\n", + // frame,subframe,frame_parms->num_MBSFN_config); + + for (i=0; i<frame_parms->num_MBSFN_config; i++) { // we have at least one MBSFN configuration + period = 1<<frame_parms->MBSFN_config[i].radioframeAllocationPeriod; + + if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) { + if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) { + if (frame_parms->frame_type == FDD) { + switch (subframe) { + + case 1: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF1) > 0) + return(1); + + break; + + case 2: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF2) > 0) + return(1); + + break; + + case 3: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF3) > 0) + return(1); + + break; + + case 6: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF6) > 0) + return(1); + + break; + + case 7: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF7) > 0) + return(1); + + break; + + case 8: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_FDD_SF8) > 0) + return(1); + + break; + } + } else { + switch (subframe) { + case 3: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF3) > 0) + return(1); + + break; + + case 4: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF4) > 0) + return(1); + + break; + + case 7: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF7) > 0) + return(1); + + break; + + case 8: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF8) > 0) + return(1); + + break; + + case 9: + if ((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig & MBSFN_TDD_SF9) > 0) + return(1); + + break; + } + } + + } else { // handle 4 frames case + + } + } + } + + return(0); +} diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 10f0c1490c81d2e97fa08887a1c0f75ec4ee2825..32273015ce9417bd80cb8f408ffb662f043afcbc 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -19,7 +19,8 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" #include "PHY/impl_defs_lte.h" //#define DEBUG_PC 0 @@ -33,20 +34,20 @@ double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db 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) +double get_pa_dB(uint8_t pa) { - if (pdsch_config_dedicated) - return(pa_values[ pdsch_config_dedicated->p_a]); - else - return(0.0); + AssertFatal(pa<8,"pa %d is not in (0...7)\n",pa); + + return(pa_values[pa]); + } -double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, +double computeRhoA_eNB(uint8_t pa, 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); + rho_a_dB = get_pa_dB(pa); if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5 rho_a_dB-=10*log10(2); @@ -59,14 +60,14 @@ double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, 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); + printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",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, +double computeRhoB_eNB(uint8_t pa, + uint8_t pb, uint8_t n_antenna_port, LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off) @@ -75,24 +76,25 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, 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); + AssertFatal(pa<8,"pa %d is not in (0...7)\n",pa); + AssertFatal(pb<4,"pb %d is not in (0...3)\n",pb); + rho_a_dB= computeRhoA_eNB(pa,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; + rho_b_dB= ratioPB[1][pb] + rho_a_dB; else - rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB; + rho_b_dB= ratioPB[0][pb] + 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); + printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pb,ratioPB[1][pb],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, @@ -102,7 +104,7 @@ double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB; double sqrt_rho_a_lin; - rho_a_dB = get_pa_dB(pdsch_config_dedicated); + rho_a_dB = get_pa_dB(pdsch_config_dedicated->p_a); if(!dl_power_off) rho_a_dB-=10*log10(2); @@ -148,3 +150,4 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, #endif return(rho_b_dB); } + diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index a332670a5992dd05cafd76779e90d5f6c942cfa1..90dca2337ed460ead6202e76bdaca8f89e3f7a8c 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -30,1065 +30,23 @@ * \warning */ #include "PHY/sse_intrin.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" //#include "prach.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "SCHED/sched_eNB.h" #include "UTIL/LOG/vcd_signal_dumper.h" +#include "prach_extern.h" //#define PRACH_DEBUG 1 //#define PRACH_WRITE_OUTPUT_DEBUG 1 -uint16_t NCS_unrestricted[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419}; -uint16_t NCS_restricted[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case -uint16_t NCS_4[7] = {2,4,6,8,10,12,15}; - -int16_t ru[2*839]; // quantized roots of unity -uint32_t ZC_inv[839]; // multiplicative inverse for roots u -uint16_t du[838]; - -typedef struct { - uint8_t f_ra; - uint8_t t0_ra; - uint8_t t1_ra; - uint8_t t2_ra; -} PRACH_TDD_PREAMBLE_MAP_elem; -typedef struct { - uint8_t num_prach; - PRACH_TDD_PREAMBLE_MAP_elem map[6]; -} PRACH_TDD_PREAMBLE_MAP; - -// This is table 5.7.1-4 from 36.211 -PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = { - // TDD Configuration Index 0 - { {1,{{0,1,0,2}}},{1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}}, - // TDD Configuration Index 1 - { {1,{{0,2,0,2}}},{1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}}, - // TDD Configuration Index 2 - { {1,{{0,1,1,2}}},{1,{{0,1,1,1}}}, {1,{{0,1,1,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,1}}}}, - // TDD Configuration Index 3 - { {1,{{0,0,0,2}}},{1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}}, - // TDD Configuration Index 4 - { {1,{{0,0,1,2}}},{1,{{0,0,1,1}}}, {1,{{0,0,1,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,1}}}}, - // TDD Configuration Index 5 - { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, - // TDD Configuration Index 6 - { {2,{{0,0,0,2},{0,0,1,2}}}, {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {2,{{0,0,0,1},{0,0,0,2}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {2,{{0,0,0,2},{0,0,1,1}}}}, - // TDD Configuration Index 7 - { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,2}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, - // TDD Configuration Index 8 - { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,1,1}}}}, - // TDD Configuration Index 9 - { {3,{{0,0,0,1},{0,0,0,2},{0,0,1,2}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,0,2}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {3,{{0,0,0,1},{0,0,0,2},{0,0,1,1}}}}, - // TDD Configuration Index 10 - { {3,{{0,0,0,0},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,2},{0,0,1,0}}}}, - // TDD Configuration Index 11 - { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}}, - // TDD Configuration Index 12 - { {4,{{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, - {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, - {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,2}}}, - {4,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1}}}, - {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, - {4,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} - }, - // TDD Configuration Index 13 - { {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1}}} - }, - // TDD Configuration Index 14 - { {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} - }, - // TDD Configuration Index 15 - { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1}}}, - {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1},{1,0,0,2}}}, - {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,1}}}, {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, - {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} - }, - // TDD Configuration Index 16 - { {5,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,1,1}}}, - {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,1,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,2}}}, - {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}} - }, - // TDD Configuration Index 17 - { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}} - }, - // TDD Configuration Index 18 - { {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}}, - {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, - {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, - {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1},{1,0,0,2}}}, - {6,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0},{2,0,0,1}}}, - {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, - {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,0,2}}} - }, - // TDD Configuration Index 19 - { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0},{1,0,1,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,1,1}}} - }, - // TDD Configuration Index 20 - { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}}, - // TDD Configuration Index 21 - { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}}, - - // TDD Configuration Index 22 - { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}}, - - // TDD Configuration Index 23 - { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, - - // TDD Configuration Index 24 - { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}}, - - // TDD Configuration Index 25 - { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, - - // TDD Configuration Index 26 - { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}}, - - // TDD Configuration Index 27 - { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}}, - {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}} - }, - - // TDD Configuration Index 28 - { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}}, - {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}} - }, - - // TDD Configuration Index 29 - { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}}, - {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}}, - {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}} - }, - - - // TDD Configuration Index 30 - { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}}, - - // TDD Configuration Index 31 - { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}}, - - // TDD Configuration Index 32 - { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}}, - - // TDD Configuration Index 33 - { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, - - // TDD Configuration Index 34 - { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}}, - - // TDD Configuration Index 35 - { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, - - // TDD Configuration Index 36 - { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}}, - - // TDD Configuration Index 37 - { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}}, - {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}} - }, - - // TDD Configuration Index 38 - { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}}, - {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}} - }, - - // TDD Configuration Index 39 - { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}}, - {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}}, - {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}} - }, - - // TDD Configuration Index 40 - { {1,{{0,1,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}}, - // TDD Configuration Index 41 - { {1,{{0,2,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}}, - - // TDD Configuration Index 42 - { {1,{{0,1,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}}, - - // TDD Configuration Index 43 - { {1,{{0,0,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}}, - - // TDD Configuration Index 44 - { {1,{{0,0,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}}, - - // TDD Configuration Index 45 - { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}}, - - // TDD Configuration Index 46 - { {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}}, - - // TDD Configuration Index 47 - { {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}} - } -}; - - - -uint16_t prach_root_sequence_map0_3[838] = { 129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84, 755, 105, 734, 93, 746, 70, 769, 60, 779, - 2, 837, 1, 838, - 56, 783, 112, 727, 148, 691, - 80, 759, 42, 797, 40, 799, - 35, 804, 73, 766, 146, 693, - 31, 808, 28, 811, 30, 809, 27, 812, 29, 810, - 24, 815, 48, 791, 68, 771, 74, 765, 178, 661, 136, 703, - 86, 753, 78, 761, 43, 796, 39, 800, 20, 819, 21, 818, - 95, 744, 202, 637, 190, 649, 181, 658, 137, 702, 125, 714, 151, 688, - 217, 622, 128, 711, 142, 697, 122, 717, 203, 636, 118, 721, 110, 729, 89, 750, 103, 736, 61, - 778, 55, 784, 15, 824, 14, 825, - 12, 827, 23, 816, 34, 805, 37, 802, 46, 793, 207, 632, 179, 660, 145, 694, 130, 709, 223, 616, - 228, 611, 227, 612, 132, 707, 133, 706, 143, 696, 135, 704, 161, 678, 201, 638, 173, 666, 106, - 733, 83, 756, 91, 748, 66, 773, 53, 786, 10, 829, 9, 830, - 7, 832, 8, 831, 16, 823, 47, 792, 64, 775, 57, 782, 104, 735, 101, 738, 108, 731, 208, 631, 184, - 655, 197, 642, 191, 648, 121, 718, 141, 698, 149, 690, 216, 623, 218, 621, - 152, 687, 144, 695, 134, 705, 138, 701, 199, 640, 162, 677, 176, 663, 119, 720, 158, 681, 164, - 675, 174, 665, 171, 668, 170, 669, 87, 752, 169, 670, 88, 751, 107, 732, 81, 758, 82, 757, 100, - 739, 98, 741, 71, 768, 59, 780, 65, 774, 50, 789, 49, 790, 26, 813, 17, 822, 13, 826, 6, 833, - 5, 834, 33, 806, 51, 788, 75, 764, 99, 740, 96, 743, 97, 742, 166, 673, 172, 667, 175, 664, 187, - 652, 163, 676, 185, 654, 200, 639, 114, 725, 189, 650, 115, 724, 194, 645, 195, 644, 192, 647, - 182, 657, 157, 682, 156, 683, 211, 628, 154, 685, 123, 716, 139, 700, 212, 627, 153, 686, 213, - 626, 215, 624, 150, 689, - 225, 614, 224, 615, 221, 618, 220, 619, 127, 712, 147, 692, 124, 715, 193, 646, 205, 634, 206, - 633, 116, 723, 160, 679, 186, 653, 167, 672, 79, 760, 85, 754, 77, 762, 92, 747, 58, 781, 62, - 777, 69, 770, 54, 785, 36, 803, 32, 807, 25, 814, 18, 821, 11, 828, 4, 835, - 3, 836, 19, 820, 22, 817, 41, 798, 38, 801, 44, 795, 52, 787, 45, 794, 63, 776, 67, 772, 72, - 767, 76, 763, 94, 745, 102, 737, 90, 749, 109, 730, 165, 674, 111, 728, 209, 630, 204, 635, 117, - 722, 188, 651, 159, 680, 198, 641, 113, 726, 183, 656, 180, 659, 177, 662, 196, 643, 155, 684, - 214, 625, 126, 713, 131, 708, 219, 620, 222, 617, 226, 613, - 230, 609, 232, 607, 262, 577, 252, 587, 418, 421, 416, 423, 413, 426, 411, 428, 376, 463, 395, - 444, 283, 556, 285, 554, 379, 460, 390, 449, 363, 476, 384, 455, 388, 451, 386, 453, 361, 478, - 387, 452, 360, 479, 310, 529, 354, 485, 328, 511, 315, 524, 337, 502, 349, 490, 335, 504, 324, - 515, - 323, 516, 320, 519, 334, 505, 359, 480, 295, 544, 385, 454, 292, 547, 291, 548, 381, 458, 399, - 440, 380, 459, 397, 442, 369, 470, 377, 462, 410, 429, 407, 432, 281, 558, 414, 425, 247, 592, - 277, 562, 271, 568, 272, 567, 264, 575, 259, 580, - 237, 602, 239, 600, 244, 595, 243, 596, 275, 564, 278, 561, 250, 589, 246, 593, 417, 422, 248, - 591, 394, 445, 393, 446, 370, 469, 365, 474, 300, 539, 299, 540, 364, 475, 362, 477, 298, 541, - 312, 527, 313, 526, 314, 525, 353, 486, 352, 487, 343, 496, 327, 512, 350, 489, 326, 513, 319, - 520, 332, 507, 333, 506, 348, 491, 347, 492, 322, 517, - 330, 509, 338, 501, 341, 498, 340, 499, 342, 497, 301, 538, 366, 473, 401, 438, 371, 468, 408, - 431, 375, 464, 249, 590, 269, 570, 238, 601, 234, 605, - 257, 582, 273, 566, 255, 584, 254, 585, 245, 594, 251, 588, 412, 427, 372, 467, 282, 557, 403, - 436, 396, 443, 392, 447, 391, 448, 382, 457, 389, 450, 294, 545, 297, 542, 311, 528, 344, 495, - 345, 494, 318, 521, 331, 508, 325, 514, 321, 518, - 346, 493, 339, 500, 351, 488, 306, 533, 289, 550, 400, 439, 378, 461, 374, 465, 415, 424, 270, - 569, 241, 598, - 231, 608, 260, 579, 268, 571, 276, 563, 409, 430, 398, 441, 290, 549, 304, 535, 308, 531, 358, - 481, 316, 523, - 293, 546, 288, 551, 284, 555, 368, 471, 253, 586, 256, 583, 263, 576, - 242, 597, 274, 565, 402, 437, 383, 456, 357, 482, 329, 510, - 317, 522, 307, 532, 286, 553, 287, 552, 266, 573, 261, 578, - 236, 603, 303, 536, 356, 483, - 355, 484, 405, 434, 404, 435, 406, 433, - 235, 604, 267, 572, 302, 537, - 309, 530, 265, 574, 233, 606, - 367, 472, 296, 543, - 336, 503, 305, 534, 373, 466, 280, 559, 279, 560, 419, 420, 240, 599, 258, 581, 229, 610 - }; - -uint16_t prach_root_sequence_map4[138] = { 1,138,2,137,3,136,4,135,5,134,6,133,7,132,8,131,9,130,10,129, - 11,128,12,127,13,126,14,125,15,124,16,123,17,122,18,121,19,120,20,119, - 21,118,22,117,23,116,24,115,25,114,26,113,27,112,28,111,29,110,30,109, - 31,108,32,107,33,106,34,105,35,104,36,103,37,102,38,101,39,100,40,99, - 41,98,42,97,43,96,44,95,45,94,46,93,47,92,48,91,49,90,50,89, - 51,88,52,87,53,86,54,85,55,84,56,83,57,82,58,81,59,80,60,79, - 61,78,62,77,63,76,64,75,65,74,66,73,67,72,68,71,69,70 - }; - -void dump_prach_config(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) -{ - - FILE *fd; - - fd = fopen("prach_config.txt","w"); - fprintf(fd,"prach_config: subframe = %d\n",subframe); - fprintf(fd,"prach_config: N_RB_UL = %d\n",frame_parms->N_RB_UL); - fprintf(fd,"prach_config: frame_type = %s\n",(frame_parms->frame_type==1) ? "TDD":"FDD"); - - if(frame_parms->frame_type==1) fprintf(fd,"prach_config: tdd_config = %d\n",frame_parms->tdd_config); - - fprintf(fd,"prach_config: rootSequenceIndex = %d\n",frame_parms->prach_config_common.rootSequenceIndex); - fprintf(fd,"prach_config: prach_ConfigIndex = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex); - fprintf(fd,"prach_config: Ncs_config = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig); - fprintf(fd,"prach_config: highSpeedFlag = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.highSpeedFlag); - fprintf(fd,"prach_config: n_ra_prboffset = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset); - fclose(fd); - -} - -// This function computes the du -void fill_du(uint8_t prach_fmt) -{ - - uint16_t iu,u,p; - uint16_t N_ZC; - uint16_t *prach_root_sequence_map; - - if (prach_fmt<4) { - N_ZC = 839; - prach_root_sequence_map = prach_root_sequence_map0_3; - } else { - N_ZC = 139; - prach_root_sequence_map = prach_root_sequence_map4; - } - - for (iu=0; iu<(N_ZC-1); iu++) { - - u=prach_root_sequence_map[iu]; - p=1; - - while (((u*p)%N_ZC)!=1) - p++; - - du[u] = ((p<(N_ZC>>1)) ? p : (N_ZC-p)); - } - -} - -uint8_t get_num_prach_tdd(module_id_t Mod_id) -{ - LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][0]->frame_parms; - return(tdd_preamble_map[fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex][fp->tdd_config].num_prach); -} - -uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index) -{ - LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][0]->frame_parms; - return(tdd_preamble_map[fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex][fp->tdd_config].map[tdd_map_index].f_ra); -} - -uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type) -{ - - if (frame_type == FDD) // FDD - return(prach_ConfigIndex>>4); - - else { - if (prach_ConfigIndex < 20) - return (0); - - if (prach_ConfigIndex < 30) - return (1); - - if (prach_ConfigIndex < 40) - return (2); - - if (prach_ConfigIndex < 48) - return (3); - else - return (4); - } -} - -uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t prach_ConfigIndex, - uint8_t n_ra_prboffset, - uint8_t tdd_mapindex, uint16_t Nf) -{ - lte_frame_type_t frame_type = frame_parms->frame_type; - uint8_t tdd_config = frame_parms->tdd_config; - - uint8_t n_ra_prb; - uint8_t f_ra,t1_ra; - uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type); - uint8_t Nsp=2; - - if (frame_type == TDD) { // TDD - - if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) { - LOG_E(PHY, "Illegal prach_ConfigIndex %"PRIu8"", prach_ConfigIndex); - return(-1); - } - - // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211) - f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra; - - if (prach_fmt < 4) { - if ((f_ra&1) == 0) { - n_ra_prb = n_ra_prboffset + 6*(f_ra>>1); - } else { - n_ra_prb = frame_parms->N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1); - } - } else { - if ((tdd_config >2) && (tdd_config<6)) - Nsp = 2; - - t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; - - if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) { - n_ra_prb = 6*f_ra; - } else { - n_ra_prb = frame_parms->N_RB_UL - 6*(f_ra+1); - } - } - } - else { //FDD - n_ra_prb = n_ra_prboffset; - } - return(n_ra_prb); -} - -int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe) -{ - // uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - uint8_t tdd_config = frame_parms->tdd_config; - uint8_t t0_ra; - uint8_t t1_ra; - uint8_t t2_ra; - - int prach_mask = 0; - - if (frame_parms->frame_type == FDD) { //FDD - //implement Table 5.7.1-2 from 36.211 (Rel-10, p.41) - if ((((frame&1) == 1) && (subframe < 9)) || - (((frame&1) == 0) && (subframe == 9))) // This is an odd frame, ignore even-only PRACH frames - if (((prach_ConfigIndex&0xf)<3) || // 0,1,2,16,17,18,32,33,34,48,49,50 - ((prach_ConfigIndex&0x1f)==18) || // 18,50 - ((prach_ConfigIndex&0xf)==15)) // 15,47 - return(0); - - switch (prach_ConfigIndex&0x1f) { - case 0: - case 3: - if (subframe==1) prach_mask = 1; - break; - - case 1: - case 4: - if (subframe==4) prach_mask = 1; - break; - - case 2: - case 5: - if (subframe==7) prach_mask = 1; - break; - - case 6: - if ((subframe==1) || (subframe==6)) prach_mask=1; - break; - - case 7: - if ((subframe==2) || (subframe==7)) prach_mask=1; - break; - - case 8: - if ((subframe==3) || (subframe==8)) prach_mask=1; - break; - - case 9: - if ((subframe==1) || (subframe==4) || (subframe==7)) prach_mask=1; - break; - - case 10: - if ((subframe==2) || (subframe==5) || (subframe==8)) prach_mask=1; - break; - - case 11: - if ((subframe==3) || (subframe==6) || (subframe==9)) prach_mask=1; - break; - - case 12: - if ((subframe&1)==0) prach_mask=1; - break; - - case 13: - if ((subframe&1)==1) prach_mask=1; - break; - - case 14: - prach_mask=1; - break; - - case 15: - if (subframe==9) prach_mask=1; - break; - } - } else { // TDD - - AssertFatal(prach_ConfigIndex<64, - "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex); - AssertFatal(tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach>0, - "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex); - - t0_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t0_ra; - t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; - t2_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t2_ra; -#ifdef PRACH_DEBUG - LOG_I(PHY,"[PRACH] Checking for PRACH format (ConfigIndex %d) in TDD subframe %d (%d,%d,%d)\n", - prach_ConfigIndex, - subframe, - t0_ra,t1_ra,t2_ra); -#endif - - if ((((t0_ra == 1) && ((frame &1)==0))|| // frame is even and PRACH is in even frames - ((t0_ra == 2) && ((frame &1)==1))|| // frame is odd and PRACH is in odd frames - (t0_ra == 0)) && // PRACH is in all frames - (((subframe<5)&&(t1_ra==0)) || // PRACH is in 1st half-frame - (((subframe>4)&&(t1_ra==1))))) { // PRACH is in 2nd half-frame - if ((prach_ConfigIndex<48) && // PRACH only in normal UL subframe - (((subframe%5)-2)==t2_ra)) prach_mask=1; - else if ((prach_ConfigIndex>47) && (((subframe%5)-1)==t2_ra)) prach_mask=1; // PRACH can be in UpPTS - } - } - - return(prach_mask); -} - -int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) { - - uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - int prach_mask = is_prach_subframe0(frame_parms,prach_ConfigIndex,frame,subframe); - -#ifdef Rel14 - int i; - - for (i=0;i<4;i++) { - if (frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] == 1) - prach_mask|=(is_prach_subframe0(frame_parms,frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],frame,subframe)<<(i+1)); - } -#endif - return(prach_mask); -} - -int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ) -{ - - lte_frame_type_t frame_type = ue->frame_parms.frame_type; - //uint8_t tdd_config = ue->frame_parms.tdd_config; - uint16_t rootSequenceIndex = ue->frame_parms.prach_config_common.rootSequenceIndex; - uint8_t prach_ConfigIndex = ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - uint8_t Ncs_config = ue->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; - uint8_t restricted_set = ue->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag; - //uint8_t n_ra_prboffset = ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; - uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex; - uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index; - int16_t *prachF = ue->prach_vars[eNB_id]->prachF; - static int16_t prach_tmp[45600*2] __attribute__((aligned(32))); - int16_t *prach = prach_tmp; - int16_t *prach2; - int16_t amp = ue->prach_vars[eNB_id]->amp; - int16_t Ncp; - uint8_t n_ra_prb; - uint16_t NCS; - uint16_t *prach_root_sequence_map; - uint16_t preamble_offset,preamble_shift; - uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar; - uint16_t d_start,numshift; - - uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type); - //uint8_t Nsp=2; - //uint8_t f_ra,t1_ra; - uint16_t N_ZC = (prach_fmt<4)?839:139; - uint8_t not_found; - int k; - int16_t *Xu; - uint16_t u; - int32_t Xu_re,Xu_im; - uint16_t offset,offset2; - int prach_start; - int i, prach_len; - uint16_t first_nonzero_root_idx=0; - -#if defined(EXMIMO) || defined(OAI_USRP) - prach_start = (ue->rx_offset+subframe*ue->frame_parms.samples_per_tti-ue->hw_timing_advance-ue->N_TA_offset); -#ifdef PRACH_DEBUG - LOG_I(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 - - if (prach_start<0) - prach_start+=(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - if (prach_start>=(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) - prach_start-=(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); -#else //normal case (simulation) - prach_start = subframe*ue->frame_parms.samples_per_tti-ue->N_TA_offset; - LOG_I(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); - +#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) +#define rx_prach0 rx_prach #endif - - // First compute physical root sequence - if (restricted_set == 0) { - AssertFatal(Ncs_config <= 15, - "[PHY] FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", Ncs_config ); - NCS = NCS_unrestricted[Ncs_config]; - } else { - AssertFatal(Ncs_config <= 14, - "[PHY] FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", Ncs_config ); - NCS = NCS_restricted[Ncs_config]; - } - - n_ra_prb = get_prach_prb_offset(&(ue->frame_parms), - ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset, - tdd_mapindex, Nf); - prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4; - - /* - // this code is not part of get_prach_prb_offset - if (frame_type == TDD) { // TDD - - if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) { - LOG_E( PHY, "[PHY][UE %"PRIu8"] Illegal prach_ConfigIndex %"PRIu8" for ", ue->Mod_id, prach_ConfigIndex ); - } - - // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211) - f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra; - - if (prach_fmt < 4) { - if ((f_ra&1) == 0) { - n_ra_prb = n_ra_prboffset + 6*(f_ra>>1); - } else { - n_ra_prb = ue->frame_parms.N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1); - } - } else { - if ((tdd_config >2) && (tdd_config<6)) - Nsp = 2; - - t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; - - if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) { - n_ra_prb = 6*f_ra; - } else { - n_ra_prb = ue->frame_parms.N_RB_UL - 6*(f_ra+1); - } - } - } - */ - - // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index - preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); - - if (restricted_set == 0) { - // This is the \nu corresponding to the preamble index - preamble_shift = (NCS==0)? 0 : (preamble_index % (N_ZC/NCS)); - preamble_shift *= NCS; - } else { // This is the high-speed case - -#ifdef PRACH_DEBUG - LOG_I(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config); -#endif - - not_found = 1; - preamble_index0 = preamble_index; - // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this - // preamble index and find the corresponding cyclic shift - preamble_offset = 0; // relative rootSequenceIndex; - - while (not_found == 1) { - // current root depending on rootSequenceIndex and preamble_offset - int index = (rootSequenceIndex + preamble_offset) % N_ZC; - - if (prach_fmt<4) { - // prach_root_sequence_map points to prach_root_sequence_map0_3 - DevAssert( index < sizeof(prach_root_sequence_map0_3) / sizeof(prach_root_sequence_map0_3[0]) ); - } else { - // prach_root_sequence_map points to prach_root_sequence_map4 - DevAssert( index < sizeof(prach_root_sequence_map4) / sizeof(prach_root_sequence_map4[0]) ); - } - - u = prach_root_sequence_map[index]; - - uint16_t n_group_ra = 0; - - if ( (du[u]<(N_ZC/3)) && (du[u]>=NCS) ) { - n_shift_ra = du[u]/NCS; - d_start = (du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = N_ZC/d_start; - n_shift_ra_bar = max(0,(N_ZC-(du[u]<<1)-(n_group_ra*d_start))/N_ZC); - } else if ( (du[u]>=(N_ZC/3)) && (du[u]<=((N_ZC - NCS)>>1)) ) { - n_shift_ra = (N_ZC - (du[u]<<1))/NCS; - d_start = N_ZC - (du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = du[u]/d_start; - n_shift_ra_bar = min(n_shift_ra,max(0,(du[u]- (n_group_ra*d_start))/NCS)); - } else { - n_shift_ra = 0; - n_shift_ra_bar = 0; - } - - // This is the number of cyclic shifts for the current root u - numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar; - - if (numshift>0 && preamble_index0==preamble_index) - first_nonzero_root_idx = preamble_offset; - - if (preamble_index0 < numshift) { - not_found = 0; - preamble_shift = (d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS); - - } else { // skip to next rootSequenceIndex and recompute parameters - preamble_offset++; - preamble_index0 -= numshift; - } - } - } - - // now generate PRACH signal -#ifdef PRACH_DEBUG - - if (NCS>0) - LOG_I(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, NCS %d (NCS_config %d, N_ZC/NCS %d) n_ra_prb %d: Preamble_offset %d, Preamble_shift %d\n", - rootSequenceIndex,preamble_index,NCS,Ncs_config,N_ZC/NCS,n_ra_prb, - preamble_offset,preamble_shift); - -#endif - - // nsymb = (frame_parms->Ncp==0) ? 14:12; - // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*subframe*nsymb; - - k = (12*n_ra_prb) - 6*ue->frame_parms.N_RB_UL; - - if (k<0) - k+=ue->frame_parms.ofdm_symbol_size; - - k*=12; - k+=13; - - Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx]; - - /* - k+=(12*ue->frame_parms.first_carrier_offset); - if (k>(12*ue->frame_parms.ofdm_symbol_size)) - k-=(12*ue->frame_parms.ofdm_symbol_size); - */ - k*=2; - - switch (ue->frame_parms.N_RB_UL) { - case 6: - memset((void*)prachF,0,4*1536); - break; - - case 15: - memset((void*)prachF,0,4*3072); - break; - - case 25: - memset((void*)prachF,0,4*6144); - break; - - case 50: - memset((void*)prachF,0,4*12288); - break; - - case 75: - memset((void*)prachF,0,4*18432); - break; - - case 100: - if (ue->frame_parms.threequarter_fs == 0) - memset((void*)prachF,0,4*24576); - else - memset((void*)prachF,0,4*18432); - break; - } - - for (offset=0,offset2=0; offset<N_ZC; offset++,offset2+=preamble_shift) { - - if (offset2 >= N_ZC) - offset2 -= N_ZC; - - Xu_re = (((int32_t)Xu[offset<<1]*amp)>>15); - Xu_im = (((int32_t)Xu[1+(offset<<1)]*amp)>>15); - prachF[k++]= ((Xu_re*ru[offset2<<1]) - (Xu_im*ru[1+(offset2<<1)]))>>15; - prachF[k++]= ((Xu_im*ru[offset2<<1]) + (Xu_re*ru[1+(offset2<<1)]))>>15; - - if (k==(12*2*ue->frame_parms.ofdm_symbol_size)) - k=0; - } - - switch (prach_fmt) { - case 0: - Ncp = 3168; - break; - - case 1: - case 3: - Ncp = 21024; - break; - - case 2: - Ncp = 6240; - break; - - case 4: - Ncp = 448; - break; - - default: - Ncp = 3168; - break; - } - - switch (ue->frame_parms.N_RB_UL) { - case 6: - Ncp>>=4; - prach+=4; // makes prach2 aligned to 128-bit - break; - - case 15: - Ncp>>=3; - break; - - case 25: - Ncp>>=2; - break; - - case 50: - Ncp>>=1; - break; - - case 75: - Ncp=(Ncp*3)>>2; - break; - } - - if (ue->frame_parms.threequarter_fs == 1) - Ncp=(Ncp*3)>>2; - - prach2 = prach+(Ncp<<1); - - // do IDFT - switch (ue->frame_parms.N_RB_UL) { - case 6: - if (prach_fmt == 4) { - idft256(prachF,prach2,1); - memmove( prach, prach+512, Ncp<<2 ); - prach_len = 256+Ncp; - } else { - idft1536(prachF,prach2,1); - memmove( prach, prach+3072, Ncp<<2 ); - prach_len = 1536+Ncp; - - if (prach_fmt>1) { - memmove( prach2+3072, prach2, 6144 ); - prach_len = 2*1536+Ncp; - } - } - - break; - - case 15: - if (prach_fmt == 4) { - idft512(prachF,prach2,1); - //TODO: account for repeated format in dft output - memmove( prach, prach+1024, Ncp<<2 ); - prach_len = 512+Ncp; - } else { - idft3072(prachF,prach2); - memmove( prach, prach+6144, Ncp<<2 ); - prach_len = 3072+Ncp; - - if (prach_fmt>1) { - memmove( prach2+6144, prach2, 12288 ); - prach_len = 2*3072+Ncp; - } - } - - break; - - case 25: - default: - if (prach_fmt == 4) { - idft1024(prachF,prach2,1); - memmove( prach, prach+2048, Ncp<<2 ); - prach_len = 1024+Ncp; - } else { - idft6144(prachF,prach2); - /*for (i=0;i<6144*2;i++) - prach2[i]<<=1;*/ - memmove( prach, prach+12288, Ncp<<2 ); - prach_len = 6144+Ncp; - - if (prach_fmt>1) { - memmove( prach2+12288, prach2, 24576 ); - prach_len = 2*6144+Ncp; - } - } - - break; - - case 50: - if (prach_fmt == 4) { - idft2048(prachF,prach2,1); - memmove( prach, prach+4096, Ncp<<2 ); - prach_len = 2048+Ncp; - } else { - idft12288(prachF,prach2); - memmove( prach, prach+24576, Ncp<<2 ); - prach_len = 12288+Ncp; - - if (prach_fmt>1) { - memmove( prach2+24576, prach2, 49152 ); - prach_len = 2*12288+Ncp; - } - } - - break; - - case 75: - if (prach_fmt == 4) { - idft3072(prachF,prach2); - //TODO: account for repeated format in dft output - memmove( prach, prach+6144, Ncp<<2 ); - prach_len = 3072+Ncp; - } else { - idft18432(prachF,prach2); - memmove( prach, prach+36864, Ncp<<2 ); - prach_len = 18432+Ncp; - - if (prach_fmt>1) { - memmove( prach2+36834, prach2, 73728 ); - prach_len = 2*18432+Ncp; - } - } - - break; - - case 100: - if (ue->frame_parms.threequarter_fs == 0) { - if (prach_fmt == 4) { - idft4096(prachF,prach2,1); - memmove( prach, prach+8192, Ncp<<2 ); - prach_len = 4096+Ncp; - } else { - idft24576(prachF,prach2); - memmove( prach, prach+49152, Ncp<<2 ); - prach_len = 24576+Ncp; - - if (prach_fmt>1) { - memmove( prach2+49152, prach2, 98304 ); - prach_len = 2* 24576+Ncp; - } - } - } - else { - if (prach_fmt == 4) { - idft3072(prachF,prach2); - //TODO: account for repeated format in dft output - memmove( prach, prach+6144, Ncp<<2 ); - prach_len = 3072+Ncp; - } else { - idft18432(prachF,prach2); - memmove( prach, prach+36864, Ncp<<2 ); - prach_len = 18432+Ncp; - printf("Generated prach for 100 PRB, 3/4 sampling\n"); - if (prach_fmt>1) { - memmove( prach2+36834, prach2, 73728 ); - prach_len = 2*18432+Ncp; - } - } - } - - break; - } - - //LOG_I(PHY,"prach_len=%d\n",prach_len); - - AssertFatal(prach_fmt<4, - "prach_fmt4 not fully implemented" ); -#if defined(EXMIMO) || defined(OAI_USRP) - int j; - int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*ue->frame_parms.samples_per_tti; - LOG_I( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); - - for (i=prach_start,j=0; i<min(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) { - ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]<<4; - ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]<<4; - } - - for (i=0; i<overflow; i++,j++) { - ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]<<4; - ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]<<4; - } -#if defined(EXMIMO) - // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on - for (k=prach_start - (ue->frame_parms.samples_per_tti>>1) ; k<prach_start ; k++) { - if (k<0) - ue->common_vars.txdata[0][k+ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; - else if (k>(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) - ue->common_vars.txdata[0][k-ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; - else - ue->common_vars.txdata[0][k] &= 0xFFFEFFFE; - } -#endif -#else - - for (i=0; i<prach_len; i++) { - ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i] = prach[2*i]; - ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1]; - } - -#endif - - - -#if defined(PRACH_WRITE_OUTPUT_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 ); -} -//__m128i mmtmpX0,mmtmpX1,mmtmpX2,mmtmpX3; - void rx_prach0(PHY_VARS_eNB *eNB, RU_t *ru, uint16_t *max_preamble, @@ -1096,7 +54,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint16_t *max_preamble_delay, uint16_t Nf, uint8_t tdd_mapindex -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,uint8_t br_flag, uint8_t ce_level #endif @@ -1146,7 +104,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32))); int32_t *prach_ifft=(int32_t*)NULL; int32_t **prach_ifftp=(int32_t **)NULL; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int prach_ifft_cnt=0; #endif #ifdef PRACH_DEBUG @@ -1165,7 +123,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, frame_type = fp->frame_type; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { AssertFatal(fp->prach_emtc_config_common.prach_Config_enabled==1, "emtc prach_Config is not enabled\n"); @@ -1200,7 +158,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint16_t N_ZC = (prach_fmt <4)?839:139; if (eNB) { -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level]; #ifdef PRACH_DEBUG @@ -1234,7 +192,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, } } else { -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { #ifdef PRACH_DEBUG frame = ru->proc.frame_prach_br; @@ -1497,7 +455,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, if ((eNB==NULL) && (ru!=NULL) && ru->function == NGFI_RRU_IF4p5) { /// **** send_IF4 of rxsigF to RAU **** /// -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH+1+ce_level); else @@ -1640,7 +598,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, if (new_dft == 1) { new_dft = 0; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { Xu=(int16_t*)eNB->X_u_br[ce_level][preamble_offset-first_nonzero_root_idx]; prach_ifft = prach_ifftp[prach_ifft_cnt++]; @@ -1697,7 +655,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, } // new dft // check energy in nth time shift, for -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if ((br_flag==0) || (eNB->prach_vars_br.repetition_number[ce_level]== eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) @@ -1762,11 +720,8 @@ void rx_prach0(PHY_VARS_eNB *eNB, } +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - -#ifndef Rel14 -#define rx_prach rx_prach0 -#else void rx_prach(PHY_VARS_eNB *eNB, RU_t *ru, uint16_t *max_preamble, @@ -1806,191 +761,5 @@ void rx_prach(PHY_VARS_eNB *eNB, } } } -#endif - -void init_prach_tables(int N_ZC) -{ - - int i,m; - - // Compute the modular multiplicative inverse 'iu' of u s.t. iu*u = 1 mod N_ZC - ZC_inv[0] = 0; - ZC_inv[1] = 1; - - for (i=2; i<N_ZC; i++) { - for (m=2; m<N_ZC; m++) - if (((i*m)%N_ZC) == 1) { - ZC_inv[i] = m; - break; - } - -#ifdef PRACH_DEBUG - - if (i<16) - printf("i %d : inv %d\n",i,ZC_inv[i]); - -#endif - } - - // Compute quantized roots of unity - for (i=0; i<N_ZC; i++) { - ru[i<<1] = (int16_t)(floor(32767.0*cos(2*M_PI*(double)i/N_ZC))); - ru[1+(i<<1)] = (int16_t)(floor(32767.0*sin(2*M_PI*(double)i/N_ZC))); -#ifdef PRACH_DEBUG - - if (i<16) - printf("i %d : runity %d,%d\n",i,ru[i<<1],ru[1+(i<<1)]); - -#endif - } -} - -void compute_prach_seq(uint16_t rootSequenceIndex, - uint8_t prach_ConfigIndex, - uint8_t zeroCorrelationZoneConfig, - uint8_t highSpeedFlag, - lte_frame_type_t frame_type, - uint32_t X_u[64][839]) -{ - - // Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC) - unsigned int k,inv_u,i,NCS=0,num_preambles; - int N_ZC; - uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type); - uint16_t *prach_root_sequence_map; - uint16_t u, preamble_offset; - uint16_t n_shift_ra,n_shift_ra_bar, d_start,numshift; - uint8_t not_found; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_IN); - -#ifdef PRACH_DEBUG - LOG_I(PHY,"compute_prach_seq: NCS_config %d, prach_fmt %d\n",zeroCorrelationZoneConfig, prach_fmt); -#endif - - AssertFatal(prach_fmt<4, - "PRACH sequence is only precomputed for prach_fmt<4 (have %"PRIu8")\n", prach_fmt ); - N_ZC = (prach_fmt < 4) ? 839 : 139; - //init_prach_tables(N_ZC); //moved to phy_init_lte_ue/eNB, since it takes to long in real-time - - if (prach_fmt < 4) { - prach_root_sequence_map = prach_root_sequence_map0_3; - } else { - // FIXME cannot be reached - prach_root_sequence_map = prach_root_sequence_map4; - } - - -#ifdef PRACH_DEBUG - LOG_I( PHY, "compute_prach_seq: done init prach_tables\n" ); -#endif - - if (highSpeedFlag== 0) { - -#ifdef PRACH_DEBUG - LOG_I(PHY,"Low speed prach : NCS_config %d\n",zeroCorrelationZoneConfig); -#endif - - AssertFatal(zeroCorrelationZoneConfig<=15, - "FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", zeroCorrelationZoneConfig ); - NCS = NCS_unrestricted[zeroCorrelationZoneConfig]; - - num_preambles = (NCS==0) ? 64 : ((64*NCS)/N_ZC); - - if (NCS>0) num_preambles++; - - preamble_offset = 0; - } else { - -#ifdef PRACH_DEBUG - LOG_I( PHY, "high speed prach : NCS_config %"PRIu8"\n", zeroCorrelationZoneConfig ); -#endif - - AssertFatal(zeroCorrelationZoneConfig<=14, - "FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", zeroCorrelationZoneConfig ); - NCS = NCS_restricted[zeroCorrelationZoneConfig]; - fill_du(prach_fmt); - - num_preambles = 64; // compute ZC sequence for 64 possible roots - // find first non-zero shift root (stored in preamble_offset) - not_found = 1; - preamble_offset = 0; - - while (not_found == 1) { - // current root depending on rootSequenceIndex - int index = (rootSequenceIndex + preamble_offset) % N_ZC; - - if (prach_fmt<4) { - // prach_root_sequence_map points to prach_root_sequence_map0_3 - DevAssert( index < sizeof(prach_root_sequence_map0_3) / sizeof(prach_root_sequence_map0_3[0]) ); - } else { - // prach_root_sequence_map points to prach_root_sequence_map4 - DevAssert( index < sizeof(prach_root_sequence_map4) / sizeof(prach_root_sequence_map4[0]) ); - } - - u = prach_root_sequence_map[index]; - - uint16_t n_group_ra = 0; - - if ( (du[u]<(N_ZC/3)) && (du[u]>=NCS) ) { - n_shift_ra = du[u]/NCS; - d_start = (du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = N_ZC/d_start; - n_shift_ra_bar = max(0,(N_ZC-(du[u]<<1)-(n_group_ra*d_start))/N_ZC); - } else if ( (du[u]>=(N_ZC/3)) && (du[u]<=((N_ZC - NCS)>>1)) ) { - n_shift_ra = (N_ZC - (du[u]<<1))/NCS; - d_start = N_ZC - (du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = du[u]/d_start; - n_shift_ra_bar = min(n_shift_ra,max(0,(du[u]- (n_group_ra*d_start))/NCS)); - } else { - n_shift_ra = 0; - n_shift_ra_bar = 0; - } - // This is the number of cyclic shifts for the current root u - numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar; - - // skip to next root and recompute parameters if numshift==0 - if (numshift>0) - not_found = 0; - else - preamble_offset++; - } - } - -#ifdef PRACH_DEBUG - - if (NCS>0) - LOG_I( PHY, "Initializing %u preambles for PRACH (NCS_config %"PRIu8", NCS %u, N_ZC/NCS %u)\n", - num_preambles, zeroCorrelationZoneConfig, NCS, N_ZC/NCS ); - -#endif - - for (i=0; i<num_preambles; i++) { - int index = (rootSequenceIndex+i+preamble_offset) % N_ZC; - - if (prach_fmt<4) { - // prach_root_sequence_map points to prach_root_sequence_map0_3 - DevAssert( index < sizeof(prach_root_sequence_map0_3) / sizeof(prach_root_sequence_map0_3[0]) ); - } else { - // prach_root_sequence_map points to prach_root_sequence_map4 - DevAssert( index < sizeof(prach_root_sequence_map4) / sizeof(prach_root_sequence_map4[0]) ); - } - - u = prach_root_sequence_map[index]; - - inv_u = ZC_inv[u]; // multiplicative inverse of u - - - // X_u[0] stores the first ZC sequence where the root u has a non-zero number of shifts - // for the unrestricted case X_u[0] is the first root indicated by the rootSequenceIndex - - for (k=0; k<N_ZC; k++) { - // 420 is the multiplicative inverse of 2 (required since ru is exp[j 2\pi n]) - X_u[i][k] = ((uint32_t*)ru)[(((k*(1+(inv_u*k)))%N_ZC)*420)%N_ZC]; - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_OUT); - -} +#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ diff --git a/openair1/PHY/LTE_TRANSPORT/prach.h b/openair1/PHY/LTE_TRANSPORT/prach.h deleted file mode 100644 index f135af6d811b5187a2fe5d4892bdce7b7ff88b7b..0000000000000000000000000000000000000000 --- a/openair1/PHY/LTE_TRANSPORT/prach.h +++ /dev/null @@ -1,35 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 - */ - -short __attribute__((aligned(16))) X_u839[4][2*839] = {{25792,20209,24697,21533,21208,24977,14453,29407,3673,32560,-10603,31004,-25018,21161,-32697,2145,-25717,-20307,-2330,-32685,24778,-21441,31178,10078,4403,32469,-28990,15273,-22038,-24250,20546,-25526,26673,19030,-20065,25905,-22930,-23408,28086,-16877,6820,32049,-31985,-7121,22218,-24084,6580,32099,-28459,-16242,31873,-7599,-20642,25448,4038,-32518,10834,30923,-21115,-25058,26955,18629,-29699,-13845,30607,11698,-30291,-12497,28519,16134,-24291,-21993,16188,28488,-3308,-32600,-13118,30026,27959,-17087,-32353,-5193,18679,26921,9552,-31344,-31534,8904,22308,24000,14122,-29568,-32314,-5435,490,32763,32605,-3247,-2819,-32646,-32758,-798,-7539,31887,28149,16771,26458,-19330,-4283,-32487,-29271,-14729,-30052,13061,-12213,30405,9669,31307,25331,20784,32111,6520,32182,-6160,29046,-15165,25563,-20499,23450,-22887,23450,-22887,25563,-20499,29046,-15165,32182,-6160,32111,6520,25331,20784,9669,31307,-12213,30405,-30052,13061,-29271,-14729,-4283,-32487,26458,-19330,28149,16771,-7539,31887,-32758,-798,-2819,-32646,32605,-3247,490,32763,-32314,-5435,14122,-29568,22308,24000,-31534,8904,9552,-31344,18679,26921,-32353,-5193,27959,-17087,-13118,30026,-3308,-32600,16188,28488,-24291,-21993,28519,16134,-30291,-12497,30607,11698,-29699,-13845,26955,18629,-21115,-25058,10834,30923,4038,-32518,-20642,25448,31873,-7599,-28459,-16242,6580,32099,22218,-24084,-31985,-7121,6820,32049,28086,-16877,-22930,-23408,-20065,25905,26673,19030,20546,-25526,-22038,-24250,-28990,15273,4403,32469,31178,10078,24778,-21441,-2330,-32685,-25717,-20307,-32697,2145,-25018,21161,-10603,31004,3673,32560,14453,29407,21208,24977,24697,21533,25792,20209,24858,21348,21579,24657,15110,29074,4646,32435,-9435,31379,-24042,22263,-32540,3855,-26887,-18731,-4526,-32454,23104,-23235,31902,7479,7299,31943,-27368,18019,-24455,-21810,17555,-27668,28757,15705,-16614,28243,-25868,-20114,25409,-20690,11526,30672,-32705,-2024,17967,-27402,11984,30496,-30904,-10893,29902,-13399,-15328,28960,-2574,-32666,17034,27991,-26018,-19919,30428,12155,-32088,-6641,32509,4099,-32428,-4708,31663,8431,-29160,-14947,23191,23148,-12099,-30452,-4161,32501,21855,-24414,-32445,4585,25942,20016,-614,-32762,-27095,18426,28874,15490,3551,-32575,-32251,5797,11756,30585,29379,-14509,-14344,-29461,-30780,11238,4889,32400,32409,4828,16929,-28055,-16719,-28181,-32719,-1779,-22129,24166,1471,32733,21946,24331,31786,7956,31756,-8076,26166,-19724,19180,-26567,13454,-29878,10253,-31122,10020,-31198,12779,-30173,18172,-27267,25096,-21068,31140,-10196,32333,5313,24207,22082,5131,32362,-18881,26780,-32641,2879,-20927,-25215,11870,-30542,32741,-1288,11296,30758,-27635,17607,-20737,-25371,24938,-21255,19279,26494,-29435,14398,-5979,-32218,32205,6038,-19871,26054,-11412,-30716,31253,9845,-28640,15920,11181,-30801,8727,31583,-23278,-23062,30694,11469,-32751,-1043,32135,-6401,-31024,10544,30651,-11585,-31326,9610,32461,-4465,-32525,-3978,29103,15056,-19577,-26277,2940,32634,17347,-27799,-31600,8668,27501,17813,-1840,-32716,-27232,18223,28023,16981,6700,-32075,-32747,1165,5857,32239,31929,-7360,-5737,-32261,-32755,920,-7061,31997,27765,17399,27568,-17711,-1105,-32749,-27026,-18529,-31846,7717,-18275,27197,1716,32721,18477,27060,28397,16348,32292,5555,32650,-2758,31815,-7838,31289,-9729,31631,-8550,32493,-4222,32593,3368,29750,13733,21394,24818,6098,32194,-13790,29724,-29953,13286,-30196,-12724,-8373,-31680,22398,-23917,31396,9375,2451,32675,-30863,11008,-16082,-28550,27300,-18122,17451,27732,-29647,13955,-7181,-31971,32617,3123,-15975,28609,-17140,-27928,32711,1900,-22666,23663,-123,-32767,20450,25601,-31064,-10429,32390,-4951,-28275,16560,22576,-23748,-17866,27468,15436,-28904,-15760,28728,18780,-26851,-23875,22443,29487,-14289,-32726,1655,29541,14177,-16508,-28306,-5375,32323,26745,-18931,-31567,-8787,10137,31159,22754,-23579,-30475,-12042,-2697,32655,32553,-3735,-6941,-32024,-32011,7000,3916,32532,32679,2390,11641,-30630,-23959,-22354,-30945,10776,-8016,31771,19674,26202,32477,4342,27700,-17504,13005,-30076,-3063,-32624,-15653,-28787,-23621,-22710,-27831,-17296,-29594,-14067,-29802,-13623,-28580,-16029,-25254,-20879,-18579,-26991,-7420,-31916,7896,-31802,23790,-22533,32629,-3002,25640,20402,1226,32744,-26092,19821,-30100,-12950,-369,-32765,30984,-10661,17243,27862,-25487,20593,-21302,-24899,26312,-19527,14892,29187,-32062,6760,5010,-32382,26815,18830,-30149,12836,8134,-31742,17658,27601,-31501,-9023,30821,-11124,-21021,25135,8609,-31616,2206,32692,-9787,-31272,14011,29620,-15220,-29019,13566,29826,-8846,-31551,736,32758,10486,-31044,-22843,23492,31695,-8313,-30384,-12270,14232,29514,12326,-30361,-31726,8193,23364,22973,10718,-30965,-32765,429,8490,31647,30001,-13175,-14783,-29243,-29853,13510,9199,31449,32731,-1534,9317,-31415,-24617,-21626,-31103,10312,-9904,31234,16824,28117,31466,9140,30563,-11814,19772,-26130,6219,-32172,-5496,-32303,-13678,-29776,-18377,-27130,-20162,-25830,-19379,-26423,-15868,-28669,-9082,-31484,1349,-32740,14563,-29353,27163,-18326,32760,674,24372,21901,981,32752,-25176,20973,-31216,-9963,-5254,-32344,28212,-16667,23705,22621,-18071,27333,-28699,-15814,16294,-28429,26385,19428,-24536,21717,-13231,-29978,32765,-307,-15545,28845,-15002,-29132,31957,7240,-27896,17191,10950,-30884,7777,31830,-21672,-24577,29325,14618,-32272,-5677,32762,-553,-32568,3612,32580,-3491,-32767,184,32159,6279,-28933,-15382,20831,25292,-6461,-32124,-12441,30313,28816,-15599,-31432,-9259,12892,30123,17762,-27536,-32671,-2513,10370,31082,26602,-19131,-24125,-22174,-19478,26349,26530,19230,21487,-24739,-20355,-25679,-30337,12383,245,32766,29215,14837,28336,-16455,4768,-32419,-19968,-25981,-32037,-6881,-30244,12610,-20259,25754,-8254,31710,1961,32708,8963,31517,12666,30219,13342,29927,11065,30841,5616,32282,-3186,32611,-14674,29297,-26240,19625,-32661,2635,-27435,-17917,-7659,-31860,18980,-26710,32766,-62,16401,28366,-19081,26638,-31362,-9494,2084,-32701,32688,-2269,3429,32587,-32737,1410,3794,-32547,30518,11927,-21764,24495,-12554,-30267,32372,5071,-23536,22798,-859,-32756,22487,23832,-32229,-5919,30736,-11355,-23018,23321,13900,-29673,-6340,32147,1594,-32729,0,32767,1594,-32729,-6340,32147,13900,-29673,-23018,23321,30736,-11355,-32229,-5919,22487,23832,-859,-32756,-23536,22798,32372,5071,-12554,-30267,-21764,24495,30518,11927,3794,-32547,-32737,1410,3429,32587,32688,-2269,2084,-32701,-31362,-9494,-19081,26638,16401,28366,32766,-62,18980,-26710,-7659,-31860,-27435,-17917,-32661,2635,-26240,19625,-14674,29297,-3186,32611,5616,32282,11065,30841,13342,29927,12666,30219,8963,31517,1961,32708,-8254,31710,-20259,25754,-30244,12610,-32037,-6881,-19968,-25981,4768,-32419,28336,-16455,29215,14837,245,32766,-30337,12383,-20355,-25679,21487,-24739,26530,19230,-19478,26349,-24125,-22174,26602,-19131,10370,31082,-32671,-2513,17762,-27536,12892,30123,-31432,-9259,28816,-15599,-12441,30313,-6461,-32124,20831,25292,-28933,-15382,32159,6279,-32767,184,32580,-3491,-32568,3612,32762,-553,-32272,-5677,29325,14618,-21672,-24577,7777,31830,10950,-30884,-27896,17191,31957,7240,-15002,-29132,-15545,28845,32765,-307,-13231,-29978,-24536,21717,26385,19428,16294,-28429,-28699,-15814,-18071,27333,23705,22621,28212,-16667,-5254,-32344,-31216,-9963,-25176,20973,981,32752,24372,21901,32760,674,27163,-18326,14563,-29353,1349,-32740,-9082,-31484,-15868,-28669,-19379,-26423,-20162,-25830,-18377,-27130,-13678,-29776,-5496,-32303,6219,-32172,19772,-26130,30563,-11814,31466,9140,16824,28117,-9904,31234,-31103,10312,-24617,-21626,9317,-31415,32731,-1534,9199,31449,-29853,13510,-14783,-29243,30001,-13175,8490,31647,-32765,429,10718,-30965,23364,22973,-31726,8193,12326,-30361,14232,29514,-30384,-12270,31695,-8313,-22843,23492,10486,-31044,736,32758,-8846,-31551,13566,29826,-15220,-29019,14011,29620,-9787,-31272,2206,32692,8609,-31616,-21021,25135,30821,-11124,-31501,-9023,17658,27601,8134,-31742,-30149,12836,26815,18830,5010,-32382,-32062,6760,14892,29187,26312,-19527,-21302,-24899,-25487,20593,17243,27862,30984,-10661,-369,-32765,-30100,-12950,-26092,19821,1226,32744,25640,20402,32629,-3002,23790,-22533,7896,-31802,-7420,-31916,-18579,-26991,-25254,-20879,-28580,-16029,-29802,-13623,-29594,-14067,-27831,-17296,-23621,-22710,-15653,-28787,-3063,-32624,13005,-30076,27700,-17504,32477,4342,19674,26202,-8016,31771,-30945,10776,-23959,-22354,11641,-30630,32679,2390,3916,32532,-32011,7000,-6941,-32024,32553,-3735,-2697,32655,-30475,-12042,22754,-23579,10137,31159,-31567,-8787,26745,-18931,-5375,32323,-16508,-28306,29541,14177,-32726,1655,29487,-14289,-23875,22443,18780,-26851,-15760,28728,15436,-28904,-17866,27468,22576,-23748,-28275,16560,32390,-4951,-31064,-10429,20450,25601,-123,-32767,-22666,23663,32711,1900,-17140,-27928,-15975,28609,32617,3123,-7181,-31971,-29647,13955,17451,27732,27300,-18122,-16082,-28550,-30863,11008,2451,32675,31396,9375,22398,-23917,-8373,-31680,-30196,-12724,-29953,13286,-13790,29724,6098,32194,21394,24818,29750,13733,32593,3368,32493,-4222,31631,-8550,31289,-9729,31815,-7838,32650,-2758,32292,5555,28397,16348,18477,27060,1716,32721,-18275,27197,-31846,7717,-27026,-18529,-1105,-32749,27568,-17711,27765,17399,-7061,31997,-32755,920,-5737,-32261,31929,-7360,5857,32239,-32747,1165,6700,-32075,28023,16981,-27232,18223,-1840,-32716,27501,17813,-31600,8668,17347,-27799,2940,32634,-19577,-26277,29103,15056,-32525,-3978,32461,-4465,-31326,9610,30651,-11585,-31024,10544,32135,-6401,-32751,-1043,30694,11469,-23278,-23062,8727,31583,11181,-30801,-28640,15920,31253,9845,-11412,-30716,-19871,26054,32205,6038,-5979,-32218,-29435,14398,19279,26494,24938,-21255,-20737,-25371,-27635,17607,11296,30758,32741,-1288,11870,-30542,-20927,-25215,-32641,2879,-18881,26780,5131,32362,24207,22082,32333,5313,31140,-10196,25096,-21068,18172,-27267,12779,-30173,10020,-31198,10253,-31122,13454,-29878,19180,-26567,26166,-19724,31756,-8076,31786,7956,21946,24331,1471,32733,-22129,24166,-32719,-1779,-16719,-28181,16929,-28055,32409,4828,4889,32400,-30780,11238,-14344,-29461,29379,-14509,11756,30585,-32251,5797,3551,-32575,28874,15490,-27095,18426,-614,-32762,25942,20016,-32445,4585,21855,-24414,-4161,32501,-12099,-30452,23191,23148,-29160,-14947,31663,8431,-32428,-4708,32509,4099,-32088,-6641,30428,12155,-26018,-19919,17034,27991,-2574,-32666,-15328,28960,29902,-13399,-30904,-10893,11984,30496,17967,-27402,-32705,-2024,11526,30672,25409,-20690,-25868,-20114,-16614,28243,28757,15705,17555,-27668,-24455,-21810,-27368,18019,7299,31943,31902,7479,23104,-23235,-4526,-32454,-26887,-18731,-32540,3855,-24042,22263,-9435,31379,4646,32435,15110,29074,21579,24657,24858,21348}, - {25792,-20210,24858,-21349,21579,-24658,15110,-29075,4646,-32436,-9435,-31380,-24042,-22264,-32540,-3856,-26887,18730,-4526,32453,23104,23234,31902,-7480,7299,-31944,-27368,-18020,-24455,21809,17555,27667,28757,-15706,-16614,-28244,-25868,20113,25409,20689,11526,-30673,-32705,2023,17967,27401,11984,-30497,-30904,10892,29902,13398,-15328,-28961,-2574,32665,17034,-27992,-26018,19918,30428,-12156,-32088,6640,32509,-4100,-32428,4707,31663,-8432,-29160,14946,23191,-23149,-12099,30451,-4161,-32502,21855,24413,-32445,-4586,25942,-20017,-614,32761,-27095,-18427,28874,-15491,3551,32574,-32251,-5798,11756,-30586,29379,14508,-14344,29460,-30780,-11239,4889,-32401,32409,-4829,16929,28054,-16719,28180,-32719,1778,-22129,-24167,1471,-32734,21946,-24332,31786,-7957,31756,8075,26166,19723,19180,26566,13454,29877,10253,31121,10020,31197,12779,30172,18172,27266,25096,21067,31140,10195,32333,-5314,24207,-22083,5131,-32363,-18881,-26781,-32641,-2880,-20927,25214,11870,30541,32741,1287,11296,-30759,-27635,-17608,-20737,25370,24938,21254,19279,-26495,-29435,-14399,-5979,32217,32205,-6039,-19871,-26055,-11412,30715,31253,-9846,-28640,-15921,11181,30800,8727,-31584,-23278,23061,30694,-11470,-32751,1042,32135,6400,-31024,-10545,30651,11584,-31326,-9611,32461,4464,-32525,3977,29103,-15057,-19577,26276,2940,-32635,17347,27798,-31600,-8669,27501,-17814,-1840,32715,-27232,-18224,28023,-16982,6700,32074,-32747,-1166,5857,-32240,31929,7359,-5737,32260,-32755,-921,-7061,-31998,27765,-17400,27568,17710,-1105,32748,-27026,18528,-31846,-7718,-18275,-27198,1716,-32722,18477,-27061,28397,-16349,32292,-5556,32650,2757,31815,7837,31289,9728,31631,8549,32493,4221,32593,-3369,29750,-13734,21394,-24819,6098,-32195,-13790,-29725,-29953,-13287,-30196,12723,-8373,31679,22398,23916,31396,-9376,2451,-32676,-30863,-11009,-16082,28549,27300,18121,17451,-27733,-29647,-13956,-7181,31970,32617,-3124,-15975,-28610,-17140,27927,32711,-1901,-22666,-23664,-123,32766,20450,-25602,-31064,10428,32390,4950,-28275,-16561,22576,23747,-17866,-27469,15436,28903,-15760,-28729,18780,26850,-23875,-22444,29487,14288,-32726,-1656,29541,-14178,-16508,28305,-5375,-32324,26745,18930,-31567,8786,10137,-31160,22754,23578,-30475,12041,-2697,-32656,32553,3734,-6941,32023,-32011,-7001,3916,-32533,32679,-2391,11641,30629,-23959,22353,-30945,-10777,-8016,-31772,19674,-26203,32477,-4343,27700,17503,13005,30075,-3063,32623,-15653,28786,-23621,22709,-27831,17295,-29594,14066,-29802,13622,-28580,16028,-25254,20878,-18579,26990,-7420,31915,7896,31801,23790,22532,32629,3001,25640,-20403,1226,-32745,-26092,-19822,-30100,12949,-369,32764,30984,10660,17243,-27863,-25487,-20594,-21302,24898,26312,19526,14892,-29188,-32062,-6761,5010,32381,26815,-18831,-30149,-12837,8134,31741,17658,-27602,-31501,9022,30821,11123,-21021,-25136,8609,31615,2206,-32693,-9787,31271,14011,-29621,-15220,29018,13566,-29827,-8846,31550,736,-32759,10486,31043,-22843,-23493,31695,8312,-30384,12269,14232,-29515,12326,30360,-31726,-8194,23364,-22974,10718,30964,-32765,-430,8490,-31648,30001,13174,-14783,29242,-29853,-13511,9199,-31450,32731,1533,9317,31414,-24617,21625,-31103,-10313,-9904,-31235,16824,-28118,31466,-9141,30563,11813,19772,26129,6219,32171,-5496,32302,-13678,29775,-18377,27129,-20162,25829,-19379,26422,-15868,28668,-9082,31483,1349,32739,14563,29352,27163,18325,32760,-675,24372,-21902,981,-32753,-25176,-20974,-31216,9962,-5254,32343,28212,16666,23705,-22622,-18071,-27334,-28699,15813,16294,28428,26385,-19429,-24536,-21718,-13231,29977,32765,306,-15545,-28846,-15002,29131,31957,-7241,-27896,-17192,10950,30883,7777,-31831,-21672,24576,29325,-14619,-32272,5676,32762,552,-32568,-3613,32580,3490,-32767,-185,32159,-6280,-28933,15381,20831,-25293,-6461,32123,-12441,-30314,28816,15598,-31432,9258,12892,-30124,17762,27535,-32671,2512,10370,-31083,26602,19130,-24125,22173,-19478,-26350,26530,-19231,21487,24738,-20355,25678,-30337,-12384,245,-32767,29215,-14838,28336,16454,4768,32418,-19968,25980,-32037,6880,-30244,-12611,-20259,-25755,-8254,-31711,1961,-32709,8963,-31518,12666,-30220,13342,-29928,11065,-30842,5616,-32283,-3186,-32612,-14674,-29298,-26240,-19626,-32661,-2636,-27435,17916,-7659,31859,18980,26709,32766,61,16401,-28367,-19081,-26639,-31362,9493,2084,32700,32688,2268,3429,-32588,-32737,-1411,3794,32546,30518,-11928,-21764,-24496,-12554,30266,32372,-5072,-23536,-22799,-859,32755,22487,-23833,-32229,5918,30736,11354,-23018,-23322,13900,29672,-6340,-32148,1594,32728,-1,-32767,1594,32728,-6340,-32148,13900,29672,-23018,-23322,30736,11354,-32229,5918,22487,-23833,-859,32755,-23536,-22799,32372,-5072,-12554,30266,-21764,-24496,30518,-11928,3794,32546,-32737,-1411,3429,-32588,32688,2268,2084,32700,-31362,9493,-19081,-26639,16401,-28367,32766,61,18980,26709,-7659,31859,-27435,17916,-32661,-2636,-26240,-19626,-14674,-29298,-3186,-32612,5616,-32283,11065,-30842,13342,-29928,12666,-30220,8963,-31518,1961,-32709,-8254,-31711,-20259,-25755,-30244,-12611,-32037,6880,-19968,25980,4768,32418,28336,16454,29215,-14838,245,-32767,-30337,-12384,-20355,25678,21487,24738,26530,-19231,-19478,-26350,-24125,22173,26602,19130,10370,-31083,-32671,2512,17762,27535,12892,-30124,-31432,9258,28816,15598,-12441,-30314,-6461,32123,20831,-25293,-28933,15381,32159,-6280,-32767,-185,32580,3490,-32568,-3613,32762,552,-32272,5676,29325,-14619,-21672,24576,7777,-31831,10950,30883,-27896,-17192,31957,-7241,-15002,29131,-15545,-28846,32765,306,-13231,29977,-24536,-21718,26385,-19429,16294,28428,-28699,15813,-18071,-27334,23705,-22622,28212,16666,-5254,32343,-31216,9962,-25176,-20974,981,-32753,24372,-21902,32760,-675,27163,18325,14563,29352,1349,32739,-9082,31483,-15868,28668,-19379,26422,-20162,25829,-18377,27129,-13678,29775,-5496,32302,6219,32171,19772,26129,30563,11813,31466,-9141,16824,-28118,-9904,-31235,-31103,-10313,-24617,21625,9317,31414,32731,1533,9199,-31450,-29853,-13511,-14783,29242,30001,13174,8490,-31648,-32765,-430,10718,30964,23364,-22974,-31726,-8194,12326,30360,14232,-29515,-30384,12269,31695,8312,-22843,-23493,10486,31043,736,-32759,-8846,31550,13566,-29827,-15220,29018,14011,-29621,-9787,31271,2206,-32693,8609,31615,-21021,-25136,30821,11123,-31501,9022,17658,-27602,8134,31741,-30149,-12837,26815,-18831,5010,32381,-32062,-6761,14892,-29188,26312,19526,-21302,24898,-25487,-20594,17243,-27863,30984,10660,-369,32764,-30100,12949,-26092,-19822,1226,-32745,25640,-20403,32629,3001,23790,22532,7896,31801,-7420,31915,-18579,26990,-25254,20878,-28580,16028,-29802,13622,-29594,14066,-27831,17295,-23621,22709,-15653,28786,-3063,32623,13005,30075,27700,17503,32477,-4343,19674,-26203,-8016,-31772,-30945,-10777,-23959,22353,11641,30629,32679,-2391,3916,-32533,-32011,-7001,-6941,32023,32553,3734,-2697,-32656,-30475,12041,22754,23578,10137,-31160,-31567,8786,26745,18930,-5375,-32324,-16508,28305,29541,-14178,-32726,-1656,29487,14288,-23875,-22444,18780,26850,-15760,-28729,15436,28903,-17866,-27469,22576,23747,-28275,-16561,32390,4950,-31064,10428,20450,-25602,-123,32766,-22666,-23664,32711,-1901,-17140,27927,-15975,-28610,32617,-3124,-7181,31970,-29647,-13956,17451,-27733,27300,18121,-16082,28549,-30863,-11009,2451,-32676,31396,-9376,22398,23916,-8373,31679,-30196,12723,-29953,-13287,-13790,-29725,6098,-32195,21394,-24819,29750,-13734,32593,-3369,32493,4221,31631,8549,31289,9728,31815,7837,32650,2757,32292,-5556,28397,-16349,18477,-27061,1716,-32722,-18275,-27198,-31846,-7718,-27026,18528,-1105,32748,27568,17710,27765,-17400,-7061,-31998,-32755,-921,-5737,32260,31929,7359,5857,-32240,-32747,-1166,6700,32074,28023,-16982,-27232,-18224,-1840,32715,27501,-17814,-31600,-8669,17347,27798,2940,-32635,-19577,26276,29103,-15057,-32525,3977,32461,4464,-31326,-9611,30651,11584,-31024,-10545,32135,6400,-32751,1042,30694,-11470,-23278,23061,8727,-31584,11181,30800,-28640,-15921,31253,-9846,-11412,30715,-19871,-26055,32205,-6039,-5979,32217,-29435,-14399,19279,-26495,24938,21254,-20737,25370,-27635,-17608,11296,-30759,32741,1287,11870,30541,-20927,25214,-32641,-2880,-18881,-26781,5131,-32363,24207,-22083,32333,-5314,31140,10195,25096,21067,18172,27266,12779,30172,10020,31197,10253,31121,13454,29877,19180,26566,26166,19723,31756,8075,31786,-7957,21946,-24332,1471,-32734,-22129,-24167,-32719,1778,-16719,28180,16929,28054,32409,-4829,4889,-32401,-30780,-11239,-14344,29460,29379,14508,11756,-30586,-32251,-5798,3551,32574,28874,-15491,-27095,-18427,-614,32761,25942,-20017,-32445,-4586,21855,24413,-4161,-32502,-12099,30451,23191,-23149,-29160,14946,31663,-8432,-32428,4707,32509,-4100,-32088,6640,30428,-12156,-26018,19918,17034,-27992,-2574,32665,-15328,-28961,29902,13398,-30904,10892,11984,-30497,17967,27401,-32705,2023,11526,-30673,25409,20689,-25868,20113,-16614,-28244,28757,-15706,17555,27667,-24455,21809,-27368,-18020,7299,-31944,31902,-7480,23104,23234,-4526,32453,-26887,18730,-32540,-3856,-24042,-22264,-9435,-31380,4646,-32436,15110,-29075,21579,-24658,24858,-21349,25792,-20210,24697,-21534,21208,-24978,14453,-29408,3673,-32561,-10603,-31005,-25018,-21162,-32697,-2146,-25717,20306,-2330,32684,24778,21440,31178,-10079,4403,-32470,-28990,-15274,-22038,24249,20546,25525,26673,-19031,-20065,-25906,-22930,23407,28086,16876,6820,-32050,-31985,7120,22218,24083,6580,-32100,-28459,16241,31873,7598,-20642,-25449,4038,32517,10834,-30924,-21115,25057,26955,-18630,-29699,13844,30607,-11699,-30291,12496,28519,-16135,-24291,21992,16188,-28489,-3308,32599,-13118,-30027,27959,17086,-32353,5192,18679,-26922,9552,31343,-31534,-8905,22308,-24001,14122,29567,-32314,5434,490,-32764,32605,3246,-2819,32645,-32758,797,-7539,-31888,28149,-16772,26458,19329,-4283,32486,-29271,14728,-30052,-13062,-12213,-30406,9669,-31308,25331,-20785,32111,-6521,32182,6159,29046,15164,25563,20498,23450,22886,23450,22886,25563,20498,29046,15164,32182,6159,32111,-6521,25331,-20785,9669,-31308,-12213,-30406,-30052,-13062,-29271,14728,-4283,32486,26458,19329,28149,-16772,-7539,-31888,-32758,797,-2819,32645,32605,3246,490,-32764,-32314,5434,14122,29567,22308,-24001,-31534,-8905,9552,31343,18679,-26922,-32353,5192,27959,17086,-13118,-30027,-3308,32599,16188,-28489,-24291,21992,28519,-16135,-30291,12496,30607,-11699,-29699,13844,26955,-18630,-21115,25057,10834,-30924,4038,32517,-20642,-25449,31873,7598,-28459,16241,6580,-32100,22218,24083,-31985,7120,6820,-32050,28086,16876,-22930,23407,-20065,-25906,26673,-19031,20546,25525,-22038,24249,-28990,-15274,4403,-32470,31178,-10079,24778,21440,-2330,32684,-25717,20306,-32697,-2146,-25018,-21162,-10603,-31005,3673,-32561,14453,-29408,21208,-24978,24697,-21534}, - {-4283,-32487,4889,32400,-6941,-32024,10370,31082,-15002,-29132,20450,25601,-26018,-19919,30607,11698,-32751,-1043,30821,-11124,-23536,22798,10718,-30965,5857,32239,-22038,-24250,31902,7479,-29953,13286,14563,-29353,8963,31517,-28580,-16029,31140,-10196,-12213,30405,-16719,-28181,32679,2390,-19478,26349,-13231,-29978,32711,1900,-15328,28960,-21115,-25058,30651,-11585,2206,32692,-32229,-5919,12326,-30361,28023,16981,-20065,25905,-24455,-21810,22398,-23917,24372,21901,-20259,25754,-27831,-17296,12779,-30173,32111,6520,1471,32733,-30945,10776,-20355,-25679,16294,-28429,32617,3123,11984,30496,-20642,25448,-32525,-3978,-15220,-29019,13900,-29673,31695,-8313,27501,17813,6820,32049,-16614,28243,-30863,11008,-31216,-9963,-19968,-25981,-3063,-32624,13454,-29878,25563,-20499,31756,-8076,32477,4342,29215,14837,23705,22621,17451,27732,11526,30672,6580,32099,2940,32634,736,32758,0,32767,736,32758,2940,32634,6580,32099,11526,30672,17451,27732,23705,22621,29215,14837,32477,4342,31756,-8076,25563,-20499,13454,-29878,-3063,-32624,-19968,-25981,-31216,-9963,-30863,11008,-16614,28243,6820,32049,27501,17813,31695,-8313,13900,-29673,-15220,-29019,-32525,-3978,-20642,25448,11984,30496,32617,3123,16294,-28429,-20355,-25679,-30945,10776,1471,32733,32111,6520,12779,-30173,-27831,-17296,-20259,25754,24372,21901,22398,-23917,-24455,-21810,-20065,25905,28023,16981,12326,-30361,-32229,-5919,2206,32692,30651,-11585,-21115,-25058,-15328,28960,32711,1900,-13231,-29978,-19478,26349,32679,2390,-16719,-28181,-12213,30405,31140,-10196,-28580,-16029,8963,31517,14563,-29353,-29953,13286,31902,7479,-22038,-24250,5857,32239,10718,-30965,-23536,22798,30821,-11124,-32751,-1043,30607,11698,-26018,-19919,20450,25601,-15002,-29132,10370,31082,-6941,-32024,4889,32400,-4283,-32487,5131,32362,-7420,-31916,11065,30841,-15868,-28669,21394,24818,-26887,-18731,31178,10078,-32755,920,30001,-13175,-21764,24495,8134,-31742,8727,31583,-24291,-21993,32509,4099,-28275,16560,10950,-30884,12892,30123,-30475,-12042,29379,-14509,-7539,31887,-20927,-25215,32629,-3002,-14674,29297,-18377,-27130,32493,-4222,-9435,31379,-25717,-20307,27568,-17711,9199,31449,-32737,1410,5010,-32382,31253,9845,-13118,30026,-29160,-14947,15436,-28904,29325,14618,-12441,30313,-31567,-8787,3551,-32575,32605,-3247,11296,30758,-26092,19821,-27435,-17917,6219,-32172,31815,-7838,21579,24657,-10603,31004,-31846,7717,-24617,-21626,2084,-32701,26312,-19527,32205,6038,18679,26921,-4161,32501,-23875,22443,-32568,3612,-28933,-15382,-16508,-28306,-614,-32762,14122,-29568,24938,-21255,30984,-10661,32766,-62,31466,9140,28397,16348,24697,21533,21208,24977,18477,27060,16824,28117,16401,28366,17243,27862,19279,26494,22308,24000,25942,20016,29541,14177,32159,6279,32580,-3491,29487,-14289,21855,-24414,9552,-31344,-5979,-32218,-21302,-24899,-31362,-9494,-31103,10312,-18275,27197,3673,32560,24858,21348,32650,-2758,19772,-26130,-7659,-31860,-30100,-12950,-27635,17607,490,32763,28874,15490,26745,-18931,-6461,-32124,-32272,-5677,-15760,28728,23191,23148,27959,-17087,-11412,-30716,-32062,6760,3429,32587,32731,-1534,-1105,-32749,-32697,2145,4646,32435,31631,-8550,-13678,-29776,-26240,19625,25640,20402,11870,-30542,-32758,-798,11756,30585,22754,-23579,-31432,-9259,7777,31830,22576,-23748,-32428,-4708,16188,28488,11181,-30801,-30149,12836,30518,11927,-14783,-29243,-7061,31997,24778,-21441,-32540,3855,29750,13733,-19379,-26423,5616,32282,7896,-31802,-18881,26780,26458,-19330,-30780,11238,32553,-3735,-32671,-2513,31957,7240,-31064,-10429,30428,12155,-30291,-12497,30694,11469,-31501,-9023,32372,5071,-32765,429,31929,-7360,-28990,15273,23104,-23235,-13790,29724,1349,-32740,12666,30219,-25254,-20879,32333,5313,-30052,13061,16929,-28055,3916,32532,-24125,-22174,32765,-307,-22666,23663,-2574,-32666,26955,18629,-31024,10544,8609,-31616,22487,23832,-31726,8193,6700,-32075,26673,19030,-27368,18019,-8373,-31680,32760,674,-8254,31710,-29594,-14067,18172,-27267,25331,20784,-22129,24166,-23959,-22354,21487,-24739,26385,19428,-15975,28609,-30904,-10893,4038,-32518,32461,-4465,14011,29620,-23018,23321,-30384,-12270,-1840,-32716,28086,-16877,28757,15705,2451,32675,-25176,20973,-32037,-6881,-15653,-28787,10253,-31122,29046,-15165,31786,7956,19674,26202,245,32766,-18071,27333,-29647,13955,-32705,-2024,-28459,-16242,-19577,-26277,-8846,-31551,1594,-32729,10486,-31044,17347,-27799,22218,-24084,25409,-20690,27300,-18122,28212,-16667,28336,-16455,27700,-17504,26166,-19724,23450,-22887,19180,-26567,13005,-30076,4768,-32419,-5254,-32344,-16082,-28550,-25868,-20114,-31985,-7121,-31600,8668,-22843,23492,-6340,32147,13566,29826,29103,15056,31873,-7599,17967,-27402,-7181,-31971,-28699,-15814,-30337,12383,-8016,31771,21946,24331,32182,-6160,10020,-31198,-23621,-22710,-30244,12610,981,32752,31396,9375,17555,-27668,-22930,-23408,-27232,18223,14232,29514,30736,-11355,-9787,-31272,-31326,9610,10834,30923,29902,-13399,-17140,-27928,-24536,21717,26530,19230,11641,-30630,-32719,-1779,9669,31307,25096,-21068,-29802,-13623,1961,32708,27163,-18326,-30196,-12724,7299,31943,20546,-25526,-32747,1165,23364,22973,-859,-32756,-21021,25135,32135,-6401,-29699,-13845,17034,27991,-123,-32767,-15545,28845,26602,-19131,-32011,7000,32409,4828,-29271,-14729,24207,22082,-18579,-26991,13342,29927,-9082,-31484,6098,32194,-4526,-32454,4403,32469,-5737,-32261,8490,31647,-12554,-30267,17658,27601,-23278,-23062,28519,16134,-32088,-6641,32390,-4951,-27896,17191,17762,-27536,-2697,32655,-14344,-29461,28149,16771,-32641,2879,23790,-22533,-3186,32611,-20162,-25830,32593,3368,-24042,22263,-2330,-32685,27765,17399,-29853,13510,3794,-32547,26815,18830,-28640,15920,-3308,-32600,31663,8431,-17866,27468,-21672,-24577,28816,-15599,10137,31159,-32251,5797,-2819,-32646,32741,-1288,1226,32744,-32661,2635,-5496,-32303,31289,-9729,15110,29074,-25018,21161,-27026,-18529,9317,-31415,32688,-2269,14892,29187,-19871,26054,-32353,-5193,-12099,-30452,18780,-26851,32762,-553,20831,25292,-5375,32323,-27095,18426,-32314,-5435,-20737,-25371,-369,-32765,18980,-26710,30563,-11814,32292,5555,25792,20209,14453,29407,1716,32721,-9904,31234,-19081,26638,-25487,20593,-29435,14398,-31534,8904,-32445,4585,-32726,1655,-32767,184,-32767,184,-32726,1655,-32445,4585,-31534,8904,-29435,14398,-25487,20593,-19081,26638,-9904,31234,1716,32721,14453,29407,25792,20209,32292,5555,30563,-11814,18980,-26710,-369,-32765,-20737,-25371,-32314,-5435,-27095,18426,-5375,32323,20831,25292,32762,-553,18780,-26851,-12099,-30452,-32353,-5193,-19871,26054,14892,29187,32688,-2269,9317,-31415,-27026,-18529,-25018,21161,15110,29074,31289,-9729,-5496,-32303,-32661,2635,1226,32744,32741,-1288,-2819,-32646,-32251,5797,10137,31159,28816,-15599,-21672,-24577,-17866,27468,31663,8431,-3308,-32600,-28640,15920,26815,18830,3794,-32547,-29853,13510,27765,17399,-2330,-32685,-24042,22263,32593,3368,-20162,-25830,-3186,32611,23790,-22533,-32641,2879,28149,16771,-14344,-29461,-2697,32655,17762,-27536,-27896,17191,32390,-4951,-32088,-6641,28519,16134,-23278,-23062,17658,27601,-12554,-30267,8490,31647,-5737,-32261,4403,32469,-4526,-32454,6098,32194,-9082,-31484,13342,29927,-18579,-26991,24207,22082,-29271,-14729,32409,4828,-32011,7000,26602,-19131,-15545,28845,-123,-32767,17034,27991,-29699,-13845,32135,-6401,-21021,25135,-859,-32756,23364,22973,-32747,1165,20546,-25526,7299,31943,-30196,-12724,27163,-18326,1961,32708,-29802,-13623,25096,-21068,9669,31307,-32719,-1779,11641,-30630,26530,19230,-24536,21717,-17140,-27928,29902,-13399,10834,30923,-31326,9610,-9787,-31272,30736,-11355,14232,29514,-27232,18223,-22930,-23408,17555,-27668,31396,9375,981,32752,-30244,12610,-23621,-22710,10020,-31198,32182,-6160,21946,24331,-8016,31771,-30337,12383,-28699,-15814,-7181,-31971,17967,-27402,31873,-7599,29103,15056,13566,29826,-6340,32147,-22843,23492,-31600,8668,-31985,-7121,-25868,-20114,-16082,-28550,-5254,-32344,4768,-32419,13005,-30076,19180,-26567,23450,-22887,26166,-19724,27700,-17504,28336,-16455,28212,-16667,27300,-18122,25409,-20690,22218,-24084,17347,-27799,10486,-31044,1594,-32729,-8846,-31551,-19577,-26277,-28459,-16242,-32705,-2024,-29647,13955,-18071,27333,245,32766,19674,26202,31786,7956,29046,-15165,10253,-31122,-15653,-28787,-32037,-6881,-25176,20973,2451,32675,28757,15705,28086,-16877,-1840,-32716,-30384,-12270,-23018,23321,14011,29620,32461,-4465,4038,-32518,-30904,-10893,-15975,28609,26385,19428,21487,-24739,-23959,-22354,-22129,24166,25331,20784,18172,-27267,-29594,-14067,-8254,31710,32760,674,-8373,-31680,-27368,18019,26673,19030,6700,-32075,-31726,8193,22487,23832,8609,-31616,-31024,10544,26955,18629,-2574,-32666,-22666,23663,32765,-307,-24125,-22174,3916,32532,16929,-28055,-30052,13061,32333,5313,-25254,-20879,12666,30219,1349,-32740,-13790,29724,23104,-23235,-28990,15273,31929,-7360,-32765,429,32372,5071,-31501,-9023,30694,11469,-30291,-12497,30428,12155,-31064,-10429,31957,7240,-32671,-2513,32553,-3735,-30780,11238,26458,-19330,-18881,26780,7896,-31802,5616,32282,-19379,-26423,29750,13733,-32540,3855,24778,-21441,-7061,31997,-14783,-29243,30518,11927,-30149,12836,11181,-30801,16188,28488,-32428,-4708,22576,-23748,7777,31830,-31432,-9259,22754,-23579,11756,30585,-32758,-798,11870,-30542,25640,20402,-26240,19625,-13678,-29776,31631,-8550,4646,32435,-32697,2145,-1105,-32749,32731,-1534,3429,32587,-32062,6760,-11412,-30716,27959,-17087,23191,23148,-15760,28728,-32272,-5677,-6461,-32124,26745,-18931,28874,15490,490,32763,-27635,17607,-30100,-12950,-7659,-31860,19772,-26130,32650,-2758,24858,21348,3673,32560,-18275,27197,-31103,10312,-31362,-9494,-21302,-24899,-5979,-32218,9552,-31344,21855,-24414,29487,-14289,32580,-3491,32159,6279,29541,14177,25942,20016,22308,24000,19279,26494,17243,27862,16401,28366,16824,28117,18477,27060,21208,24977,24697,21533,28397,16348,31466,9140,32766,-62,30984,-10661,24938,-21255,14122,-29568,-614,-32762,-16508,-28306,-28933,-15382,-32568,3612,-23875,22443,-4161,32501,18679,26921,32205,6038,26312,-19527,2084,-32701,-24617,-21626,-31846,7717,-10603,31004,21579,24657,31815,-7838,6219,-32172,-27435,-17917,-26092,19821,11296,30758,32605,-3247,3551,-32575,-31567,-8787,-12441,30313,29325,14618,15436,-28904,-29160,-14947,-13118,30026,31253,9845,5010,-32382,-32737,1410,9199,31449,27568,-17711,-25717,-20307,-9435,31379,32493,-4222,-18377,-27130,-14674,29297,32629,-3002,-20927,-25215,-7539,31887,29379,-14509,-30475,-12042,12892,30123,10950,-30884,-28275,16560,32509,4099,-24291,-21993,8727,31583,8134,-31742,-21764,24495,30001,-13175,-32755,920,31178,10078,-26887,-18731,21394,24818,-15868,-28669,11065,30841,-7420,-31916,5131,32362}, - {-4283,32486,5131,-32363,-7420,31915,11065,-30842,-15868,28668,21394,-24819,-26887,18730,31178,-10079,-32755,-921,30001,13174,-21764,-24496,8134,31741,8727,-31584,-24291,21992,32509,-4100,-28275,-16561,10950,30883,12892,-30124,-30475,12041,29379,14508,-7539,-31888,-20927,25214,32629,3001,-14674,-29298,-18377,27129,32493,4221,-9435,-31380,-25717,20306,27568,17710,9199,-31450,-32737,-1411,5010,32381,31253,-9846,-13118,-30027,-29160,14946,15436,28903,29325,-14619,-12441,-30314,-31567,8786,3551,32574,32605,3246,11296,-30759,-26092,-19822,-27435,17916,6219,32171,31815,7837,21579,-24658,-10603,-31005,-31846,-7718,-24617,21625,2084,32700,26312,19526,32205,-6039,18679,-26922,-4161,-32502,-23875,-22444,-32568,-3613,-28933,15381,-16508,28305,-614,32761,14122,29567,24938,21254,30984,10660,32766,61,31466,-9141,28397,-16349,24697,-21534,21208,-24978,18477,-27061,16824,-28118,16401,-28367,17243,-27863,19279,-26495,22308,-24001,25942,-20017,29541,-14178,32159,-6280,32580,3490,29487,14288,21855,24413,9552,31343,-5979,32217,-21302,24898,-31362,9493,-31103,-10313,-18275,-27198,3673,-32561,24858,-21349,32650,2757,19772,26129,-7659,31859,-30100,12949,-27635,-17608,490,-32764,28874,-15491,26745,18930,-6461,32123,-32272,5676,-15760,-28729,23191,-23149,27959,17086,-11412,30715,-32062,-6761,3429,-32588,32731,1533,-1105,32748,-32697,-2146,4646,-32436,31631,8549,-13678,29775,-26240,-19626,25640,-20403,11870,30541,-32758,797,11756,-30586,22754,23578,-31432,9258,7777,-31831,22576,23747,-32428,4707,16188,-28489,11181,30800,-30149,-12837,30518,-11928,-14783,29242,-7061,-31998,24778,21440,-32540,-3856,29750,-13734,-19379,26422,5616,-32283,7896,31801,-18881,-26781,26458,19329,-30780,-11239,32553,3734,-32671,2512,31957,-7241,-31064,10428,30428,-12156,-30291,12496,30694,-11470,-31501,9022,32372,-5072,-32765,-430,31929,7359,-28990,-15274,23104,23234,-13790,-29725,1349,32739,12666,-30220,-25254,20878,32333,-5314,-30052,-13062,16929,28054,3916,-32533,-24125,22173,32765,306,-22666,-23664,-2574,32665,26955,-18630,-31024,-10545,8609,31615,22487,-23833,-31726,-8194,6700,32074,26673,-19031,-27368,-18020,-8373,31679,32760,-675,-8254,-31711,-29594,14066,18172,27266,25331,-20785,-22129,-24167,-23959,22353,21487,24738,26385,-19429,-15975,-28610,-30904,10892,4038,32517,32461,4464,14011,-29621,-23018,-23322,-30384,12269,-1840,32715,28086,16876,28757,-15706,2451,-32676,-25176,-20974,-32037,6880,-15653,28786,10253,31121,29046,15164,31786,-7957,19674,-26203,245,-32767,-18071,-27334,-29647,-13956,-32705,2023,-28459,16241,-19577,26276,-8846,31550,1594,32728,10486,31043,17347,27798,22218,24083,25409,20689,27300,18121,28212,16666,28336,16454,27700,17503,26166,19723,23450,22886,19180,26566,13005,30075,4768,32418,-5254,32343,-16082,28549,-25868,20113,-31985,7120,-31600,-8669,-22843,-23493,-6340,-32148,13566,-29827,29103,-15057,31873,7598,17967,27401,-7181,31970,-28699,15813,-30337,-12384,-8016,-31772,21946,-24332,32182,6159,10020,31197,-23621,22709,-30244,-12611,981,-32753,31396,-9376,17555,27667,-22930,23407,-27232,-18224,14232,-29515,30736,11354,-9787,31271,-31326,-9611,10834,-30924,29902,13398,-17140,27927,-24536,-21718,26530,-19231,11641,30629,-32719,1778,9669,-31308,25096,21067,-29802,13622,1961,-32709,27163,18325,-30196,12723,7299,-31944,20546,25525,-32747,-1166,23364,-22974,-859,32755,-21021,-25136,32135,6400,-29699,13844,17034,-27992,-123,32766,-15545,-28846,26602,19130,-32011,-7001,32409,-4829,-29271,14728,24207,-22083,-18579,26990,13342,-29928,-9082,31483,6098,-32195,-4526,32453,4403,-32470,-5737,32260,8490,-31648,-12554,30266,17658,-27602,-23278,23061,28519,-16135,-32088,6640,32390,4950,-27896,-17192,17762,27535,-2697,-32656,-14344,29460,28149,-16772,-32641,-2880,23790,22532,-3186,-32612,-20162,25829,32593,-3369,-24042,-22264,-2330,32684,27765,-17400,-29853,-13511,3794,32546,26815,-18831,-28640,-15921,-3308,32599,31663,-8432,-17866,-27469,-21672,24576,28816,15598,10137,-31160,-32251,-5798,-2819,32645,32741,1287,1226,-32745,-32661,-2636,-5496,32302,31289,9728,15110,-29075,-25018,-21162,-27026,18528,9317,31414,32688,2268,14892,-29188,-19871,-26055,-32353,5192,-12099,30451,18780,26850,32762,552,20831,-25293,-5375,-32324,-27095,-18427,-32314,5434,-20737,25370,-369,32764,18980,26709,30563,11813,32292,-5556,25792,-20210,14453,-29408,1716,-32722,-9904,-31235,-19081,-26639,-25487,-20594,-29435,-14399,-31534,-8905,-32445,-4586,-32726,-1656,-32767,-185,-32767,-185,-32726,-1656,-32445,-4586,-31534,-8905,-29435,-14399,-25487,-20594,-19081,-26639,-9904,-31235,1716,-32722,14453,-29408,25792,-20210,32292,-5556,30563,11813,18980,26709,-369,32764,-20737,25370,-32314,5434,-27095,-18427,-5375,-32324,20831,-25293,32762,552,18780,26850,-12099,30451,-32353,5192,-19871,-26055,14892,-29188,32688,2268,9317,31414,-27026,18528,-25018,-21162,15110,-29075,31289,9728,-5496,32302,-32661,-2636,1226,-32745,32741,1287,-2819,32645,-32251,-5798,10137,-31160,28816,15598,-21672,24576,-17866,-27469,31663,-8432,-3308,32599,-28640,-15921,26815,-18831,3794,32546,-29853,-13511,27765,-17400,-2330,32684,-24042,-22264,32593,-3369,-20162,25829,-3186,-32612,23790,22532,-32641,-2880,28149,-16772,-14344,29460,-2697,-32656,17762,27535,-27896,-17192,32390,4950,-32088,6640,28519,-16135,-23278,23061,17658,-27602,-12554,30266,8490,-31648,-5737,32260,4403,-32470,-4526,32453,6098,-32195,-9082,31483,13342,-29928,-18579,26990,24207,-22083,-29271,14728,32409,-4829,-32011,-7001,26602,19130,-15545,-28846,-123,32766,17034,-27992,-29699,13844,32135,6400,-21021,-25136,-859,32755,23364,-22974,-32747,-1166,20546,25525,7299,-31944,-30196,12723,27163,18325,1961,-32709,-29802,13622,25096,21067,9669,-31308,-32719,1778,11641,30629,26530,-19231,-24536,-21718,-17140,27927,29902,13398,10834,-30924,-31326,-9611,-9787,31271,30736,11354,14232,-29515,-27232,-18224,-22930,23407,17555,27667,31396,-9376,981,-32753,-30244,-12611,-23621,22709,10020,31197,32182,6159,21946,-24332,-8016,-31772,-30337,-12384,-28699,15813,-7181,31970,17967,27401,31873,7598,29103,-15057,13566,-29827,-6340,-32148,-22843,-23493,-31600,-8669,-31985,7120,-25868,20113,-16082,28549,-5254,32343,4768,32418,13005,30075,19180,26566,23450,22886,26166,19723,27700,17503,28336,16454,28212,16666,27300,18121,25409,20689,22218,24083,17347,27798,10486,31043,1594,32728,-8846,31550,-19577,26276,-28459,16241,-32705,2023,-29647,-13956,-18071,-27334,245,-32767,19674,-26203,31786,-7957,29046,15164,10253,31121,-15653,28786,-32037,6880,-25176,-20974,2451,-32676,28757,-15706,28086,16876,-1840,32715,-30384,12269,-23018,-23322,14011,-29621,32461,4464,4038,32517,-30904,10892,-15975,-28610,26385,-19429,21487,24738,-23959,22353,-22129,-24167,25331,-20785,18172,27266,-29594,14066,-8254,-31711,32760,-675,-8373,31679,-27368,-18020,26673,-19031,6700,32074,-31726,-8194,22487,-23833,8609,31615,-31024,-10545,26955,-18630,-2574,32665,-22666,-23664,32765,306,-24125,22173,3916,-32533,16929,28054,-30052,-13062,32333,-5314,-25254,20878,12666,-30220,1349,32739,-13790,-29725,23104,23234,-28990,-15274,31929,7359,-32765,-430,32372,-5072,-31501,9022,30694,-11470,-30291,12496,30428,-12156,-31064,10428,31957,-7241,-32671,2512,32553,3734,-30780,-11239,26458,19329,-18881,-26781,7896,31801,5616,-32283,-19379,26422,29750,-13734,-32540,-3856,24778,21440,-7061,-31998,-14783,29242,30518,-11928,-30149,-12837,11181,30800,16188,-28489,-32428,4707,22576,23747,7777,-31831,-31432,9258,22754,23578,11756,-30586,-32758,797,11870,30541,25640,-20403,-26240,-19626,-13678,29775,31631,8549,4646,-32436,-32697,-2146,-1105,32748,32731,1533,3429,-32588,-32062,-6761,-11412,30715,27959,17086,23191,-23149,-15760,-28729,-32272,5676,-6461,32123,26745,18930,28874,-15491,490,-32764,-27635,-17608,-30100,12949,-7659,31859,19772,26129,32650,2757,24858,-21349,3673,-32561,-18275,-27198,-31103,-10313,-31362,9493,-21302,24898,-5979,32217,9552,31343,21855,24413,29487,14288,32580,3490,32159,-6280,29541,-14178,25942,-20017,22308,-24001,19279,-26495,17243,-27863,16401,-28367,16824,-28118,18477,-27061,21208,-24978,24697,-21534,28397,-16349,31466,-9141,32766,61,30984,10660,24938,21254,14122,29567,-614,32761,-16508,28305,-28933,15381,-32568,-3613,-23875,-22444,-4161,-32502,18679,-26922,32205,-6039,26312,19526,2084,32700,-24617,21625,-31846,-7718,-10603,-31005,21579,-24658,31815,7837,6219,32171,-27435,17916,-26092,-19822,11296,-30759,32605,3246,3551,32574,-31567,8786,-12441,-30314,29325,-14619,15436,28903,-29160,14946,-13118,-30027,31253,-9846,5010,32381,-32737,-1411,9199,-31450,27568,17710,-25717,20306,-9435,-31380,32493,4221,-18377,27129,-14674,-29298,32629,3001,-20927,25214,-7539,-31888,29379,14508,-30475,12041,12892,-30124,10950,30883,-28275,-16561,32509,-4100,-24291,21992,8727,-31584,8134,31741,-21764,-24496,30001,13174,-32755,-921,31178,-10079,-26887,18730,21394,-24819,-15868,28668,11065,-30842,-7420,31915,5131,-32363,-4283,32486,4889,-32401,-6941,32023,10370,-31083,-15002,29131,20450,-25602,-26018,19918,30607,-11699,-32751,1042,30821,11123,-23536,-22799,10718,30964,5857,-32240,-22038,24249,31902,-7480,-29953,-13287,14563,29352,8963,-31518,-28580,16028,31140,10195,-12213,-30406,-16719,28180,32679,-2391,-19478,-26350,-13231,29977,32711,-1901,-15328,-28961,-21115,25057,30651,11584,2206,-32693,-32229,5918,12326,30360,28023,-16982,-20065,-25906,-24455,21809,22398,23916,24372,-21902,-20259,-25755,-27831,17295,12779,30172,32111,-6521,1471,-32734,-30945,-10777,-20355,25678,16294,28428,32617,-3124,11984,-30497,-20642,-25449,-32525,3977,-15220,29018,13900,29672,31695,8312,27501,-17814,6820,-32050,-16614,-28244,-30863,-11009,-31216,9962,-19968,25980,-3063,32623,13454,29877,25563,20498,31756,8075,32477,-4343,29215,-14838,23705,-22622,17451,-27733,11526,-30673,6580,-32100,2940,-32635,736,-32759,-1,-32767,736,-32759,2940,-32635,6580,-32100,11526,-30673,17451,-27733,23705,-22622,29215,-14838,32477,-4343,31756,8075,25563,20498,13454,29877,-3063,32623,-19968,25980,-31216,9962,-30863,-11009,-16614,-28244,6820,-32050,27501,-17814,31695,8312,13900,29672,-15220,29018,-32525,3977,-20642,-25449,11984,-30497,32617,-3124,16294,28428,-20355,25678,-30945,-10777,1471,-32734,32111,-6521,12779,30172,-27831,17295,-20259,-25755,24372,-21902,22398,23916,-24455,21809,-20065,-25906,28023,-16982,12326,30360,-32229,5918,2206,-32693,30651,11584,-21115,25057,-15328,-28961,32711,-1901,-13231,29977,-19478,-26350,32679,-2391,-16719,28180,-12213,-30406,31140,10195,-28580,16028,8963,-31518,14563,29352,-29953,-13287,31902,-7480,-22038,24249,5857,-32240,10718,30964,-23536,-22799,30821,11123,-32751,1042,30607,-11699,-26018,19918,20450,-25602,-15002,29131,10370,-31083,-6941,32023,4889,-32401} -}; -short __attribute__((aligned(16))) X_u139[4][2*139] = {{23300,23038,23300,23038,24317,21962,26201,19676,28620,15954,31023,10547,32597,3326,32297,-5528,28973,-15304,21685,-24565,10195,-31141,-4430,-32467,-19380,-26422,-30238,-12625,-32165,6256,-22236,24067,-2221,32691,19971,25977,32414,4796,25749,-20265,1480,-32734,-24808,-21407,-31849,7703,-10898,30901,21125,25048,32014,-6982,7342,-31934,-26640,-19080,-27064,18472,9489,31362,32748,-1111,5892,-32233,-30777,-11246,-14975,29145,27870,17231,18165,-27271,-27474,-17857,-16277,28438,29944,13304,8778,-31570,-32665,-2590,5162,32357,29635,-13979,-22774,-23560,-13643,29791,32764,370,-14313,-29476,-18778,26852,32714,1850,-16916,-28064,-12283,30377,31253,-9844,-28253,-16597,8062,31759,15629,-28800,-30515,11938,31468,9134,-20554,-25520,3695,32557,12965,-30093,-25286,20840,31666,-8422,-32515,-4063,29312,14644,-23816,-22507,17544,27674,-11593,-30648,6619,32091,-2959,-32634,740,32758,-1,-32767,740,32758,-2959,-32634,6619,32091,-11593,-30648,17544,27674,-23816,-22507,29312,14644,-32515,-4063,31666,-8422,-25286,20840,12965,-30093,3695,32557,-20554,-25520,31468,9134,-30515,11938,15629,-28800,8062,31759,-28253,-16597,31253,-9844,-12283,30377,-16916,-28064,32714,1850,-18778,26852,-14313,-29476,32764,370,-13643,29791,-22774,-23560,29635,-13979,5162,32357,-32665,-2590,8778,-31570,29944,13304,-16277,28438,-27474,-17857,18165,-27271,27870,17231,-14975,29145,-30777,-11246,5892,-32233,32748,-1111,9489,31362,-27064,18472,-26640,-19080,7342,-31934,32014,-6982,21125,25048,-10898,30901,-31849,7703,-24808,-21407,1480,-32734,25749,-20265,32414,4796,19971,25977,-2221,32691,-22236,24067,-32165,6256,-30238,-12625,-19380,-26422,-4430,-32467,10195,-31141,21685,-24565,28973,-15304,32297,-5528,32597,3326,31023,10547,28620,15954,26201,19676,24317,21962}, - {23300,-23039,24317,-21963,26201,-19677,28620,-15955,31023,-10548,32597,-3327,32297,5527,28973,15303,21685,24564,10195,31140,-4430,32466,-19380,26421,-30238,12624,-32165,-6257,-22236,-24068,-2221,-32692,19971,-25978,32414,-4797,25749,20264,1480,32733,-24808,21406,-31849,-7704,-10898,-30902,21125,-25049,32014,6981,7342,31933,-26640,19079,-27064,-18473,9489,-31363,32748,1110,5892,32232,-30777,11245,-14975,-29146,27870,-17232,18165,27270,-27474,17856,-16277,-28439,29944,-13305,8778,31569,-32665,2589,5162,-32358,29635,13978,-22774,23559,-13643,-29792,32764,-371,-14313,29475,-18778,-26853,32714,-1851,-16916,28063,-12283,-30378,31253,9843,-28253,16596,8062,-31760,15629,28799,-30515,-11939,31468,-9135,-20554,25519,3695,-32558,12965,30092,-25286,-20841,31666,8421,-32515,4062,29312,-14645,-23816,22506,17544,-27675,-11593,30647,6619,-32092,-2959,32633,740,-32759,0,32767,740,-32759,-2959,32633,6619,-32092,-11593,30647,17544,-27675,-23816,22506,29312,-14645,-32515,4062,31666,8421,-25286,-20841,12965,30092,3695,-32558,-20554,25519,31468,-9135,-30515,-11939,15629,28799,8062,-31760,-28253,16596,31253,9843,-12283,-30378,-16916,28063,32714,-1851,-18778,-26853,-14313,29475,32764,-371,-13643,-29792,-22774,23559,29635,13978,5162,-32358,-32665,2589,8778,31569,29944,-13305,-16277,-28439,-27474,17856,18165,27270,27870,-17232,-14975,-29146,-30777,11245,5892,32232,32748,1110,9489,-31363,-27064,-18473,-26640,19079,7342,31933,32014,6981,21125,-25049,-10898,-30902,-31849,-7704,-24808,21406,1480,32733,25749,20264,32414,-4797,19971,-25978,-2221,-32692,-22236,-24068,-32165,-6257,-30238,12624,-19380,26421,-4430,32466,10195,31140,21685,24564,28973,15303,32297,5527,32597,-3327,31023,-10548,28620,-15955,26201,-19677,24317,-21963,23300,-23039}, - {32764,-371,0,32767,32764,-371,1480,32733,32597,-3327,5892,32232,31468,-9135,12965,30092,27870,-17232,21685,24564,19971,-25978,29635,13978,6619,-32092,32714,-1851,-10898,-30902,26201,-19677,-27064,-18473,8062,-31760,-32515,4062,-16277,-28439,-19380,26421,-32165,-6257,8778,31569,-23816,22506,31253,9843,7342,31933,23300,-23039,32014,6981,-12283,-30378,17544,-27675,-32665,2589,-22236,-24068,-4430,32466,-27474,17856,31666,8421,15629,28799,9489,-31363,28620,-15955,-31849,-7704,-18778,-26853,-2959,32633,-22774,23559,32414,-4797,28973,15303,-14975,-29146,3695,-32558,-20554,25519,-30777,11245,32297,5527,25749,20264,-13643,-29792,740,-32759,-14313,29475,-24808,21406,31023,-10548,32748,1110,-30515,-11939,-25286,-20841,18165,27270,10195,31140,-2221,-32692,5162,-32358,-11593,30647,-16916,28063,21125,-25049,24317,-21963,-26640,19079,-28253,16596,29312,-14645,29944,-13305,-30238,12624,-30238,12624,29944,-13305,29312,-14645,-28253,16596,-26640,19079,24317,-21963,21125,-25049,-16916,28063,-11593,30647,5162,-32358,-2221,-32692,10195,31140,18165,27270,-25286,-20841,-30515,-11939,32748,1110,31023,-10548,-24808,21406,-14313,29475,740,-32759,-13643,-29792,25749,20264,32297,5527,-30777,11245,-20554,25519,3695,-32558,-14975,-29146,28973,15303,32414,-4797,-22774,23559,-2959,32633,-18778,-26853,-31849,-7704,28620,-15955,9489,-31363,15629,28799,31666,8421,-27474,17856,-4430,32466,-22236,-24068,-32665,2589,17544,-27675,-12283,-30378,32014,6981,23300,-23039,7342,31933,31253,9843,-23816,22506,8778,31569,-32165,-6257,-19380,26421,-16277,-28439,-32515,4062,8062,-31760,-27064,-18473,26201,-19677,-10898,-30902,32714,-1851,6619,-32092,29635,13978,19971,-25978,21685,24564,27870,-17232,12965,30092,31468,-9135,5892,32232,32597,-3327,1480,32733}, - {32764,370,1480,-32734,32597,3326,5892,-32233,31468,9134,12965,-30093,27870,17231,21685,-24565,19971,25977,29635,-13979,6619,32091,32714,1850,-10898,30901,26201,19676,-27064,18472,8062,31759,-32515,-4063,-16277,28438,-19380,-26422,-32165,6256,8778,-31570,-23816,-22507,31253,-9844,7342,-31934,23300,23038,32014,-6982,-12283,30377,17544,27674,-32665,-2590,-22236,24067,-4430,-32467,-27474,-17857,31666,-8422,15629,-28800,9489,31362,28620,15954,-31849,7703,-18778,26852,-2959,-32634,-22774,-23560,32414,4796,28973,-15304,-14975,29145,3695,32557,-20554,-25520,-30777,-11246,32297,-5528,25749,-20265,-13643,29791,740,32758,-14313,-29476,-24808,-21407,31023,10547,32748,-1111,-30515,11938,-25286,20840,18165,-27271,10195,-31141,-2221,32691,5162,32357,-11593,-30648,-16916,-28064,21125,25048,24317,21962,-26640,-19080,-28253,-16597,29312,14644,29944,13304,-30238,-12625,-30238,-12625,29944,13304,29312,14644,-28253,-16597,-26640,-19080,24317,21962,21125,25048,-16916,-28064,-11593,-30648,5162,32357,-2221,32691,10195,-31141,18165,-27271,-25286,20840,-30515,11938,32748,-1111,31023,10547,-24808,-21407,-14313,-29476,740,32758,-13643,29791,25749,-20265,32297,-5528,-30777,-11246,-20554,-25520,3695,32557,-14975,29145,28973,-15304,32414,4796,-22774,-23560,-2959,-32634,-18778,26852,-31849,7703,28620,15954,9489,31362,15629,-28800,31666,-8422,-27474,-17857,-4430,-32467,-22236,24067,-32665,-2590,17544,27674,-12283,30377,32014,-6982,23300,23038,7342,-31934,31253,-9844,-23816,-22507,8778,-31570,-32165,6256,-19380,-26422,-16277,28438,-32515,-4063,8062,31759,-27064,18472,26201,19676,-10898,30901,32714,1850,6619,32091,29635,-13979,19971,25977,21685,-24565,27870,17231,12965,-30093,31468,9134,5892,-32233,32597,3326,1480,-32734,32764,370,0,-32768} -}; - -int16_t e839[839*2] = {32767,0,32766,245,32763,490,32758,736,32752,981,32744,1226,32733,1471,32721,1716,32708,1961,32692,2206,32675,2451,32655,2696,32634,2940,32611,3185,32587,3429,32560,3673,32532,3916,32501,4160,32469,4403,32435,4646,32400,4889,32362,5131,32323,5374,32282,5616,32239,5857,32194,6098,32147,6339,32099,6580,32049,6820,31997,7060,31943,7299,31887,7538,31830,7777,31771,8015,31710,8253,31647,8490,31583,8727,31517,8963,31449,9199,31379,9434,31307,9669,31234,9903,31159,10137,31082,10370,31004,10602,30923,10834,30841,11065,30758,11296,30672,11526,30585,11756,30496,11984,30405,12212,30313,12440,30219,12666,30123,12892,30026,13117,29927,13342,29826,13566,29724,13789,29620,14011,29514,14232,29407,14453,29297,14673,29187,14892,29074,15110,28960,15327,28845,15544,28728,15759,28609,15974,28488,16188,28366,16401,28243,16613,28117,16824,27991,17034,27862,17243,27732,17451,27601,17658,27468,17865,27333,18070,27197,18274,27060,18477,26921,18679,26780,18880,26638,19080,26494,19279,26349,19477,26202,19674,26054,19870,25905,20064,25754,20258,25601,20450,25448,20641,25292,20831,25135,21020,24977,21208,24818,21394,24657,21579,24495,21763,24331,21946,24166,22128,24000,22308,23832,22487,23663,22665,23492,22842,23321,23017,23148,23191,22973,23364,22798,23535,22621,23705,22443,23874,22263,24041,22082,24207,21901,24372,21717,24535,21533,24697,21348,24858,21161,25017,20973,25175,20784,25331,20593,25486,20402,25640,20209,25792,20016,25942,19821,26091,19625,26239,19428,26385,19230,26530,19030,26673,18830,26815,18629,26955,18426,27094,18223,27231,18019,27367,17813,27501,17607,27634,17399,27765,17191,27895,16981,28023,16771,28149,16560,28274,16348,28397,16134,28519,15920,28639,15705,28757,15490,28874,15273,28989,15056,29103,14837,29215,14618,29325,14398,29434,14177,29541,13955,29646,13733,29750,13510,29852,13286,29952,13061,30051,12836,30148,12610,30243,12383,30336,12155,30428,11927,30518,11698,30607,11469,30694,11238,30779,11008,30862,10776,30944,10544,31023,10312,31102,10078,31178,9845,31253,9610,31325,9375,31396,9140,31466,8904,31533,8668,31599,8431,31663,8193,31725,7956,31786,7717,31845,7479,31902,7240,31957,7000,32010,6760,32061,6520,32111,6279,32159,6038,32205,5797,32250,5555,32292,5313,32333,5071,32372,4828,32409,4585,32444,4342,32477,4099,32509,3855,32539,3612,32567,3368,32593,3123,32617,2879,32640,2635,32660,2390,32679,2145,32696,1900,32711,1655,32725,1410,32736,1165,32746,920,32754,674,32760,429,32764,184,32766,-62,32766,-307,32765,-553,32762,-798,32757,-1043,32750,-1288,32741,-1534,32731,-1779,32718,-2024,32704,-2269,32688,-2513,32670,-2758,32650,-3002,32629,-3247,32605,-3491,32580,-3735,32553,-3978,32524,-4222,32493,-4465,32461,-4708,32427,-4951,32390,-5193,32352,-5435,32313,-5677,32271,-5919,32228,-6160,32182,-6401,32135,-6641,32087,-6881,32036,-7121,31984,-7360,31929,-7599,31873,-7838,31815,-8076,31756,-8313,31695,-8550,31631,-8787,31566,-9023,31500,-9259,31431,-9494,31361,-9729,31289,-9963,31215,-10196,31140,-10429,31063,-10661,30984,-10893,30903,-11124,30821,-11355,30736,-11585,30651,-11814,30563,-12042,30474,-12270,30383,-12497,30290,-12724,30195,-12950,30099,-13175,30001,-13399,29902,-13623,29801,-13845,29698,-14067,29593,-14289,29487,-14509,29379,-14729,29270,-14947,29159,-15165,29046,-15382,28932,-15599,28816,-15814,28698,-16029,28579,-16242,28458,-16455,28336,-16667,28212,-16877,28086,-17087,27959,-17296,27830,-17504,27700,-17711,27568,-17917,27434,-18122,27300,-18326,27163,-18529,27025,-18731,26886,-18931,26745,-19131,26602,-19330,26458,-19527,26312,-19724,26166,-19919,26017,-20114,25867,-20307,25716,-20499,25563,-20690,25409,-20879,25253,-21068,25096,-21255,24938,-21441,24778,-21626,24616,-21810,24454,-21993,24290,-22174,24124,-22354,23958,-22533,23790,-22710,23620,-22887,23450,-23062,23277,-23235,23104,-23408,22929,-23579,22754,-23748,22576,-23917,22398,-24084,22218,-24250,22037,-24414,21855,-24577,21671,-24739,21487,-24899,21301,-25058,21114,-25215,20926,-25371,20736,-25526,20546,-25679,20354,-25830,20161,-25981,19967,-26130,19772,-26277,19576,-26423,19378,-26567,19180,-26710,18980,-26851,18780,-26991,18578,-27130,18376,-27267,18172,-27402,17967,-27536,17762,-27668,17555,-27799,17347,-27928,17139,-28055,16929,-28181,16718,-28306,16507,-28429,16294,-28550,16081,-28669,15867,-28787,15652,-28904,15436,-29019,15219,-29132,15001,-29243,14782,-29353,14563,-29461,14343,-29568,14122,-29673,13900,-29776,13677,-29878,13454,-29978,13230,-30076,13005,-30173,12779,-30267,12553,-30361,12326,-30452,12098,-30542,11870,-30630,11641,-30716,11411,-30801,11181,-30884,10950,-30965,10718,-31044,10486,-31122,10253,-31198,10020,-31272,9786,-31344,9552,-31415,9317,-31484,9081,-31551,8845,-31616,8609,-31680,8372,-31742,8134,-31802,7896,-31860,7658,-31916,7419,-31971,7180,-32024,6940,-32075,6700,-32124,6460,-32172,6219,-32218,5978,-32261,5736,-32303,5495,-32344,5253,-32382,5010,-32419,4768,-32454,4525,-32487,4282,-32518,4038,-32547,3794,-32575,3551,-32600,3307,-32624,3062,-32646,2818,-32666,2573,-32685,2329,-32701,2084,-32716,1839,-32729,1594,-32740,1349,-32749,1104,-32756,858,-32762,613,-32765,368,-32767,122,-32767,-123,-32765,-369,-32762,-614,-32756,-859,-32749,-1105,-32740,-1350,-32729,-1595,-32716,-1840,-32701,-2085,-32685,-2330,-32666,-2574,-32646,-2819,-32624,-3063,-32600,-3308,-32575,-3552,-32547,-3795,-32518,-4039,-32487,-4283,-32454,-4526,-32419,-4769,-32382,-5011,-32344,-5254,-32303,-5496,-32261,-5737,-32218,-5979,-32172,-6220,-32124,-6461,-32075,-6701,-32024,-6941,-31971,-7181,-31916,-7420,-31860,-7659,-31802,-7897,-31742,-8135,-31680,-8373,-31616,-8610,-31551,-8846,-31484,-9082,-31415,-9318,-31344,-9553,-31272,-9787,-31198,-10021,-31122,-10254,-31044,-10487,-30965,-10719,-30884,-10951,-30801,-11182,-30716,-11412,-30630,-11642,-30542,-11871,-30452,-12099,-30361,-12327,-30267,-12554,-30173,-12780,-30076,-13006,-29978,-13231,-29878,-13455,-29776,-13678,-29673,-13901,-29568,-14123,-29461,-14344,-29353,-14564,-29243,-14783,-29132,-15002,-29019,-15220,-28904,-15437,-28787,-15653,-28669,-15868,-28550,-16082,-28429,-16295,-28306,-16508,-28181,-16719,-28055,-16930,-27928,-17140,-27799,-17348,-27668,-17556,-27536,-17763,-27402,-17968,-27267,-18173,-27130,-18377,-26991,-18579,-26851,-18781,-26710,-18981,-26567,-19181,-26423,-19379,-26277,-19577,-26130,-19773,-25981,-19968,-25830,-20162,-25679,-20355,-25526,-20547,-25371,-20737,-25215,-20927,-25058,-21115,-24899,-21302,-24739,-21488,-24577,-21672,-24414,-21856,-24250,-22038,-24084,-22219,-23917,-22399,-23748,-22577,-23579,-22755,-23408,-22930,-23235,-23105,-23062,-23278,-22887,-23451,-22710,-23621,-22533,-23791,-22354,-23959,-22174,-24125,-21993,-24291,-21810,-24455,-21626,-24617,-21441,-24779,-21255,-24939,-21068,-25097,-20879,-25254,-20690,-25410,-20499,-25564,-20307,-25717,-20114,-25868,-19919,-26018,-19724,-26167,-19527,-26313,-19330,-26459,-19131,-26603,-18931,-26746,-18731,-26887,-18529,-27026,-18326,-27164,-18122,-27301,-17917,-27435,-17711,-27569,-17504,-27701,-17296,-27831,-17087,-27960,-16877,-28087,-16667,-28213,-16455,-28337,-16242,-28459,-16029,-28580,-15814,-28699,-15599,-28817,-15382,-28933,-15165,-29047,-14947,-29160,-14729,-29271,-14509,-29380,-14289,-29488,-14067,-29594,-13845,-29699,-13623,-29802,-13399,-29903,-13175,-30002,-12950,-30100,-12724,-30196,-12497,-30291,-12270,-30384,-12042,-30475,-11814,-30564,-11585,-30652,-11355,-30737,-11124,-30822,-10893,-30904,-10661,-30985,-10429,-31064,-10196,-31141,-9963,-31216,-9729,-31290,-9494,-31362,-9259,-31432,-9023,-31501,-8787,-31567,-8550,-31632,-8313,-31696,-8076,-31757,-7838,-31816,-7599,-31874,-7360,-31930,-7121,-31985,-6881,-32037,-6641,-32088,-6401,-32136,-6160,-32183,-5919,-32229,-5677,-32272,-5435,-32314,-5193,-32353,-4951,-32391,-4708,-32428,-4465,-32462,-4222,-32494,-3978,-32525,-3735,-32554,-3491,-32581,-3247,-32606,-3002,-32630,-2758,-32651,-2513,-32671,-2269,-32689,-2024,-32705,-1779,-32719,-1534,-32732,-1288,-32742,-1043,-32751,-798,-32758,-553,-32763,-307,-32766,-62,-32767,184,-32767,429,-32765,674,-32761,920,-32755,1165,-32747,1410,-32737,1655,-32726,1900,-32712,2145,-32697,2390,-32680,2635,-32661,2879,-32641,3123,-32618,3368,-32594,3612,-32568,3855,-32540,4099,-32510,4342,-32478,4585,-32445,4828,-32410,5071,-32373,5313,-32334,5555,-32293,5797,-32251,6038,-32206,6279,-32160,6520,-32112,6760,-32062,7000,-32011,7240,-31958,7479,-31903,7717,-31846,7956,-31787,8193,-31726,8431,-31664,8668,-31600,8904,-31534,9140,-31467,9375,-31397,9610,-31326,9845,-31254,10078,-31179,10312,-31103,10544,-31024,10776,-30945,11008,-30863,11238,-30780,11469,-30695,11698,-30608,11927,-30519,12155,-30429,12383,-30337,12610,-30244,12836,-30149,13061,-30052,13286,-29953,13510,-29853,13733,-29751,13955,-29647,14177,-29542,14398,-29435,14618,-29326,14837,-29216,15056,-29104,15273,-28990,15490,-28875,15705,-28758,15920,-28640,16134,-28520,16348,-28398,16560,-28275,16771,-28150,16981,-28024,17191,-27896,17399,-27766,17607,-27635,17813,-27502,18019,-27368,18223,-27232,18426,-27095,18629,-26956,18830,-26816,19030,-26674,19230,-26531,19428,-26386,19625,-26240,19821,-26092,20016,-25943,20209,-25793,20402,-25641,20593,-25487,20784,-25332,20973,-25176,21161,-25018,21348,-24859,21533,-24698,21717,-24536,21901,-24373,22082,-24208,22263,-24042,22443,-23875,22621,-23706,22798,-23536,22973,-23365,23148,-23192,23321,-23018,23492,-22843,23663,-22666,23832,-22488,24000,-22309,24166,-22129,24331,-21947,24495,-21764,24657,-21580,24818,-21395,24977,-21209,25135,-21021,25292,-20832,25448,-20642,25601,-20451,25754,-20259,25905,-20065,26054,-19871,26202,-19675,26349,-19478,26494,-19280,26638,-19081,26780,-18881,26921,-18680,27060,-18478,27197,-18275,27333,-18071,27468,-17866,27601,-17659,27732,-17452,27862,-17244,27991,-17035,28117,-16825,28243,-16614,28366,-16402,28488,-16189,28609,-15975,28728,-15760,28845,-15545,28960,-15328,29074,-15111,29187,-14893,29297,-14674,29407,-14454,29514,-14233,29620,-14012,29724,-13790,29826,-13567,29927,-13343,30026,-13118,30123,-12893,30219,-12667,30313,-12441,30405,-12213,30496,-11985,30585,-11757,30672,-11527,30758,-11297,30841,-11066,30923,-10835,31004,-10603,31082,-10371,31159,-10138,31234,-9904,31307,-9670,31379,-9435,31449,-9200,31517,-8964,31583,-8728,31647,-8491,31710,-8254,31771,-8016,31830,-7778,31887,-7539,31943,-7300,31997,-7061,32049,-6821,32099,-6581,32147,-6340,32194,-6099,32239,-5858,32282,-5617,32323,-5375,32362,-5132,32400,-4890,32435,-4647,32469,-4404,32501,-4161,32532,-3917,32560,-3674,32587,-3430,32611,-3186,32634,-2941,32655,-2697,32675,-2452,32692,-2207,32708,-1962,32721,-1717,32733,-1472,32744,-1227,32752,-982,32758,-737,32763,-491,32766,-246}; - -int16_t e139[139*2] = {32767,0,32733,1480,32633,2958,32466,4429,32232,5892,31933,7342,31569,8778,31140,10195,30647,11592,30092,12965,29475,14312,28799,15629,28063,16915,27270,18165,26421,19379,25519,20553,24564,21685,23559,22773,22506,23815,21406,24807,20264,25749,19079,26639,17856,27473,16596,28252,15303,28973,13978,29635,12624,30237,11245,30776,9843,31253,8421,31666,6981,32014,5527,32297,4062,32514,2589,32664,1110,32748,-371,32764,-1851,32714,-3327,32597,-4797,32414,-6257,32164,-7704,31848,-9135,31468,-10548,31023,-11939,30514,-13305,29944,-14645,29312,-15955,28620,-17232,27870,-18473,27063,-19677,26201,-20841,25285,-21963,24317,-23039,23300,-24068,22235,-25049,21125,-25978,19971,-26853,18777,-27675,17544,-28439,16276,-29146,14974,-29792,13642,-30378,12282,-30902,10897,-31363,9489,-31760,8062,-32092,6619,-32358,5162,-32558,3695,-32692,2220,-32759,740,-32759,-741,-32692,-2221,-32558,-3696,-32358,-5163,-32092,-6620,-31760,-8063,-31363,-9490,-30902,-10898,-30378,-12283,-29792,-13643,-29146,-14975,-28439,-16277,-27675,-17545,-26853,-18778,-25978,-19972,-25049,-21126,-24068,-22236,-23039,-23301,-21963,-24318,-20841,-25286,-19677,-26202,-18473,-27064,-17232,-27871,-15955,-28621,-14645,-29313,-13305,-29945,-11939,-30515,-10548,-31024,-9135,-31469,-7704,-31849,-6257,-32165,-4797,-32415,-3327,-32598,-1851,-32715,-371,-32765,1110,-32749,2589,-32665,4062,-32515,5527,-32298,6981,-32015,8421,-31667,9843,-31254,11245,-30777,12624,-30238,13978,-29636,15303,-28974,16596,-28253,17856,-27474,19079,-26640,20264,-25750,21406,-24808,22506,-23816,23559,-22774,24564,-21686,25519,-20554,26421,-19380,27270,-18166,28063,-16916,28799,-15630,29475,-14313,30092,-12966,30647,-11593,31140,-10196,31569,-8779,31933,-7343,32232,-5893,32466,-4430,32633,-2959,32733,-1481}; diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c new file mode 100644 index 0000000000000000000000000000000000000000..2f39346be2027e4fc1d9460ec6cb508026b9f666 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c @@ -0,0 +1,771 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/prach_common.c + * \brief Common routines for UE/eNB PRACH physical channel V8.6 2009-03 + * \author R. Knopp + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#include "PHY/sse_intrin.h" +#include "PHY/defs_common.h" +#include "PHY/phy_extern.h" +#include "PHY/phy_extern_ue.h" +#include "UTIL/LOG/vcd_signal_dumper.h" + + +uint16_t NCS_unrestricted[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419}; +uint16_t NCS_restricted[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case +uint16_t NCS_4[7] = {2,4,6,8,10,12,15}; + +int16_t ru[2*839]; // quantized roots of unity +uint32_t ZC_inv[839]; // multiplicative inverse for roots u +uint16_t du[838]; + +// This is table 5.7.1-4 from 36.211 +PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = { + // TDD Configuration Index 0 + { {1,{{0,1,0,2}}},{1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}}, + // TDD Configuration Index 1 + { {1,{{0,2,0,2}}},{1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}}, + // TDD Configuration Index 2 + { {1,{{0,1,1,2}}},{1,{{0,1,1,1}}}, {1,{{0,1,1,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,1}}}}, + // TDD Configuration Index 3 + { {1,{{0,0,0,2}}},{1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}}, + // TDD Configuration Index 4 + { {1,{{0,0,1,2}}},{1,{{0,0,1,1}}}, {1,{{0,0,1,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,1}}}}, + // TDD Configuration Index 5 + { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, + // TDD Configuration Index 6 + { {2,{{0,0,0,2},{0,0,1,2}}}, {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {2,{{0,0,0,1},{0,0,0,2}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {2,{{0,0,0,2},{0,0,1,1}}}}, + // TDD Configuration Index 7 + { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,2}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, + // TDD Configuration Index 8 + { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,1,1}}}}, + // TDD Configuration Index 9 + { {3,{{0,0,0,1},{0,0,0,2},{0,0,1,2}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,0,2}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {3,{{0,0,0,1},{0,0,0,2},{0,0,1,1}}}}, + // TDD Configuration Index 10 + { {3,{{0,0,0,0},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,2},{0,0,1,0}}}}, + // TDD Configuration Index 11 + { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}}, + // TDD Configuration Index 12 + { {4,{{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, + {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,2}}}, + {4,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {4,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} + }, + // TDD Configuration Index 13 + { {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1}}} + }, + // TDD Configuration Index 14 + { {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} + }, + // TDD Configuration Index 15 + { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1}}}, + {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1},{1,0,0,2}}}, + {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,1}}}, {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, + {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} + }, + // TDD Configuration Index 16 + { {5,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,1,1}}}, + {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,1,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,2}}}, + {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}} + }, + // TDD Configuration Index 17 + { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}} + }, + // TDD Configuration Index 18 + { {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, + {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1},{1,0,0,2}}}, + {6,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0},{2,0,0,1}}}, + {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,0,2}}} + }, + // TDD Configuration Index 19 + { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0},{1,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,1,1}}} + }, + // TDD Configuration Index 20 + { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}}, + // TDD Configuration Index 21 + { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}}, + + // TDD Configuration Index 22 + { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}}, + + // TDD Configuration Index 23 + { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, + + // TDD Configuration Index 24 + { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}}, + + // TDD Configuration Index 25 + { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, + + // TDD Configuration Index 26 + { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}}, + + // TDD Configuration Index 27 + { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}} + }, + + // TDD Configuration Index 28 + { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}}, + {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}} + }, + + // TDD Configuration Index 29 + { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}}, + {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}}, + {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}} + }, + + + // TDD Configuration Index 30 + { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}}, + + // TDD Configuration Index 31 + { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}}, + + // TDD Configuration Index 32 + { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}}, + + // TDD Configuration Index 33 + { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, + + // TDD Configuration Index 34 + { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}}, + + // TDD Configuration Index 35 + { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, + + // TDD Configuration Index 36 + { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}}, + + // TDD Configuration Index 37 + { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}} + }, + + // TDD Configuration Index 38 + { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}}, + {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}} + }, + + // TDD Configuration Index 39 + { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}}, + {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}}, + {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}} + }, + + // TDD Configuration Index 40 + { {1,{{0,1,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}}, + // TDD Configuration Index 41 + { {1,{{0,2,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}}, + + // TDD Configuration Index 42 + { {1,{{0,1,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}}, + + // TDD Configuration Index 43 + { {1,{{0,0,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}}, + + // TDD Configuration Index 44 + { {1,{{0,0,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}}, + + // TDD Configuration Index 45 + { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}}, + + // TDD Configuration Index 46 + { {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}}, + + // TDD Configuration Index 47 + { {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}} + } +}; + + + +uint16_t prach_root_sequence_map0_3[838] = { 129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84, 755, 105, 734, 93, 746, 70, 769, 60, 779, + 2, 837, 1, 838, + 56, 783, 112, 727, 148, 691, + 80, 759, 42, 797, 40, 799, + 35, 804, 73, 766, 146, 693, + 31, 808, 28, 811, 30, 809, 27, 812, 29, 810, + 24, 815, 48, 791, 68, 771, 74, 765, 178, 661, 136, 703, + 86, 753, 78, 761, 43, 796, 39, 800, 20, 819, 21, 818, + 95, 744, 202, 637, 190, 649, 181, 658, 137, 702, 125, 714, 151, 688, + 217, 622, 128, 711, 142, 697, 122, 717, 203, 636, 118, 721, 110, 729, 89, 750, 103, 736, 61, + 778, 55, 784, 15, 824, 14, 825, + 12, 827, 23, 816, 34, 805, 37, 802, 46, 793, 207, 632, 179, 660, 145, 694, 130, 709, 223, 616, + 228, 611, 227, 612, 132, 707, 133, 706, 143, 696, 135, 704, 161, 678, 201, 638, 173, 666, 106, + 733, 83, 756, 91, 748, 66, 773, 53, 786, 10, 829, 9, 830, + 7, 832, 8, 831, 16, 823, 47, 792, 64, 775, 57, 782, 104, 735, 101, 738, 108, 731, 208, 631, 184, + 655, 197, 642, 191, 648, 121, 718, 141, 698, 149, 690, 216, 623, 218, 621, + 152, 687, 144, 695, 134, 705, 138, 701, 199, 640, 162, 677, 176, 663, 119, 720, 158, 681, 164, + 675, 174, 665, 171, 668, 170, 669, 87, 752, 169, 670, 88, 751, 107, 732, 81, 758, 82, 757, 100, + 739, 98, 741, 71, 768, 59, 780, 65, 774, 50, 789, 49, 790, 26, 813, 17, 822, 13, 826, 6, 833, + 5, 834, 33, 806, 51, 788, 75, 764, 99, 740, 96, 743, 97, 742, 166, 673, 172, 667, 175, 664, 187, + 652, 163, 676, 185, 654, 200, 639, 114, 725, 189, 650, 115, 724, 194, 645, 195, 644, 192, 647, + 182, 657, 157, 682, 156, 683, 211, 628, 154, 685, 123, 716, 139, 700, 212, 627, 153, 686, 213, + 626, 215, 624, 150, 689, + 225, 614, 224, 615, 221, 618, 220, 619, 127, 712, 147, 692, 124, 715, 193, 646, 205, 634, 206, + 633, 116, 723, 160, 679, 186, 653, 167, 672, 79, 760, 85, 754, 77, 762, 92, 747, 58, 781, 62, + 777, 69, 770, 54, 785, 36, 803, 32, 807, 25, 814, 18, 821, 11, 828, 4, 835, + 3, 836, 19, 820, 22, 817, 41, 798, 38, 801, 44, 795, 52, 787, 45, 794, 63, 776, 67, 772, 72, + 767, 76, 763, 94, 745, 102, 737, 90, 749, 109, 730, 165, 674, 111, 728, 209, 630, 204, 635, 117, + 722, 188, 651, 159, 680, 198, 641, 113, 726, 183, 656, 180, 659, 177, 662, 196, 643, 155, 684, + 214, 625, 126, 713, 131, 708, 219, 620, 222, 617, 226, 613, + 230, 609, 232, 607, 262, 577, 252, 587, 418, 421, 416, 423, 413, 426, 411, 428, 376, 463, 395, + 444, 283, 556, 285, 554, 379, 460, 390, 449, 363, 476, 384, 455, 388, 451, 386, 453, 361, 478, + 387, 452, 360, 479, 310, 529, 354, 485, 328, 511, 315, 524, 337, 502, 349, 490, 335, 504, 324, + 515, + 323, 516, 320, 519, 334, 505, 359, 480, 295, 544, 385, 454, 292, 547, 291, 548, 381, 458, 399, + 440, 380, 459, 397, 442, 369, 470, 377, 462, 410, 429, 407, 432, 281, 558, 414, 425, 247, 592, + 277, 562, 271, 568, 272, 567, 264, 575, 259, 580, + 237, 602, 239, 600, 244, 595, 243, 596, 275, 564, 278, 561, 250, 589, 246, 593, 417, 422, 248, + 591, 394, 445, 393, 446, 370, 469, 365, 474, 300, 539, 299, 540, 364, 475, 362, 477, 298, 541, + 312, 527, 313, 526, 314, 525, 353, 486, 352, 487, 343, 496, 327, 512, 350, 489, 326, 513, 319, + 520, 332, 507, 333, 506, 348, 491, 347, 492, 322, 517, + 330, 509, 338, 501, 341, 498, 340, 499, 342, 497, 301, 538, 366, 473, 401, 438, 371, 468, 408, + 431, 375, 464, 249, 590, 269, 570, 238, 601, 234, 605, + 257, 582, 273, 566, 255, 584, 254, 585, 245, 594, 251, 588, 412, 427, 372, 467, 282, 557, 403, + 436, 396, 443, 392, 447, 391, 448, 382, 457, 389, 450, 294, 545, 297, 542, 311, 528, 344, 495, + 345, 494, 318, 521, 331, 508, 325, 514, 321, 518, + 346, 493, 339, 500, 351, 488, 306, 533, 289, 550, 400, 439, 378, 461, 374, 465, 415, 424, 270, + 569, 241, 598, + 231, 608, 260, 579, 268, 571, 276, 563, 409, 430, 398, 441, 290, 549, 304, 535, 308, 531, 358, + 481, 316, 523, + 293, 546, 288, 551, 284, 555, 368, 471, 253, 586, 256, 583, 263, 576, + 242, 597, 274, 565, 402, 437, 383, 456, 357, 482, 329, 510, + 317, 522, 307, 532, 286, 553, 287, 552, 266, 573, 261, 578, + 236, 603, 303, 536, 356, 483, + 355, 484, 405, 434, 404, 435, 406, 433, + 235, 604, 267, 572, 302, 537, + 309, 530, 265, 574, 233, 606, + 367, 472, 296, 543, + 336, 503, 305, 534, 373, 466, 280, 559, 279, 560, 419, 420, 240, 599, 258, 581, 229, 610 + }; + +uint16_t prach_root_sequence_map4[138] = { 1,138,2,137,3,136,4,135,5,134,6,133,7,132,8,131,9,130,10,129, + 11,128,12,127,13,126,14,125,15,124,16,123,17,122,18,121,19,120,20,119, + 21,118,22,117,23,116,24,115,25,114,26,113,27,112,28,111,29,110,30,109, + 31,108,32,107,33,106,34,105,35,104,36,103,37,102,38,101,39,100,40,99, + 41,98,42,97,43,96,44,95,45,94,46,93,47,92,48,91,49,90,50,89, + 51,88,52,87,53,86,54,85,55,84,56,83,57,82,58,81,59,80,60,79, + 61,78,62,77,63,76,64,75,65,74,66,73,67,72,68,71,69,70 + }; + +void dump_prach_config(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) +{ + + FILE *fd; + + fd = fopen("prach_config.txt","w"); + fprintf(fd,"prach_config: subframe = %d\n",subframe); + fprintf(fd,"prach_config: N_RB_UL = %d\n",frame_parms->N_RB_UL); + fprintf(fd,"prach_config: frame_type = %s\n",(frame_parms->frame_type==1) ? "TDD":"FDD"); + + if(frame_parms->frame_type==1) fprintf(fd,"prach_config: tdd_config = %d\n",frame_parms->tdd_config); + + fprintf(fd,"prach_config: rootSequenceIndex = %d\n",frame_parms->prach_config_common.rootSequenceIndex); + fprintf(fd,"prach_config: prach_ConfigIndex = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex); + fprintf(fd,"prach_config: Ncs_config = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig); + fprintf(fd,"prach_config: highSpeedFlag = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.highSpeedFlag); + fprintf(fd,"prach_config: n_ra_prboffset = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset); + fclose(fd); + +} + +// This function computes the du +void fill_du(uint8_t prach_fmt) +{ + + uint16_t iu,u,p; + uint16_t N_ZC; + uint16_t *prach_root_sequence_map; + + if (prach_fmt<4) { + N_ZC = 839; + prach_root_sequence_map = prach_root_sequence_map0_3; + } else { + N_ZC = 139; + prach_root_sequence_map = prach_root_sequence_map4; + } + + for (iu=0; iu<(N_ZC-1); iu++) { + + u=prach_root_sequence_map[iu]; + p=1; + + while (((u*p)%N_ZC)!=1) + p++; + + du[u] = ((p<(N_ZC>>1)) ? p : (N_ZC-p)); + } + +} + +uint8_t get_num_prach_tdd(module_id_t Mod_id) +{ + LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][0]->frame_parms; + return(tdd_preamble_map[fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex][fp->tdd_config].num_prach); +} + +uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index) +{ + LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][0]->frame_parms; + return(tdd_preamble_map[fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex][fp->tdd_config].map[tdd_map_index].f_ra); +} + +uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type) +{ + + if (frame_type == FDD) // FDD + return(prach_ConfigIndex>>4); + + else { + if (prach_ConfigIndex < 20) + return (0); + + if (prach_ConfigIndex < 30) + return (1); + + if (prach_ConfigIndex < 40) + return (2); + + if (prach_ConfigIndex < 48) + return (3); + else + return (4); + } +} + +uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t prach_ConfigIndex, + uint8_t n_ra_prboffset, + uint8_t tdd_mapindex, uint16_t Nf) +{ + lte_frame_type_t frame_type = frame_parms->frame_type; + uint8_t tdd_config = frame_parms->tdd_config; + + uint8_t n_ra_prb; + uint8_t f_ra,t1_ra; + uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type); + uint8_t Nsp=2; + + if (frame_type == TDD) { // TDD + + if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) { + LOG_E(PHY, "Illegal prach_ConfigIndex %"PRIu8"", prach_ConfigIndex); + return(-1); + } + + // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211) + f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra; + + if (prach_fmt < 4) { + if ((f_ra&1) == 0) { + n_ra_prb = n_ra_prboffset + 6*(f_ra>>1); + } else { + n_ra_prb = frame_parms->N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1); + } + } else { + if ((tdd_config >2) && (tdd_config<6)) + Nsp = 2; + + t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; + + if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) { + n_ra_prb = 6*f_ra; + } else { + n_ra_prb = frame_parms->N_RB_UL - 6*(f_ra+1); + } + } + } + else { //FDD + n_ra_prb = n_ra_prboffset; + } + return(n_ra_prb); +} + +int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe) +{ + // uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; + uint8_t tdd_config = frame_parms->tdd_config; + uint8_t t0_ra; + uint8_t t1_ra; + uint8_t t2_ra; + + int prach_mask = 0; + + if (frame_parms->frame_type == FDD) { //FDD + //implement Table 5.7.1-2 from 36.211 (Rel-10, p.41) + if ((((frame&1) == 1) && (subframe < 9)) || + (((frame&1) == 0) && (subframe == 9))) // This is an odd frame, ignore even-only PRACH frames + if (((prach_ConfigIndex&0xf)<3) || // 0,1,2,16,17,18,32,33,34,48,49,50 + ((prach_ConfigIndex&0x1f)==18) || // 18,50 + ((prach_ConfigIndex&0xf)==15)) // 15,47 + return(0); + + switch (prach_ConfigIndex&0x1f) { + case 0: + case 3: + if (subframe==1) prach_mask = 1; + break; + + case 1: + case 4: + if (subframe==4) prach_mask = 1; + break; + + case 2: + case 5: + if (subframe==7) prach_mask = 1; + break; + + case 6: + if ((subframe==1) || (subframe==6)) prach_mask=1; + break; + + case 7: + if ((subframe==2) || (subframe==7)) prach_mask=1; + break; + + case 8: + if ((subframe==3) || (subframe==8)) prach_mask=1; + break; + + case 9: + if ((subframe==1) || (subframe==4) || (subframe==7)) prach_mask=1; + break; + + case 10: + if ((subframe==2) || (subframe==5) || (subframe==8)) prach_mask=1; + break; + + case 11: + if ((subframe==3) || (subframe==6) || (subframe==9)) prach_mask=1; + break; + + case 12: + if ((subframe&1)==0) prach_mask=1; + break; + + case 13: + if ((subframe&1)==1) prach_mask=1; + break; + + case 14: + prach_mask=1; + break; + + case 15: + if (subframe==9) prach_mask=1; + break; + } + } else { // TDD + + AssertFatal(prach_ConfigIndex<64, + "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex); + AssertFatal(tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach>0, + "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex); + + t0_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t0_ra; + t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; + t2_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t2_ra; +#ifdef PRACH_DEBUG + LOG_I(PHY,"[PRACH] Checking for PRACH format (ConfigIndex %d) in TDD subframe %d (%d,%d,%d)\n", + prach_ConfigIndex, + subframe, + t0_ra,t1_ra,t2_ra); +#endif + + if ((((t0_ra == 1) && ((frame &1)==0))|| // frame is even and PRACH is in even frames + ((t0_ra == 2) && ((frame &1)==1))|| // frame is odd and PRACH is in odd frames + (t0_ra == 0)) && // PRACH is in all frames + (((subframe<5)&&(t1_ra==0)) || // PRACH is in 1st half-frame + (((subframe>4)&&(t1_ra==1))))) { // PRACH is in 2nd half-frame + if ((prach_ConfigIndex<48) && // PRACH only in normal UL subframe + (((subframe%5)-2)==t2_ra)) prach_mask=1; + else if ((prach_ConfigIndex>47) && (((subframe%5)-1)==t2_ra)) prach_mask=1; // PRACH can be in UpPTS + } + } + + return(prach_mask); +} + +int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) { + + uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; + int prach_mask = is_prach_subframe0(frame_parms,prach_ConfigIndex,frame,subframe); + +#ifdef Rel14 + int i; + + for (i=0;i<4;i++) { + if (frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] == 1) + prach_mask|=(is_prach_subframe0(frame_parms,frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],frame,subframe)<<(i+1)); + } +#endif + return(prach_mask); +} + + +void compute_prach_seq(uint16_t rootSequenceIndex, + uint8_t prach_ConfigIndex, + uint8_t zeroCorrelationZoneConfig, + uint8_t highSpeedFlag, + lte_frame_type_t frame_type, + uint32_t X_u[64][839]) +{ + + // Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC) + unsigned int k,inv_u,i,NCS=0,num_preambles; + int N_ZC; + uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type); + uint16_t *prach_root_sequence_map; + uint16_t u, preamble_offset; + uint16_t n_shift_ra,n_shift_ra_bar, d_start,numshift; + uint8_t not_found; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_IN); + +#ifdef PRACH_DEBUG + LOG_I(PHY,"compute_prach_seq: NCS_config %d, prach_fmt %d\n",zeroCorrelationZoneConfig, prach_fmt); +#endif + + AssertFatal(prach_fmt<4, + "PRACH sequence is only precomputed for prach_fmt<4 (have %"PRIu8")\n", prach_fmt ); + N_ZC = (prach_fmt < 4) ? 839 : 139; + //init_prach_tables(N_ZC); //moved to phy_init_lte_ue/eNB, since it takes to long in real-time + + if (prach_fmt < 4) { + prach_root_sequence_map = prach_root_sequence_map0_3; + } else { + // FIXME cannot be reached + prach_root_sequence_map = prach_root_sequence_map4; + } + + +#ifdef PRACH_DEBUG + LOG_I( PHY, "compute_prach_seq: done init prach_tables\n" ); +#endif + + if (highSpeedFlag== 0) { + +#ifdef PRACH_DEBUG + LOG_I(PHY,"Low speed prach : NCS_config %d\n",zeroCorrelationZoneConfig); +#endif + + AssertFatal(zeroCorrelationZoneConfig<=15, + "FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", zeroCorrelationZoneConfig ); + NCS = NCS_unrestricted[zeroCorrelationZoneConfig]; + + num_preambles = (NCS==0) ? 64 : ((64*NCS)/N_ZC); + + if (NCS>0) num_preambles++; + + preamble_offset = 0; + } else { + +#ifdef PRACH_DEBUG + LOG_I( PHY, "high speed prach : NCS_config %"PRIu8"\n", zeroCorrelationZoneConfig ); +#endif + + AssertFatal(zeroCorrelationZoneConfig<=14, + "FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", zeroCorrelationZoneConfig ); + NCS = NCS_restricted[zeroCorrelationZoneConfig]; + fill_du(prach_fmt); + + num_preambles = 64; // compute ZC sequence for 64 possible roots + // find first non-zero shift root (stored in preamble_offset) + not_found = 1; + preamble_offset = 0; + + while (not_found == 1) { + // current root depending on rootSequenceIndex + int index = (rootSequenceIndex + preamble_offset) % N_ZC; + + if (prach_fmt<4) { + // prach_root_sequence_map points to prach_root_sequence_map0_3 + DevAssert( index < sizeof(prach_root_sequence_map0_3) / sizeof(prach_root_sequence_map0_3[0]) ); + } else { + // prach_root_sequence_map points to prach_root_sequence_map4 + DevAssert( index < sizeof(prach_root_sequence_map4) / sizeof(prach_root_sequence_map4[0]) ); + } + + u = prach_root_sequence_map[index]; + + uint16_t n_group_ra = 0; + + if ( (du[u]<(N_ZC/3)) && (du[u]>=NCS) ) { + n_shift_ra = du[u]/NCS; + d_start = (du[u]<<1) + (n_shift_ra * NCS); + n_group_ra = N_ZC/d_start; + n_shift_ra_bar = max(0,(N_ZC-(du[u]<<1)-(n_group_ra*d_start))/N_ZC); + } else if ( (du[u]>=(N_ZC/3)) && (du[u]<=((N_ZC - NCS)>>1)) ) { + n_shift_ra = (N_ZC - (du[u]<<1))/NCS; + d_start = N_ZC - (du[u]<<1) + (n_shift_ra * NCS); + n_group_ra = du[u]/d_start; + n_shift_ra_bar = min(n_shift_ra,max(0,(du[u]- (n_group_ra*d_start))/NCS)); + } else { + n_shift_ra = 0; + n_shift_ra_bar = 0; + } + + // This is the number of cyclic shifts for the current root u + numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar; + + // skip to next root and recompute parameters if numshift==0 + if (numshift>0) + not_found = 0; + else + preamble_offset++; + } + } + +#ifdef PRACH_DEBUG + + if (NCS>0) + LOG_I( PHY, "Initializing %u preambles for PRACH (NCS_config %"PRIu8", NCS %u, N_ZC/NCS %u)\n", + num_preambles, zeroCorrelationZoneConfig, NCS, N_ZC/NCS ); + +#endif + + for (i=0; i<num_preambles; i++) { + int index = (rootSequenceIndex+i+preamble_offset) % N_ZC; + + if (prach_fmt<4) { + // prach_root_sequence_map points to prach_root_sequence_map0_3 + DevAssert( index < sizeof(prach_root_sequence_map0_3) / sizeof(prach_root_sequence_map0_3[0]) ); + } else { + // prach_root_sequence_map points to prach_root_sequence_map4 + DevAssert( index < sizeof(prach_root_sequence_map4) / sizeof(prach_root_sequence_map4[0]) ); + } + + u = prach_root_sequence_map[index]; + + inv_u = ZC_inv[u]; // multiplicative inverse of u + + + // X_u[0] stores the first ZC sequence where the root u has a non-zero number of shifts + // for the unrestricted case X_u[0] is the first root indicated by the rootSequenceIndex + + for (k=0; k<N_ZC; k++) { + // 420 is the multiplicative inverse of 2 (required since ru is exp[j 2\pi n]) + X_u[i][k] = ((uint32_t*)ru)[(((k*(1+(inv_u*k)))%N_ZC)*420)%N_ZC]; + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_OUT); + +} + +void init_prach_tables(int N_ZC) +{ + + int i,m; + + // Compute the modular multiplicative inverse 'iu' of u s.t. iu*u = 1 mod N_ZC + ZC_inv[0] = 0; + ZC_inv[1] = 1; + + for (i=2; i<N_ZC; i++) { + for (m=2; m<N_ZC; m++) + if (((i*m)%N_ZC) == 1) { + ZC_inv[i] = m; + break; + } + +#ifdef PRACH_DEBUG + + if (i<16) + printf("i %d : inv %d\n",i,ZC_inv[i]); + +#endif + } + + // Compute quantized roots of unity + for (i=0; i<N_ZC; i++) { + ru[i<<1] = (int16_t)(floor(32767.0*cos(2*M_PI*(double)i/N_ZC))); + ru[1+(i<<1)] = (int16_t)(floor(32767.0*sin(2*M_PI*(double)i/N_ZC))); +#ifdef PRACH_DEBUG + + if (i<16) + printf("i %d : runity %d,%d\n",i,ru[i<<1],ru[1+(i<<1)]); + +#endif + } +} + diff --git a/openair1/PHY/LTE_TRANSPORT/prach_extern.h b/openair1/PHY/LTE_TRANSPORT/prach_extern.h new file mode 100644 index 0000000000000000000000000000000000000000..2f8a83e24f2a052e3359cd499e8dddf395a5671d --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/prach_extern.h @@ -0,0 +1,93 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/prach_common.c + * \brief Common routines for UE/eNB PRACH physical channel V8.6 2009-03 + * \author R. Knopp + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#include "PHY/sse_intrin.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" + +//#define PRACH_DEBUG 1 +//#define PRACH_WRITE_OUTPUT_DEBUG 1 + +extern uint16_t NCS_unrestricted[16]; +extern uint16_t NCS_restricted[15]; +extern uint16_t NCS_4[7]; + +extern int16_t ru[2*839]; // quantized roots of unity +extern uint32_t ZC_inv[839]; // multiplicative inverse for roots u +extern uint16_t du[838]; + + + +// This is table 5.7.1-4 from 36.211 +extern PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7]; + + + + +extern uint16_t prach_root_sequence_map0_3[838]; + + +extern uint16_t prach_root_sequence_map4[138]; + +void dump_prach_config(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); + + +// This function computes the du +void fill_du(uint8_t prach_fmt); + + +uint8_t get_num_prach_tdd(module_id_t Mod_id); + + +uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index); + + +uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type); + + +uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t prach_ConfigIndex, + uint8_t n_ra_prboffset, + uint8_t tdd_mapindex, uint16_t Nf); + + +int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe); + +int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe); + + +void compute_prach_seq(uint16_t rootSequenceIndex, + uint8_t prach_ConfigIndex, + uint8_t zeroCorrelationZoneConfig, + uint8_t highSpeedFlag, + lte_frame_type_t frame_type, + uint32_t X_u[64][839]); + diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c deleted file mode 100644 index 9e328353a4fdd975b26640822813bd4d5a909846..0000000000000000000000000000000000000000 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ /dev/null @@ -1,804 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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/print_stats.c -* \brief PHY statstic logging function -* \author R. Knopp, F. Kaltenberger, navid nikaein -* \date 2011 -* \version 0.1 -* \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr -* \note -* \warning -*/ - -#include "PHY/LTE_TRANSPORT/proto.h" - -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/extern.h" - -#ifdef OPENAIR2 -#include "../openair2/LAYER2/MAC/proto.h" -#include "../openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#endif - -extern int mac_get_rrc_status(uint8_t Mod_id,uint8_t eNB_flag,uint8_t index); -#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) -#include "common_lib.h" -extern openair0_config_t openair0_cfg[]; -#endif - -int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length, runmode_t mode, int input_level_dBm) -{ - - uint8_t eNB=0; - uint32_t RRC_status; - int len=length; - int harq_pid,round; - - if (ue==NULL) - return 0; - - if ((mode == normal_txrx) || (mode == no_L2_connect)) { - len += sprintf(&buffer[len], "[UE_PROC] UE %d, RNTI %x\n",ue->Mod_id, ue->pdcch_vars[0][0]->crnti); - len += sprintf(&buffer[len],"[UE PROC] RSRP[0] %.2f dBm/RE, RSSI %.2f dBm, RSRQ[0] %.2f dB, N0 %d dBm/RE (NF %.1f dB)\n", - 10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB, - 10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB, - 10*log10(ue->measurements.rsrq[0]), - ue->measurements.n0_power_tot_dBm, - (double)ue->measurements.n0_power_tot_dBm+132.24); - - /* - len += sprintf(&buffer[len], - "[UE PROC] Frame count: %d\neNB0 RSSI %d dBm/RE (%d dB, %d dB)\neNB1 RSSI %d dBm/RE (%d dB, %d dB)neNB2 RSSI %d dBm/RE (%d dB, %d dB)\nN0 %d dBm/RE, %f dBm/%dPRB (%d dB, %d dB)\n", - proc->frame_rx, - ue->measurements.rx_rssi_dBm[0], - ue->measurements.rx_power_dB[0][0], - ue->measurements.rx_power_dB[0][1], - ue->measurements.rx_rssi_dBm[1], - ue->measurements.rx_power_dB[1][0], - ue->measurements.rx_power_dB[1][1], - ue->measurements.rx_rssi_dBm[2], - ue->measurements.rx_power_dB[2][0], - ue->measurements.rx_power_dB[2][1], - ue->measurements.n0_power_tot_dBm, - ue->measurements.n0_power_tot_dBm+10*log10(12*ue->frame_parms.N_RB_DL), - ue->frame_parms.N_RB_DL, - ue->measurements.n0_power_dB[0], - ue->measurements.n0_power_dB[1]); - */ - -#ifdef EXMIMO - len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB (LNA %d, vga %d dB)\n",ue->rx_total_gain_dB, openair0_cfg[0].rxg_mode[0],(int)openair0_cfg[0].rx_gain[0]); -#endif -#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB\n",ue->rx_total_gain_dB); -#endif -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - len += sprintf(&buffer[len], "[UE_PROC] Frequency offset %d Hz, estimated carrier frequency %f Hz\n",ue->common_vars.freq_offset,openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset); -#endif - len += sprintf(&buffer[len], "[UE PROC] UE mode = %s (%d)\n",mode_string[ue->UE_mode[0]],ue->UE_mode[0]); - len += sprintf(&buffer[len], "[UE PROC] timing_advance = %d\n",ue->timing_advance); - if (ue->UE_mode[0]==PUSCH) { - len += sprintf(&buffer[len], "[UE PROC] Po_PUSCH = %d dBm (PL %d dB, Po_NOMINAL_PUSCH %d dBm, PHR %d dB)\n", - ue->ulsch[0]->Po_PUSCH, - get_PL(ue->Mod_id,ue->CC_id,0), - ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH, - ue->ulsch[0]->PHR); - len += sprintf(&buffer[len], "[UE PROC] Po_PUCCH = %d dBm (Po_NOMINAL_PUCCH %d dBm, g_pucch %d dB)\n", - get_PL(ue->Mod_id,ue->CC_id,0)+ - ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+ - ue->dlsch[0][0][0]->g_pucch, - ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, - ue->dlsch[0][0][0]->g_pucch); - } - //for (eNB=0;eNB<NUMBER_OF_eNB_MAX;eNB++) { - for (eNB=0; eNB<1; eNB++) { - len += sprintf(&buffer[len], "[UE PROC] RX spatial power eNB%d: [%d %d; %d %d] dB\n", - eNB, - ue->measurements.rx_spatial_power_dB[eNB][0][0], - ue->measurements.rx_spatial_power_dB[eNB][0][1], - ue->measurements.rx_spatial_power_dB[eNB][1][0], - ue->measurements.rx_spatial_power_dB[eNB][1][1]); - - len += sprintf(&buffer[len], "[UE PROC] RX total power eNB%d: %d dB, avg: %d dB\n",eNB,ue->measurements.rx_power_tot_dB[eNB],ue->measurements.rx_power_avg_dB[eNB]); - len += sprintf(&buffer[len], "[UE PROC] RX total power lin: %d, avg: %d, RX total noise lin: %d, avg: %d\n",ue->measurements.rx_power_tot[eNB], - ue->measurements.rx_power_avg[eNB], ue->measurements.n0_power_tot, ue->measurements.n0_power_avg); - len += sprintf(&buffer[len], "[UE PROC] effective SINR %.2f dB\n",ue->sinr_eff); - len += sprintf(&buffer[len], "[UE PROC] Wideband CQI eNB %d: %d dB, avg: %d dB\n",eNB,ue->measurements.wideband_cqi_tot[eNB],ue->measurements.wideband_cqi_avg[eNB]); - - switch (ue->frame_parms.N_RB_DL) { - case 6: - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 0): [%d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][0][0], - ue->measurements.subband_cqi_dB[eNB][0][1], - ue->measurements.subband_cqi_dB[eNB][0][2], - ue->measurements.subband_cqi_dB[eNB][0][3], - ue->measurements.subband_cqi_dB[eNB][0][4], - ue->measurements.subband_cqi_dB[eNB][0][5]); - - - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 1): [%d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][1][0], - ue->measurements.subband_cqi_dB[eNB][1][1], - ue->measurements.subband_cqi_dB[eNB][1][2], - ue->measurements.subband_cqi_dB[eNB][1][3], - ue->measurements.subband_cqi_dB[eNB][1][4], - ue->measurements.subband_cqi_dB[eNB][1][5]); - - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 0): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][0], - ue->measurements.subband_pmi_im[eNB][0][0], - ue->measurements.subband_pmi_re[eNB][1][0], - ue->measurements.subband_pmi_im[eNB][1][0], - ue->measurements.subband_pmi_re[eNB][2][0], - ue->measurements.subband_pmi_im[eNB][2][0], - ue->measurements.subband_pmi_re[eNB][3][0], - ue->measurements.subband_pmi_im[eNB][3][0], - ue->measurements.subband_pmi_re[eNB][4][0], - ue->measurements.subband_pmi_im[eNB][4][0], - ue->measurements.subband_pmi_re[eNB][5][0], - ue->measurements.subband_pmi_im[eNB][5][0]); - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 1): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][1], - ue->measurements.subband_pmi_im[eNB][0][1], - ue->measurements.subband_pmi_re[eNB][1][1], - ue->measurements.subband_pmi_im[eNB][1][1], - ue->measurements.subband_pmi_re[eNB][2][1], - ue->measurements.subband_pmi_im[eNB][2][1], - ue->measurements.subband_pmi_re[eNB][3][1], - ue->measurements.subband_pmi_im[eNB][3][1], - ue->measurements.subband_pmi_re[eNB][4][1], - ue->measurements.subband_pmi_im[eNB][4][1], - ue->measurements.subband_pmi_re[eNB][5][1], - ue->measurements.subband_pmi_im[eNB][5][1]); - - len += sprintf(&buffer[len], "[UE PROC] PMI Antenna selection eNB%d : [%d %d %d %d %d %d]\n", - eNB, - ue->measurements.selected_rx_antennas[eNB][0], - ue->measurements.selected_rx_antennas[eNB][1], - ue->measurements.selected_rx_antennas[eNB][2], - ue->measurements.selected_rx_antennas[eNB][3], - ue->measurements.selected_rx_antennas[eNB][4], - ue->measurements.selected_rx_antennas[eNB][5]); - - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (max): %jx\n",eNB,pmi2hex_2Ar1(quantize_subband_pmi(&ue->measurements,eNB,6))); - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (both): %jx,%jx\n",eNB, - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,0,6)), - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,1,6))); - break; - - case 25: - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 0): [%d %d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][0][0], - ue->measurements.subband_cqi_dB[eNB][0][1], - ue->measurements.subband_cqi_dB[eNB][0][2], - ue->measurements.subband_cqi_dB[eNB][0][3], - ue->measurements.subband_cqi_dB[eNB][0][4], - ue->measurements.subband_cqi_dB[eNB][0][5], - ue->measurements.subband_cqi_dB[eNB][0][6]); - - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 1): [%d %d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][1][0], - ue->measurements.subband_cqi_dB[eNB][1][1], - ue->measurements.subband_cqi_dB[eNB][1][2], - ue->measurements.subband_cqi_dB[eNB][1][3], - ue->measurements.subband_cqi_dB[eNB][1][4], - ue->measurements.subband_cqi_dB[eNB][1][5], - ue->measurements.subband_cqi_dB[eNB][1][6]); - - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 0): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][0], - ue->measurements.subband_pmi_im[eNB][0][0], - ue->measurements.subband_pmi_re[eNB][1][0], - ue->measurements.subband_pmi_im[eNB][1][0], - ue->measurements.subband_pmi_re[eNB][2][0], - ue->measurements.subband_pmi_im[eNB][2][0], - ue->measurements.subband_pmi_re[eNB][3][0], - ue->measurements.subband_pmi_im[eNB][3][0], - ue->measurements.subband_pmi_re[eNB][4][0], - ue->measurements.subband_pmi_im[eNB][4][0], - ue->measurements.subband_pmi_re[eNB][5][0], - ue->measurements.subband_pmi_im[eNB][5][0], - ue->measurements.subband_pmi_re[eNB][6][0], - ue->measurements.subband_pmi_im[eNB][6][0]); - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 1): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][1], - ue->measurements.subband_pmi_im[eNB][0][1], - ue->measurements.subband_pmi_re[eNB][1][1], - ue->measurements.subband_pmi_im[eNB][1][1], - ue->measurements.subband_pmi_re[eNB][2][1], - ue->measurements.subband_pmi_im[eNB][2][1], - ue->measurements.subband_pmi_re[eNB][3][1], - ue->measurements.subband_pmi_im[eNB][3][1], - ue->measurements.subband_pmi_re[eNB][4][1], - ue->measurements.subband_pmi_im[eNB][4][1], - ue->measurements.subband_pmi_re[eNB][5][1], - ue->measurements.subband_pmi_im[eNB][5][1], - ue->measurements.subband_pmi_re[eNB][6][1], - ue->measurements.subband_pmi_im[eNB][6][1]); - - len += sprintf(&buffer[len], "[UE PROC] PMI Antenna selection eNB%d : [%d %d %d %d %d %d %d]\n", - eNB, - ue->measurements.selected_rx_antennas[eNB][0], - ue->measurements.selected_rx_antennas[eNB][1], - ue->measurements.selected_rx_antennas[eNB][2], - ue->measurements.selected_rx_antennas[eNB][3], - ue->measurements.selected_rx_antennas[eNB][4], - ue->measurements.selected_rx_antennas[eNB][5], - ue->measurements.selected_rx_antennas[eNB][6]); - - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (max): %jx\n",eNB,pmi2hex_2Ar1(quantize_subband_pmi(&ue->measurements,eNB,7))); - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (both): %jx,%jx\n",eNB, - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,0,7)), - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,1,7))); - break; - - case 50: - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 0): [%d %d %d %d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][0][0], - ue->measurements.subband_cqi_dB[eNB][0][1], - ue->measurements.subband_cqi_dB[eNB][0][2], - ue->measurements.subband_cqi_dB[eNB][0][3], - ue->measurements.subband_cqi_dB[eNB][0][4], - ue->measurements.subband_cqi_dB[eNB][0][5], - ue->measurements.subband_cqi_dB[eNB][0][6], - ue->measurements.subband_cqi_dB[eNB][0][7], - ue->measurements.subband_cqi_dB[eNB][0][8]); - - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 1): [%d %d %d %d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][1][0], - ue->measurements.subband_cqi_dB[eNB][1][1], - ue->measurements.subband_cqi_dB[eNB][1][2], - ue->measurements.subband_cqi_dB[eNB][1][3], - ue->measurements.subband_cqi_dB[eNB][1][4], - ue->measurements.subband_cqi_dB[eNB][1][5], - ue->measurements.subband_cqi_dB[eNB][1][6], - ue->measurements.subband_cqi_dB[eNB][1][7], - ue->measurements.subband_cqi_dB[eNB][1][8]); - - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 0): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][0], - ue->measurements.subband_pmi_im[eNB][0][0], - ue->measurements.subband_pmi_re[eNB][1][0], - ue->measurements.subband_pmi_im[eNB][1][0], - ue->measurements.subband_pmi_re[eNB][2][0], - ue->measurements.subband_pmi_im[eNB][2][0], - ue->measurements.subband_pmi_re[eNB][3][0], - ue->measurements.subband_pmi_im[eNB][3][0], - ue->measurements.subband_pmi_re[eNB][4][0], - ue->measurements.subband_pmi_im[eNB][4][0], - ue->measurements.subband_pmi_re[eNB][5][0], - ue->measurements.subband_pmi_im[eNB][5][0], - ue->measurements.subband_pmi_re[eNB][6][0], - ue->measurements.subband_pmi_im[eNB][6][0], - ue->measurements.subband_pmi_re[eNB][7][0], - ue->measurements.subband_pmi_im[eNB][7][0], - ue->measurements.subband_pmi_re[eNB][8][0], - ue->measurements.subband_pmi_im[eNB][8][0]); - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 1): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][1], - ue->measurements.subband_pmi_im[eNB][0][1], - ue->measurements.subband_pmi_re[eNB][1][1], - ue->measurements.subband_pmi_im[eNB][1][1], - ue->measurements.subband_pmi_re[eNB][2][1], - ue->measurements.subband_pmi_im[eNB][2][1], - ue->measurements.subband_pmi_re[eNB][3][1], - ue->measurements.subband_pmi_im[eNB][3][1], - ue->measurements.subband_pmi_re[eNB][4][1], - ue->measurements.subband_pmi_im[eNB][4][1], - ue->measurements.subband_pmi_re[eNB][5][1], - ue->measurements.subband_pmi_im[eNB][5][1], - ue->measurements.subband_pmi_re[eNB][6][1], - ue->measurements.subband_pmi_im[eNB][6][1], - ue->measurements.subband_pmi_re[eNB][7][1], - ue->measurements.subband_pmi_im[eNB][7][1], - ue->measurements.subband_pmi_re[eNB][8][1], - ue->measurements.subband_pmi_im[eNB][8][1]); - - len += sprintf(&buffer[len], "[UE PROC] PMI Antenna selection eNB%d : [%d %d %d %d %d %d %d %d %d]\n", - eNB, - ue->measurements.selected_rx_antennas[eNB][0], - ue->measurements.selected_rx_antennas[eNB][1], - ue->measurements.selected_rx_antennas[eNB][2], - ue->measurements.selected_rx_antennas[eNB][3], - ue->measurements.selected_rx_antennas[eNB][4], - ue->measurements.selected_rx_antennas[eNB][5], - ue->measurements.selected_rx_antennas[eNB][6], - ue->measurements.selected_rx_antennas[eNB][7], - ue->measurements.selected_rx_antennas[eNB][8]); - - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (max): %jx\n",eNB,pmi2hex_2Ar1(quantize_subband_pmi(&ue->measurements,eNB,9))); - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (both): %jx,%jx\n",eNB, - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,0,9)), - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,1,9))); - break; - - case 100: - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 0): [%d %d %d %d %d %d %d %d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][0][0], - ue->measurements.subband_cqi_dB[eNB][0][1], - ue->measurements.subband_cqi_dB[eNB][0][2], - ue->measurements.subband_cqi_dB[eNB][0][3], - ue->measurements.subband_cqi_dB[eNB][0][4], - ue->measurements.subband_cqi_dB[eNB][0][5], - ue->measurements.subband_cqi_dB[eNB][0][6], - ue->measurements.subband_cqi_dB[eNB][0][7], - ue->measurements.subband_cqi_dB[eNB][0][8], - ue->measurements.subband_cqi_dB[eNB][0][9], - ue->measurements.subband_cqi_dB[eNB][0][10], - ue->measurements.subband_cqi_dB[eNB][0][11], - ue->measurements.subband_cqi_dB[eNB][0][12]); - - len += sprintf(&buffer[len], "[UE PROC] Subband CQI eNB%d (Ant 1): [%d %d %d %d %d %d %d %d %d %d %d %d %d] dB\n", - eNB, - ue->measurements.subband_cqi_dB[eNB][1][0], - ue->measurements.subband_cqi_dB[eNB][1][1], - ue->measurements.subband_cqi_dB[eNB][1][2], - ue->measurements.subband_cqi_dB[eNB][1][3], - ue->measurements.subband_cqi_dB[eNB][1][4], - ue->measurements.subband_cqi_dB[eNB][1][5], - ue->measurements.subband_cqi_dB[eNB][1][6], - ue->measurements.subband_cqi_dB[eNB][1][7], - ue->measurements.subband_cqi_dB[eNB][1][8], - ue->measurements.subband_cqi_dB[eNB][1][9], - ue->measurements.subband_cqi_dB[eNB][1][10], - ue->measurements.subband_cqi_dB[eNB][1][11], - ue->measurements.subband_cqi_dB[eNB][1][12]); - - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 0): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][0], - ue->measurements.subband_pmi_im[eNB][0][0], - ue->measurements.subband_pmi_re[eNB][1][0], - ue->measurements.subband_pmi_im[eNB][1][0], - ue->measurements.subband_pmi_re[eNB][2][0], - ue->measurements.subband_pmi_im[eNB][2][0], - ue->measurements.subband_pmi_re[eNB][3][0], - ue->measurements.subband_pmi_im[eNB][3][0], - ue->measurements.subband_pmi_re[eNB][4][0], - ue->measurements.subband_pmi_im[eNB][4][0], - ue->measurements.subband_pmi_re[eNB][5][0], - ue->measurements.subband_pmi_im[eNB][5][0], - ue->measurements.subband_pmi_re[eNB][6][0], - ue->measurements.subband_pmi_im[eNB][6][0], - ue->measurements.subband_pmi_re[eNB][7][0], - ue->measurements.subband_pmi_im[eNB][7][0], - ue->measurements.subband_pmi_re[eNB][8][0], - ue->measurements.subband_pmi_im[eNB][8][0], - ue->measurements.subband_pmi_re[eNB][9][0], - ue->measurements.subband_pmi_im[eNB][9][0], - ue->measurements.subband_pmi_re[eNB][10][0], - ue->measurements.subband_pmi_im[eNB][10][0], - ue->measurements.subband_pmi_re[eNB][11][0], - ue->measurements.subband_pmi_im[eNB][11][0], - ue->measurements.subband_pmi_re[eNB][12][0], - ue->measurements.subband_pmi_im[eNB][12][0]); - - len += sprintf(&buffer[len], "[UE PROC] Subband PMI eNB%d (Ant 1): [(%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d) (%d %d)]\n", - eNB, - ue->measurements.subband_pmi_re[eNB][0][1], - ue->measurements.subband_pmi_im[eNB][0][1], - ue->measurements.subband_pmi_re[eNB][1][1], - ue->measurements.subband_pmi_im[eNB][1][1], - ue->measurements.subband_pmi_re[eNB][2][1], - ue->measurements.subband_pmi_im[eNB][2][1], - ue->measurements.subband_pmi_re[eNB][3][1], - ue->measurements.subband_pmi_im[eNB][3][1], - ue->measurements.subband_pmi_re[eNB][4][1], - ue->measurements.subband_pmi_im[eNB][4][1], - ue->measurements.subband_pmi_re[eNB][5][1], - ue->measurements.subband_pmi_im[eNB][5][1], - ue->measurements.subband_pmi_re[eNB][6][1], - ue->measurements.subband_pmi_im[eNB][6][1], - ue->measurements.subband_pmi_re[eNB][7][1], - ue->measurements.subband_pmi_im[eNB][7][1], - ue->measurements.subband_pmi_re[eNB][8][1], - ue->measurements.subband_pmi_im[eNB][8][1], - ue->measurements.subband_pmi_re[eNB][9][1], - ue->measurements.subband_pmi_im[eNB][9][1], - ue->measurements.subband_pmi_re[eNB][10][1], - ue->measurements.subband_pmi_im[eNB][10][1], - ue->measurements.subband_pmi_re[eNB][11][1], - ue->measurements.subband_pmi_im[eNB][11][1], - ue->measurements.subband_pmi_re[eNB][12][1], - ue->measurements.subband_pmi_im[eNB][12][1]); - - len += sprintf(&buffer[len], "[UE PROC] PMI Antenna selection eNB%d : [%d %d %d %d %d %d %d %d %d %d %d %d %d]\n", - eNB, - ue->measurements.selected_rx_antennas[eNB][0], - ue->measurements.selected_rx_antennas[eNB][1], - ue->measurements.selected_rx_antennas[eNB][2], - ue->measurements.selected_rx_antennas[eNB][3], - ue->measurements.selected_rx_antennas[eNB][4], - ue->measurements.selected_rx_antennas[eNB][5], - ue->measurements.selected_rx_antennas[eNB][6], - ue->measurements.selected_rx_antennas[eNB][7], - ue->measurements.selected_rx_antennas[eNB][8], - ue->measurements.selected_rx_antennas[eNB][9], - ue->measurements.selected_rx_antennas[eNB][10], - ue->measurements.selected_rx_antennas[eNB][11], - ue->measurements.selected_rx_antennas[eNB][12]); - - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (max): %jx\n",eNB,pmi2hex_2Ar1(quantize_subband_pmi(&ue->measurements,eNB,13))); - len += sprintf(&buffer[len], "[UE PROC] Quantized PMI eNB %d (both): %jx,%jx\n",eNB, - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,0,13)), - pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,1,13))); - break; - } - -#ifdef OPENAIR2 - RRC_status = mac_UE_get_rrc_status(ue->Mod_id, 0); - len += sprintf(&buffer[len],"[UE PROC] RRC status = %d\n",RRC_status); -#endif - - - len += sprintf(&buffer[len], "[UE PROC] Transmission Mode %d \n",ue->transmission_mode[eNB]); - len += sprintf(&buffer[len], "[UE PROC] PBCH err conseq %d, PBCH error total %d, PBCH FER %d\n", - ue->pbch_vars[eNB]->pdu_errors_conseq, - ue->pbch_vars[eNB]->pdu_errors, - ue->pbch_vars[eNB]->pdu_fer); - - if (ue->transmission_mode[eNB] == 6) - len += sprintf(&buffer[len], "[UE PROC] Mode 6 Wideband CQI eNB %d : %d dB\n",eNB,ue->measurements.precoded_cqi_dB[eNB][0]); - - for (harq_pid=0;harq_pid<8;harq_pid++) { - len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 0 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][0][0]->harq_processes[harq_pid]->mcs); - for (round=0;round<8;round++) - len+=sprintf(&buffer[len],"%d/%d ", - ue->dlsch[0][0][0]->harq_processes[harq_pid]->errors[round], - ue->dlsch[0][0][0]->harq_processes[harq_pid]->trials[round]); - len+=sprintf(&buffer[len],"\n"); - } - if (ue->dlsch[0][0] && ue->dlsch[0][0][0] && ue->dlsch[0][0][1]) { - len += sprintf(&buffer[len], "[UE PROC] Saved PMI for DLSCH eNB %d : %jx (%p)\n",eNB,pmi2hex_2Ar1(ue->dlsch[0][0][0]->pmi_alloc),ue->dlsch[0][0][0]); - - len += sprintf(&buffer[len], "[UE PROC] eNB %d: dl_power_off = %d\n",eNB,ue->dlsch[0][0][0]->harq_processes[0]->dl_power_off); - - for (harq_pid=0;harq_pid<8;harq_pid++) { - len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 1 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][0][1]->harq_processes[0]->mcs); - for (round=0;round<8;round++) - len+=sprintf(&buffer[len],"%d/%d ", - ue->dlsch[0][0][1]->harq_processes[harq_pid]->errors[round], - ue->dlsch[0][0][1]->harq_processes[harq_pid]->trials[round]); - len+=sprintf(&buffer[len],"\n"); - } - } - - len += sprintf(&buffer[len], "[UE PROC] DLSCH Total %d, Error %d, FER %d\n",ue->dlsch_received[0],ue->dlsch_errors[0],ue->dlsch_fer[0]); - len += sprintf(&buffer[len], "[UE PROC] DLSCH (SI) Total %d, Error %d\n",ue->dlsch_SI_received[0],ue->dlsch_SI_errors[0]); - len += sprintf(&buffer[len], "[UE PROC] DLSCH (RA) Total %d, Error %d\n",ue->dlsch_ra_received[0],ue->dlsch_ra_errors[0]); -#if defined(Rel10) || defined(Rel14) - int i=0; - - //len += sprintf(&buffer[len], "[UE PROC] MCH Total %d\n", ue->dlsch_mch_received[0]); - for(i=0; i <ue->frame_parms.num_MBSFN_config; i++ ) { - len += sprintf(&buffer[len], "[UE PROC] MCH (MCCH MBSFN %d) Total %d, Error %d, Trials %d\n", - i, ue->dlsch_mcch_received[i][0],ue->dlsch_mcch_errors[i][0],ue->dlsch_mcch_trials[i][0]); - len += sprintf(&buffer[len], "[UE PROC] MCH (MTCH MBSFN %d) Total %d, Error %d, Trials %d\n", - i, ue->dlsch_mtch_received[i][0],ue->dlsch_mtch_errors[i][0],ue->dlsch_mtch_trials[i][0]); - } - -#endif - len += sprintf(&buffer[len], "[UE PROC] DLSCH Bitrate %dkbps\n",(ue->bitrate[0]/1000)); - len += sprintf(&buffer[len], "[UE PROC] Total Received Bits %dkbits\n",(ue->total_received_bits[0]/1000)); - len += sprintf(&buffer[len], "[UE PROC] IA receiver %d\n",ue->use_ia_receiver); - - } - - } else { - len += sprintf(&buffer[len], "[UE PROC] Frame count: %d, RSSI %3.2f dB (%d dB, %d dB), N0 %3.2f dB (%d dB, %d dB)\n", - proc->frame_rx, - 10*log10(ue->measurements.rssi), - ue->measurements.rx_power_dB[0][0], - ue->measurements.rx_power_dB[0][1], - 10*log10(ue->measurements.n0_power_tot), - ue->measurements.n0_power_dB[0], - ue->measurements.n0_power_dB[1]); -#ifdef EXMIMO - ue->rx_total_gain_dB = ((int)(10*log10(ue->measurements.rssi)))-input_level_dBm; - len += sprintf(&buffer[len], "[UE PROC] rxg_mode %d, input level (set by user) %d dBm, VGA gain %d dB ==> total gain %3.2f dB, noise figure %3.2f dB\n", - openair0_cfg[0].rxg_mode[0], - input_level_dBm, - (int)openair0_cfg[0].rx_gain[0], - 10*log10(ue->measurements.rssi)-input_level_dBm, - 10*log10(ue->measurements.n0_power_tot)-ue->rx_total_gain_dB+105); -#endif - } - - len += sprintf(&buffer[len],"EOF\n"); - - return len; -} // is_clusterhead - -/* -int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length) -{ - - unsigned int success=0; - uint8_t eNB_id,UE_id,i,j,number_of_cards_l=1; - uint32_t ulsch_errors=0,dlsch_errors=0; - uint32_t ulsch_round_attempts[4]= {0,0,0,0},ulsch_round_errors[4]= {0,0,0,0}; - uint32_t dlsch_round_attempts[4]= {0,0,0,0},dlsch_round_errors[4]= {0,0,0,0}; - uint32_t UE_id_mac, RRC_status; - eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0]; - if (eNB==NULL) - return 0; - - int len = length; - - // if(eNB->frame==0){ - eNB->total_dlsch_bitrate = 0;//eNB->UE_stats[UE_id].dlsch_bitrate + eNB->total_dlsch_bitrate; - eNB->total_transmitted_bits = 0;// eNB->UE_stats[UE_id].total_transmitted_bits + eNB->total_transmitted_bits; - eNB->total_system_throughput = 0;//eNB->UE_stats[UE_id].total_transmitted_bits + eNB->total_system_throughput; - // } - - for (eNB_id=0; eNB_id<number_of_cards_l; eNB_id++) { - len += sprintf(&buffer[len],"eNB %d/%d Frame %d: RX Gain %d dB, I0 %d dBm (%d,%d) dB \n", - eNB_id,number_of_cards_l, - proc->frame_tx, - eNB->rx_total_gain_dB, - eNB->measurements.n0_power_tot_dBm, - eNB->measurements.n0_power_dB[0], - eNB->measurements.n0_power_dB[1]); - - len += sprintf(&buffer[len],"PRB I0 (%X.%X.%X.%X): ", - eNB->rb_mask_ul[0], - eNB->rb_mask_ul[1],eNB->rb_mask_ul[2],eNB->rb_mask_ul[3]); - - for (i=0; i<eNB->frame_parms.N_RB_UL; i++) { - len += sprintf(&buffer[len],"%4d ", - eNB->measurements.n0_subband_power_tot_dBm[i]); - if ((i>0) && ((i%25) == 0)) - len += sprintf(&buffer[len],"\n"); - } - len += sprintf(&buffer[len],"\n"); - len += sprintf(&buffer[len],"\nPERFORMANCE PARAMETERS\n"); - - for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { - if (eNB && - (eNB->dlsch!=NULL) && - (eNB->dlsch[(uint8_t)UE_id]!=NULL) && - (eNB->dlsch[(uint8_t)UE_id][0]->rnti>0)&& - (eNB->UE_stats[UE_id].mode == PUSCH)) { - - eNB->total_dlsch_bitrate = eNB->UE_stats[UE_id].dlsch_bitrate + eNB->total_dlsch_bitrate; - eNB->total_transmitted_bits = eNB->UE_stats[UE_id].total_TBS + eNB->total_transmitted_bits; - - //eNB->total_system_throughput = eNB->UE_stats[UE_id].total_transmitted_bits + eNB->total_system_throughput; - - for (i=0; i<8; i++) - success = success + (eNB->UE_stats[UE_id].dlsch_trials[i][0] - eNB->UE_stats[UE_id].dlsch_l2_errors[i]); - - - - len += sprintf(&buffer[len],"Total DLSCH %d kbits / %d frames ",(eNB->total_transmitted_bits/1000),proc->frame_tx+1); - len += sprintf(&buffer[len],"Total DLSCH throughput %d kbps ",(eNB->total_dlsch_bitrate/1000)); - len += sprintf(&buffer[len],"Total DLSCH trans %d / %d frames\n",success,proc->frame_tx+1); - //len += sprintf(&buffer[len],"[eNB PROC] FULL MU-MIMO Transmissions/Total Transmissions = %d/%d\n",eNB->FULL_MUMIMO_transmissions,eNB->check_for_total_transmissions); - //len += sprintf(&buffer[len],"[eNB PROC] MU-MIMO Transmissions/Total Transmissions = %d/%d\n",eNB->check_for_MUMIMO_transmissions,eNB->check_for_total_transmissions); - //len += sprintf(&buffer[len],"[eNB PROC] SU-MIMO Transmissions/Total Transmissions = %d/%d\n",eNB->check_for_SUMIMO_transmissions,eNB->check_for_total_transmissions); - - len += sprintf(&buffer[len],"UE %d (%x) Power: (%d,%d) dB, Po_PUSCH: (%d,%d) dBm, Po_PUCCH (%d/%d) dBm, Po_PUCCH1 (%d,%d) dBm, PUCCH1 Thres %d dBm \n", - UE_id, - eNB->UE_stats[UE_id].crnti, - dB_fixed(eNB->pusch_vars[UE_id]->ulsch_power[0]), - dB_fixed(eNB->pusch_vars[UE_id]->ulsch_power[1]), - eNB->UE_stats[UE_id].UL_rssi[0], - eNB->UE_stats[UE_id].UL_rssi[1], - dB_fixed(eNB->UE_stats[UE_id].Po_PUCCH/eNB->frame_parms.N_RB_UL)-eNB->rx_total_gain_dB, - eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, - dB_fixed(eNB->UE_stats[UE_id].Po_PUCCH1_below/eNB->frame_parms.N_RB_UL)-eNB->rx_total_gain_dB, - dB_fixed(eNB->UE_stats[UE_id].Po_PUCCH1_above/eNB->frame_parms.N_RB_UL)-eNB->rx_total_gain_dB, - PUCCH1_THRES+eNB->measurements.n0_power_tot_dBm-dB_fixed(eNB->frame_parms.N_RB_UL)); - - len+= sprintf(&buffer[len],"DL mcs %d, UL mcs %d, UL rb %d, delta_TF %d, ", - eNB->dlsch[(uint8_t)UE_id][0]->harq_processes[0]->mcs, - eNB->ulsch[(uint8_t)UE_id]->harq_processes[0]->mcs, - eNB->ulsch[(uint8_t)UE_id]->harq_processes[0]->nb_rb, - eNB->ulsch[(uint8_t)UE_id]->harq_processes[0]->delta_TF); - - len += sprintf(&buffer[len],"Wideband CQI: (%d,%d) dB\n", - eNB->measurements.wideband_cqi_dB[UE_id][0], - eNB->measurements.wideband_cqi_dB[UE_id][1]); - - len += sprintf(&buffer[len],"DL TM %d, DL_cqi %d, DL_pmi_single %jx ", - eNB->transmission_mode[UE_id], - eNB->UE_stats[UE_id].DL_cqi[0], - pmi2hex_2Ar1(eNB->UE_stats[UE_id].DL_pmi_single)); - - len += sprintf(&buffer[len],"Timing advance %d samples (%d 16Ts), update %d ", - eNB->UE_stats[UE_id].UE_timing_offset, - eNB->UE_stats[UE_id].UE_timing_offset>>2, - eNB->UE_stats[UE_id].timing_advance_update); - - len += sprintf(&buffer[len],"Mode = %s(%d) ", - mode_string[eNB->UE_stats[UE_id].mode], - eNB->UE_stats[UE_id].mode); - UE_id_mac = find_UE_id(eNB->Mod_id,eNB->dlsch[(uint8_t)UE_id][0]->rnti); - - if (UE_id_mac != -1) { - RRC_status = mac_eNB_get_rrc_status(eNB->Mod_id,eNB->dlsch[(uint8_t)UE_id][0]->rnti); - len += sprintf(&buffer[len],"UE_id_mac = %d, RRC status = %d\n",UE_id_mac,RRC_status); - } else - len += sprintf(&buffer[len],"UE_id_mac = -1\n"); - - len += sprintf(&buffer[len],"SR received/total: %d/%d (diff %d)\n", - eNB->UE_stats[UE_id].sr_received, - eNB->UE_stats[UE_id].sr_total, - eNB->UE_stats[UE_id].sr_total-eNB->UE_stats[UE_id].sr_received); - - len += sprintf(&buffer[len],"DL Subband CQI: "); - - int nb_sb; - switch (eNB->frame_parms.N_RB_DL) { - case 6: - nb_sb=0; - break; - case 15: - nb_sb = 4; - case 25: - nb_sb = 7; - break; - case 50: - nb_sb = 9; - break; - case 75: - nb_sb = 10; - break; - case 100: - nb_sb = 13; - break; - default: - nb_sb=0; - break; - } - for (i=0; i<nb_sb; i++) - len += sprintf(&buffer[len],"%2d ", - eNB->UE_stats[UE_id].DL_subband_cqi[0][i]); - len += sprintf(&buffer[len],"\n"); - - - - ulsch_errors = 0; - - for (j=0; j<4; j++) { - ulsch_round_attempts[j]=0; - ulsch_round_errors[j]=0; - } - - len += sprintf(&buffer[len],"ULSCH errors/attempts per harq (per round): \n"); - - for (i=0; i<8; i++) { - len += sprintf(&buffer[len]," harq %d: %d/%d (fer %d) (%d/%d, %d/%d, %d/%d, %d/%d) ", - i, - eNB->UE_stats[UE_id].ulsch_errors[i], - eNB->UE_stats[UE_id].ulsch_decoding_attempts[i][0], - eNB->UE_stats[UE_id].ulsch_round_fer[i][0], - eNB->UE_stats[UE_id].ulsch_round_errors[i][0], - eNB->UE_stats[UE_id].ulsch_decoding_attempts[i][0], - eNB->UE_stats[UE_id].ulsch_round_errors[i][1], - eNB->UE_stats[UE_id].ulsch_decoding_attempts[i][1], - eNB->UE_stats[UE_id].ulsch_round_errors[i][2], - eNB->UE_stats[UE_id].ulsch_decoding_attempts[i][2], - eNB->UE_stats[UE_id].ulsch_round_errors[i][3], - eNB->UE_stats[UE_id].ulsch_decoding_attempts[i][3]); - if ((i&1) == 1) - len += sprintf(&buffer[len],"\n"); - - ulsch_errors+=eNB->UE_stats[UE_id].ulsch_errors[i]; - - for (j=0; j<4; j++) { - ulsch_round_attempts[j]+=eNB->UE_stats[UE_id].ulsch_decoding_attempts[i][j]; - ulsch_round_errors[j]+=eNB->UE_stats[UE_id].ulsch_round_errors[i][j]; - } - } - - len += sprintf(&buffer[len],"ULSCH errors/attempts total %d/%d (%d/%d, %d/%d, %d/%d, %d/%d)\n", - ulsch_errors,ulsch_round_attempts[0], - - ulsch_round_errors[0],ulsch_round_attempts[0], - ulsch_round_errors[1],ulsch_round_attempts[1], - ulsch_round_errors[2],ulsch_round_attempts[2], - ulsch_round_errors[3],ulsch_round_attempts[3]); - - dlsch_errors = 0; - - for (j=0; j<4; j++) { - dlsch_round_attempts[j]=0; - dlsch_round_errors[j]=0; - } - - len += sprintf(&buffer[len],"DLSCH errors/attempts per harq (per round): \n"); - - for (i=0; i<8; i++) { - len += sprintf(&buffer[len]," harq %d: %d/%d (%d/%d/%d, %d/%d/%d, %d/%d/%d, %d/%d/%d) ", - i, - eNB->UE_stats[UE_id].dlsch_l2_errors[i], - eNB->UE_stats[UE_id].dlsch_trials[i][0], - eNB->UE_stats[UE_id].dlsch_ACK[i][0], - eNB->UE_stats[UE_id].dlsch_NAK[i][0], - eNB->UE_stats[UE_id].dlsch_trials[i][0], - eNB->UE_stats[UE_id].dlsch_ACK[i][1], - eNB->UE_stats[UE_id].dlsch_NAK[i][1], - eNB->UE_stats[UE_id].dlsch_trials[i][1], - eNB->UE_stats[UE_id].dlsch_ACK[i][2], - eNB->UE_stats[UE_id].dlsch_NAK[i][2], - eNB->UE_stats[UE_id].dlsch_trials[i][2], - eNB->UE_stats[UE_id].dlsch_ACK[i][3], - eNB->UE_stats[UE_id].dlsch_NAK[i][3], - eNB->UE_stats[UE_id].dlsch_trials[i][3]); - if ((i&1) == 1) - len += sprintf(&buffer[len],"\n"); - - - dlsch_errors+=eNB->UE_stats[UE_id].dlsch_l2_errors[i]; - - for (j=0; j<4; j++) { - dlsch_round_attempts[j]+=eNB->UE_stats[UE_id].dlsch_trials[i][j]; - dlsch_round_errors[j]+=eNB->UE_stats[UE_id].dlsch_NAK[i][j]; - } - } - - len += sprintf(&buffer[len],"DLSCH errors/attempts total %d/%d (%d/%d, %d/%d, %d/%d, %d/%d): \n", - dlsch_errors,dlsch_round_attempts[0], - dlsch_round_errors[0],dlsch_round_attempts[0], - dlsch_round_errors[1],dlsch_round_attempts[1], - dlsch_round_errors[2],dlsch_round_attempts[2], - dlsch_round_errors[3],dlsch_round_attempts[3]); - - - len += sprintf(&buffer[len],"DLSCH total bits from MAC: %dkbit ",(eNB->UE_stats[UE_id].total_TBS_MAC)/1000); - len += sprintf(&buffer[len],"DLSCH total bits ack'ed: %dkbit ",(eNB->UE_stats[UE_id].total_TBS)/1000); - len += sprintf(&buffer[len],"DLSCH Average throughput (100 frames): %dkbps\n",(eNB->UE_stats[UE_id].dlsch_bitrate/1000)); - // len += sprintf(&buffer[len],"[eNB PROC] Transmission Mode %d\n",eNB->transmission_mode[UE_id]); - } - } - - len += sprintf(&buffer[len],"\n"); - } - - len += sprintf(&buffer[len],"EOF\n"); - - return len; -} -*/ diff --git a/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..d8b17ff26386e5f825c514faee7d8a0cbfbae331 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h @@ -0,0 +1,362 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/proto.h + * \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03 + * \author R. Knopp, F. Kaltenberger + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_PROTO_NB_IOT__H__ +#define __LTE_TRANSPORT_PROTO_NB_IOT__H__ +#include "PHY/defs_L1_NB_IoT.h" +//#include <math.h> + +//NPSS + +int generate_npss_NB_IoT(int32_t **txdataF, + short amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + unsigned short symbol_offset, // symbol_offset should equal to 3 for NB-IoT + unsigned short slot_offset, + unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE + +//NSSS + +int generate_sss_NB_IoT(int32_t **txdataF, + int16_t amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint16_t symbol_offset, // symbol_offset = 3 for NB-IoT + uint16_t slot_offset, + unsigned short frame_number, // new attribute (Get value from higher layer), it does not exist for LTE + unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE + +//*****************Vincent part for Cell ID estimation from NSSS ******************// + +int rx_nsss_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int32_t *tot_metric); + +int nsss_extract_NB_IoT(PHY_VARS_UE_NB_IoT *ue, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **nsss_ext, + int l); + +//NRS + +void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + int32_t **txdataF, + int16_t amp, + uint16_t Ntti, // Ntti = 10 + unsigned short RB_IoT_ID, // RB reserved for NB-IoT + unsigned short With_NSSS); // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal + + +//NPBCH + +int allocate_npbch_REs_in_RB(NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **txdataF, + uint32_t *jj, + uint32_t symbol_offset, + uint8_t *x0, + uint8_t pilots, + int16_t amp, + unsigned short id_offset, + uint32_t *re_allocated); + + +int generate_npbch(NB_IoT_eNB_NPBCH_t *eNB_npbch, + int32_t **txdataF, + int amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t *npbch_pdu, + uint8_t frame_mod64, + unsigned short NB_IoT_RB_ID); + + +void npbch_scrambling(NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t *npbch_e, + uint32_t length); + +// Functions below implement 36-211 and 36-212 + +/*Function to pack the DCI*/ +// newly added function for NB-IoT , does not exist for LTE +void add_dci_NB_IoT(DCI_PDU_NB_IoT *DCI_pdu, + void *pdu, + rnti_t rnti, + unsigned char dci_size_bytes, + unsigned char aggregation, + unsigned char dci_size_bits, + unsigned char dci_fmt, + uint8_t npdcch_start_symbol); + + +/*Use the UL DCI Information to configure PHY and also Pack the DCI*/ +int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + DCI_CONTENT *DCI_Content, + uint16_t rnti, + DCI_format_NB_IoT_t dci_format, + uint8_t UE_id, + uint8_t aggregation, + uint8_t npdcch_start_symbol); + + +/*Use the DL DCI Information to configure PHY and also Pack the DCI*/ +int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + int frame, + uint8_t subframe, + DCI_CONTENT *DCI_Content, + uint16_t rnti, + DCI_format_NB_IoT_t dci_format, + NB_IoT_eNB_NDLSCH_t *ndlsch, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t aggregation, + uint8_t npdcch_start_symbol); + + +/*Function for DCI encoding, scrambling, modulation*/ +uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t *npdcch, + uint8_t Num_dci, + DCI_ALLOC_NB_IoT_t *dci_alloc, + int16_t amp, + NB_IoT_DL_FRAME_PARMS *fp, + int32_t **txdataF, + uint32_t subframe, + uint8_t npdcch_start_symbol); + +/*! + \brief Decoding of PUSCH/ACK/RI/ACK from 36-212. + @param phy_vars_eNB Pointer to eNB top-level descriptor + @param proc Pointer to RXTX proc variables + @param UE_id ID of UE transmitting this PUSCH + @param subframe Index of subframe for PUSCH + @param control_only_flag Receive PUSCH with control information only + @param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213 + @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used + @returns 0 on success +*/ +unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + uint8_t UE_id, + uint8_t control_only_flag, + uint8_t Nbundled, + uint8_t llr8_flag); + +//NB-IoT version +NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(//unsigned char Kmimo, + //unsigned char Mdlharq, + uint32_t Nsoft, + //unsigned char N_RB_DL, + uint8_t abstraction_flag, + NB_IoT_DL_FRAME_PARMS* frame_parms); + + +NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t abstraction_flag); + + +uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe); + + +/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213. + @param I_MCS */ + +//uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS); +unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS, uint8_t N_sc_RU); + +/** \fn dlsch_encoding(PHY_VARS_eNB *eNB, + uint8_t *input_buffer, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe) + \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are: + - CRC computation and addition + - Code block segmentation and sub-block CRC addition + - Channel coding (Turbo coding) + - Rate matching (sub-block interleaving, bit collection, selection and transmission + - Code block concatenation + @param eNB Pointer to eNB PHY context + @param input_buffer Pointer to input buffer for sub-frame + @param frame_parms Pointer to frame descriptor structure + @param num_pdcch_symbols Number of PDCCH symbols in this subframe + @param dlsch Pointer to dlsch to be encoded + @param frame Frame number + @param subframe Subframe number + @param rm_stats Time statistics for rate-matching + @param te_stats Time statistics for turbo-encoding + @param i_stats Time statistics for interleaving + @returns status +*/ + +int32_t dlsch_encoding_NB_IoT(unsigned char *a, + NB_IoT_eNB_DLSCH_t *dlsch, + uint8_t Nsf, // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table) + unsigned int G, // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation) + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats); + + +void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + uint8_t eNB_id, // this is the effective sector id + uint8_t UE_id, + NB_IoT_eNB_NULSCH_t **ulsch, + uint8_t cooperation_flag); + + + + +void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF, + int32_t **rxdataF_ext, + // uint32_t first_rb, + //uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block + uint8_t N_sc_RU, // number of subcarriers in UL + uint32_t I_sc, // subcarrier indication field + uint32_t nb_rb, + uint8_t l, + uint8_t Ns, + NB_IoT_DL_FRAME_PARMS *frame_parms); + +void extract_CQI_NB_IoT(void *o,UCI_format_NB_IoT_t uci_format,NB_IoT_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode); + +//*****************Vincent part for nprach ******************// +void RX_NPRACH_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_buffer); + +uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + int16_t *Rx_sub_sampled_buffer, + uint16_t sub_sampling_rate, + uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES, + uint32_t estimated_TA_coarse, + char coarse); + +uint8_t NPRACH_detection_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_sub_sampled_buffer, uint16_t sub_sampling_rate, uint32_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES); + +int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate); +//************************************************************// +//*****************Vincent part for ULSCH demodulation ******************// +uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc); + +void generate_grouphop_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); + +void init_ul_hopping_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); + +void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol, + uint8_t Qm); + +void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol); + +int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *ulsch_llr, + uint8_t symbol, + uint8_t uint8_t, + int16_t **llrp); + + +int32_t ulsch_qpsk_llr_NB_IoT( + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *ulsch_llr, + uint8_t symbol, + uint8_t nb_rb, + int16_t **llrp); + +void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol); +//************************************************************// + +//************************************************************// +//*****************Vincent part for DLSCH demodulation ******************// + +int rx_npdsch_NB_IoT(PHY_VARS_UE_NB_IoT *ue, + unsigned char eNB_id, + unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference + uint32_t frame, + uint8_t subframe, + unsigned char symbol, + unsigned char first_symbol_flag, + unsigned char i_mod, + unsigned char harq_pid); + +unsigned short dlsch_extract_rbs_single_NB_IoT(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned short pmi, + unsigned char *pmi_ext, + unsigned int *rb_alloc, + unsigned char symbol, + unsigned char subframe, + uint32_t frame, + uint32_t high_speed_flag, + NB_IoT_DL_FRAME_PARMS *frame_parms); + +void dlsch_channel_level_NB_IoT(int **dl_ch_estimates_ext, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t *avg, + uint8_t symbol, + unsigned short nb_rb); + +void dlsch_channel_compensation_NB_IoT(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **dl_ch_mag, + int **dl_ch_magb, + int **rxdataF_comp, + int **rho, + NB_IoT_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + uint8_t first_symbol_flag, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift, + PHY_MEASUREMENTS_NB_IoT *measurements); + +int dlsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + uint8_t symbol, + uint8_t first_symbol_flag, + uint16_t nb_rb, + int16_t **llr32p, + uint8_t beamforming_mode); + +//************************************************************// + + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/pss.c b/openair1/PHY/LTE_TRANSPORT/pss.c index c746a331db246e2e46139d4386120389d3549557..33bd5cc7e8246f06b49ec8e85b30072cd4d10f33 100644 --- a/openair1/PHY/LTE_TRANSPORT/pss.c +++ b/openair1/PHY/LTE_TRANSPORT/pss.c @@ -36,8 +36,8 @@ */ //#include "defs.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" int generate_pss(int32_t **txdataF, short amp, @@ -75,6 +75,11 @@ int generate_pss(int32_t **txdataF, a = (frame_parms->nb_antenna_ports_eNB == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15)>>15; //printf("[PSS] amp=%d, a=%d\n",amp,a); +#if BASIC_SIMULATOR + /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */ + a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15; +#endif + Nsymb = (frame_parms->Ncp==NORMAL)?14:12; for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { @@ -105,10 +110,3 @@ int generate_pss(int32_t **txdataF, return(0); } -int generate_pss_emul(PHY_VARS_eNB *phy_vars_eNb,uint8_t sect_id) -{ - - LOG_D(PHY,"EMUL eNB generate_pss_emul eNB %d, sect_id %d\n",phy_vars_eNb->Mod_id,sect_id); - eNB_transport_info[phy_vars_eNb->Mod_id][phy_vars_eNb->CC_id].cntl.pss=sect_id; - return(0); -} diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 9a19b0ddaf3dee79997ca3af075bd9448b74d43b..e7aa11d30ad4b6b2fa069b6a2dd3f254979a734f 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -29,9 +29,10 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "LAYER2/MAC/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "LAYER2/MAC/mac.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -42,6 +43,8 @@ //#define DEBUG_PUCCH_TXS //#define DEBUG_PUCCH_RX +#include "pucch_extern.h" + int16_t cfo_pucch_np[24*7] = {20787,-25330,27244,-18205,31356,-9512,32767,0,31356,9511,27244,18204,20787,25329, 27244,-18205,30272,-12540,32137,-6393,32767,0,32137,6392,30272,12539,27244,18204, 31356,-9512,32137,-6393,32609,-3212,32767,0,32609,3211,32137,6392,31356,9511, @@ -61,1083 +64,6 @@ int16_t cfo_pucch_ep[24*6] = {24278,-22005,29621,-14010,32412,-4808,32412,4807,2 }; -void init_ncs_cell(LTE_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]) -{ - - uint8_t ns,l,reset=1,i,N_UL_symb; - uint32_t x1,x2,j=0,s=0; - - N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6; - x2 = frame_parms->Nid_cell; - - for (ns=0; ns<20; ns++) { - - for (l=0; l<N_UL_symb; l++) { - ncs_cell[ns][l]=0; - - for (i=0; i<8; i++) { - if ((j%32) == 0) { - s = lte_gold_generic(&x1,&x2,reset); - // printf("s %x\n",s); - reset=0; - } - - if (((s>>(j%32))&1)==1) - ncs_cell[ns][l] += (1<<i); - - j++; - } - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH ncs_cell init (j %d): Ns %d, l %d => ncs_cell %d\n",j,ns,l,ncs_cell[ns][l]); -#endif - } - - } -} - -int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377}; -int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0,-16384,-28378,-32768,-28378,-16384}; - -int16_t W4[3][4] = {{32767, 32767, 32767, 32767}, - {32767,-32768, 32767,-32768}, - {32767,-32768,-32768, 32767} -}; -int16_t W3_re[3][6] = {{32767, 32767, 32767}, - {32767,-16384,-16384}, - {32767,-16384,-16384} -}; - -int16_t W3_im[3][6] = {{0 ,0 ,0 }, - {0 , 28377,-28378}, - {0 ,-28378, 28377} -}; - -char *pucch_format_string[] = { - "format 1", - "format 1a", - "format 1b", - "pucch_format1b_csA2", - "pucch_format1b_csA3", - "pucch_format1b_csA4", - "format 2", - "format 2a", - "format 2b", - "pucch_format3" -}; - -/* PUCCH format3 >> */ -#define D_I 0 -#define D_Q 1 -#define D_IQDATA 2 -#define D_NSLT1SF 2 -#define D_NSYM1SLT 7 -#define D_NSYM1SF 2*7 -#define D_NSC1RB 12 -#define D_NRB1PUCCH 2 -#define D_NPUCCH_SF5 5 -#define D_NPUCCH_SF4 4 - -uint8_t chcod_tbl[128][48] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1}, - {0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0}, - {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1}, - {1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1}, - {0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}, - {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0}, - {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1}, - {1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1}, - {0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0}, - {0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, - {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1}, - {1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1}, - {0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0}, - {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1}, - {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, - {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0}, - {0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1}, - {0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1}, - {1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0}, - {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0}, - {0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1}, - {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1}, - {1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, - {1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0}, - {0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1}, - {0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1}, - {1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0}, - {0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0}, - {0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1}, - {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1}, - {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0}, - {1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0}, - {0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1}, - {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1}, - {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0}, - {1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0}, - {0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1}, - {0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1}, - {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0}, - {1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0}, - {0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1}, - {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, - {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}, - {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1}, - {0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0}, - {0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0}, - {1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1}, - {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1}, - {0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0}, - {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, - {1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1}, - {0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0}, - {0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1}, - {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1}, - {0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0}, - {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1}, - {1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0}, - {1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0}, - {0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1}, - {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, - {1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0}, - {0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1}, - {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, - {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0}, - {1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0}, - {0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1}, - {0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1}, - {1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0}, - {1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0}, - {0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1}, - {0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0}, - {1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1}, - {1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1}, - {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0}, - {0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0}, - {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1}, - {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1}, - {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0}, - {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0}, - {1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1}, - {1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1}, - {0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0}, - {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0}, - {1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1}, - {1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1}, - {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0}, - {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0}, - {1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1}, - {1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1}, - {0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, - {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0}, - {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1}, - {1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1}, - {0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0}, - {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0}, - {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1}, - {1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1}, - {0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0}, - {0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0}, - {1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1}, - {1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1}, - {0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1}, - {1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0}, - {1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1}, - {0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, - {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0}, - {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1}, - {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, - {1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0}, - {1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0}, - {0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1}, - {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}, - {1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0}, - {1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}, - {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1} }; - -// W5_TBL -int16_t W5_fmt3_re[5][5] = { {32767, 32767, 32767, 32767, 32767}, - {32767, 10125, -26509, -26509, 10125}, - {32767, -26509, 10125, 10125, -26509}, - {32767, -26509, 10125, 10125, -26509}, - {32767, 10125, -26509, -26509, 10125} }; - -int16_t W5_fmt3_im[5][5] = { {0, 0, 0, 0, 0}, - {0, 31163, 19259, -19259, -31163}, - {0, 19259, -31163, 31163, -19259}, - {0, -19259, 31163, -31163, 19259}, - {0, -31163, -19259, 19259, 31163} }; - -int16_t W4_fmt3[4][4] = { {32767, 32767, 32767, 32767}, - {32767, -32767, 32767, -32767}, - {32767, 32767, -32767, -32767}, - {32767, -32767, -32767, 32767} }; - -// W2 TBL -int16_t W2[2] = {32767, 32767}; - -// e^j*pai*floor (ncs_cell(ns,l)/64)/2 -int16_t RotTBL_re[4] = {32767, 0, -32767, 0}; -int16_t RotTBL_im[4] = {0, 32767, 0, -32767}; - -//np4_tbl, np5_tbl -uint8_t Np5_TBL[5] = {0, 3, 6, 8, 10}; -uint8_t Np4_TBL[4] = {0, 3, 6, 9}; - -// alpha_TBL -int16_t alphaTBL_re[12] = {32767, 28377, 16383, 0, -16383, -28377, -32767, -28377, -16383, 0, 16383, 28377}; -int16_t alphaTBL_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0, -16383, -28377, -32767, -28377, -16383}; - -/* PUCCH format3 << */ - -void generate_pucch1x(int32_t **txdataF, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t ncs_cell[20][7], - PUCCH_FMT_t fmt, - PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, - uint16_t n1_pucch, - uint8_t shortened_format, - uint8_t *payload, - int16_t amp, - uint8_t subframe) -{ - - uint32_t u,v,n; - uint32_t z[12*14],*zptr; - int16_t d0; - uint8_t ns,N_UL_symb,nsymb,n_oc,n_oc0,n_oc1; - uint8_t c = (frame_parms->Ncp==0) ? 3 : 2; - uint16_t nprime,nprime0,nprime1; - uint16_t i,j,re_offset,thres,h; - uint8_t Nprime_div_deltaPUCCH_Shift,Nprime,d; - uint8_t m,l,refs; - uint8_t n_cs,S,alpha_ind,rem; - int16_t tmp_re,tmp_im,ref_re,ref_im,W_re=0,W_im=0; - int32_t *txptr; - uint32_t symbol_offset; - - uint8_t deltaPUCCH_Shift = frame_parms->pucch_config_common.deltaPUCCH_Shift; - uint8_t NRB2 = frame_parms->pucch_config_common.nRB_CQI; - uint8_t Ncs1 = frame_parms->pucch_config_common.nCS_AN; - uint8_t Ncs1_div_deltaPUCCH_Shift = Ncs1/deltaPUCCH_Shift; - - LOG_D(PHY,"generate_pucch Start [deltaPUCCH_Shift %d, NRB2 %d, Ncs1_div_deltaPUCCH_Shift %d, n1_pucch %d]\n", deltaPUCCH_Shift, NRB2, Ncs1_div_deltaPUCCH_Shift,n1_pucch); - - - uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30; - uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30; - uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; - uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; - - if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) { - printf("[PHY] generate_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift); - return; - } - - if (Ncs1_div_deltaPUCCH_Shift > 7) { - printf("[PHY] generate_pucch: Illegal Ncs1_div_deltaPUCCH_Shift %d (should be 0...7)\n",Ncs1_div_deltaPUCCH_Shift); - return; - } - - zptr = z; - thres = (c*Ncs1_div_deltaPUCCH_Shift); - Nprime_div_deltaPUCCH_Shift = (n1_pucch < thres) ? Ncs1_div_deltaPUCCH_Shift : (12/deltaPUCCH_Shift); - Nprime = Nprime_div_deltaPUCCH_Shift * deltaPUCCH_Shift; - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH: cNcs1/deltaPUCCH_Shift %d, Nprime %d, n1_pucch %d\n",thres,Nprime,n1_pucch); -#endif - - LOG_D(PHY,"[PHY] PUCCH: n1_pucch %d, thres %d Ncs1_div_deltaPUCCH_Shift %d (12/deltaPUCCH_Shift) %d Nprime_div_deltaPUCCH_Shift %d \n", - n1_pucch, thres, Ncs1_div_deltaPUCCH_Shift, (int)(12/deltaPUCCH_Shift), Nprime_div_deltaPUCCH_Shift); - LOG_D(PHY,"[PHY] PUCCH: deltaPUCCH_Shift %d, Nprime %d\n",deltaPUCCH_Shift,Nprime); - - - N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6; - - if (n1_pucch < thres) - nprime0=n1_pucch; - else - nprime0 = (n1_pucch - thres)%(12*c/deltaPUCCH_Shift); - - if (n1_pucch >= thres) - nprime1= ((c*(nprime0+1))%((12*c/deltaPUCCH_Shift)+1))-1; - else { - d = (frame_parms->Ncp==0) ? 2 : 0; - h= (nprime0+d)%(c*Nprime_div_deltaPUCCH_Shift); -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH: h %d, d %d\n",h,d); -#endif - nprime1 = (h/c) + (h%c)*Nprime_div_deltaPUCCH_Shift; - } - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH: nprime0 %d nprime1 %d, %s, payload (%d,%d)\n",nprime0,nprime1,pucch_format_string[fmt],payload[0],payload[1]); -#endif - - n_oc0 = nprime0/Nprime_div_deltaPUCCH_Shift; - - if (frame_parms->Ncp==1) - n_oc0<<=1; - - n_oc1 = nprime1/Nprime_div_deltaPUCCH_Shift; - - if (frame_parms->Ncp==1) // extended CP - n_oc1<<=1; - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH: noc0 %d noc1 %d\n",n_oc0,n_oc1); -#endif - - nprime=nprime0; - n_oc =n_oc0; - - // loop over 2 slots - for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) { - - if ((nprime&1) == 0) - S=0; // 1 - else - S=1; // j - - //loop over symbols in slot - for (l=0; l<N_UL_symb; l++) { - // Compute n_cs (36.211 p. 18) - n_cs = ncs_cell[ns][l]; - - if (frame_parms->Ncp==0) { // normal CP - n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc%deltaPUCCH_Shift))%Nprime)%12; - } else { - n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc>>1))%Nprime)%12; - } - - - refs=0; - - // Comput W_noc(m) (36.211 p. 19) - if ((ns==(1+(subframe<<1))) && (shortened_format==1)) { // second slot and shortened format - - if (l<2) { // data - W_re=W3_re[n_oc][l]; - W_im=W3_im[n_oc][l]; - } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP - W_re=W3_re[n_oc][l-2]; - W_im=W3_im[n_oc][l-2]; - refs=1; - } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP - W_re=W4[n_oc][l-2]; - W_im=0; - refs=1; - } else if ((l>=N_UL_symb-2)) { // data - W_re=W3_re[n_oc][l-N_UL_symb+4]; - W_im=W3_im[n_oc][l-N_UL_symb+4]; - } - } else { - if (l<2) { // data - W_re=W4[n_oc][l]; - W_im=0; - } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP - W_re=W3_re[n_oc][l-2]; - W_im=W3_im[n_oc][l-2]; - refs=1; - } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP - W_re=W4[n_oc][l-2]; - W_im=0; - refs=1; - } else if ((l>=N_UL_symb-2)) { // data - W_re=W4[n_oc][l-N_UL_symb+4]; - W_im=0; - } - } - - // multiply W by S(ns) (36.211 p.17). only for data, reference symbols do not have this factor - if ((S==1)&&(refs==0)) { - tmp_re = W_re; - W_re = -W_im; - W_im = tmp_re; - } - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH: ncs[%d][%d]=%d, W_re %d, W_im %d, S %d, refs %d\n",ns,l,n_cs,W_re,W_im,S,refs); -#endif - alpha_ind=0; - // compute output sequence - - for (n=0; n<12; n++) { - - // this is r_uv^alpha(n) - tmp_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); - tmp_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); - - // this is S(ns)*w_noc(m)*r_uv^alpha(n) - ref_re = (tmp_re*W_re - tmp_im*W_im)>>15; - ref_im = (tmp_re*W_im + tmp_im*W_re)>>15; - - if ((l<2)||(l>=(N_UL_symb-2))) { //these are PUCCH data symbols - switch (fmt) { - case pucch_format1: //OOK 1-bit - - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15; - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15; - - break; - - case pucch_format1a: //BPSK 1-bit - d0 = (payload[0]&1)==0 ? amp : -amp; - ((int16_t *)&zptr[n])[0] = ((int32_t)d0*ref_re)>>15; - ((int16_t *)&zptr[n])[1] = ((int32_t)d0*ref_im)>>15; - // printf("d0 %d\n",d0); - break; - - case pucch_format1b: //QPSK 2-bits (Table 5.4.1-1 from 36.211, pg. 18) - if (((payload[0]&1)==0) && ((payload[1]&1)==0)) {// 1 - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15; - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15; - } else if (((payload[0]&1)==0) && ((payload[1]&1)==1)) { // -j - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_im)>>15; - ((int16_t *)&zptr[n])[1] = (-(int32_t)amp*ref_re)>>15; - } else if (((payload[0]&1)==1) && ((payload[1]&1)==0)) { // j - ((int16_t *)&zptr[n])[0] = (-(int32_t)amp*ref_im)>>15; - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_re)>>15; - } else { // -1 - ((int16_t *)&zptr[n])[0] = (-(int32_t)amp*ref_re)>>15; - ((int16_t *)&zptr[n])[1] = (-(int32_t)amp*ref_im)>>15; - } - - break; - case pucch_format1b_csA2: - case pucch_format1b_csA3: - case pucch_format1b_csA4: - AssertFatal(1==0,"PUCCH format 1b_csX not supported yet\n"); - break; - case pucch_format2: - case pucch_format2a: - case pucch_format2b: - AssertFatal(1==0,"should not go here\n"); - break; - - case pucch_format3: - fprintf(stderr, "PUCCH format 3 not handled\n"); - abort(); - } // switch fmt - } else { // These are PUCCH reference symbols - - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15; - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15; - // printf("ref\n"); - } - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH subframe %d z(%d,%d) => %d,%d, alpha(%d) => %d,%d\n",subframe,l,n,((int16_t *)&zptr[n])[0],((int16_t *)&zptr[n])[1], - alpha_ind,alpha_re[alpha_ind],alpha_im[alpha_ind]); -#endif - alpha_ind = (alpha_ind + n_cs)%12; - } // n - - zptr+=12; - } // l - - nprime=nprime1; - n_oc =n_oc1; - } // ns - - rem = ((((12*Ncs1_div_deltaPUCCH_Shift)>>3)&7)>0) ? 1 : 0; - - m = (n1_pucch < thres) ? NRB2 : (((n1_pucch-thres)/(12*c/deltaPUCCH_Shift))+NRB2+((deltaPUCCH_Shift*Ncs1_div_deltaPUCCH_Shift)>>3)+rem); - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH: m %d\n",m); -#endif - nsymb = N_UL_symb<<1; - - //for (j=0,l=0;l<(nsymb-1);l++) { - for (j=0,l=0; l<(nsymb); l++) { - if ((l<(nsymb>>1)) && ((m&1) == 0)) - re_offset = (m*6) + frame_parms->first_carrier_offset; - else if ((l<(nsymb>>1)) && ((m&1) == 1)) - re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; - else if ((m&1) == 0) - re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; - else - re_offset = ((m-1)*6) + frame_parms->first_carrier_offset; - - if (re_offset > frame_parms->ofdm_symbol_size) - re_offset -= (frame_parms->ofdm_symbol_size); - - symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb)); - txptr = &txdataF[0][symbol_offset]; - - for (i=0; i<12; i++,j++) { - txptr[re_offset++] = z[j]; - - if (re_offset==frame_parms->ofdm_symbol_size) - re_offset = 0; - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]); -#endif - } - } - -} - -void generate_pucch_emul(PHY_VARS_UE *ue, - UE_rxtx_proc_t *proc, - PUCCH_FMT_t format, - uint8_t ncs1, - uint8_t *pucch_payload, - uint8_t sr) - -{ - - int subframe = proc->subframe_tx; - - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_flag = format; - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_Ncs1 = ncs1; - - - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.sr = sr; - // the value of ue->pucch_sel[subframe] is set by get_n1_pucch - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_sel = ue->pucch_sel[subframe]; - - // LOG_I(PHY,"subframe %d emu tx pucch_sel is %d sr is %d \n", subframe, UE_transport_info[ue->Mod_id].cntl.pucch_sel, sr); - - if (format == pucch_format1a) { - - ue->pucch_payload[0] = pucch_payload[0]; - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_payload = pucch_payload[0]; - } else if (format == pucch_format1b) { - ue->pucch_payload[0] = pucch_payload[0] + (pucch_payload[1]<<1); - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_payload = pucch_payload[0] + (pucch_payload[1]<<1); - } else if (format == pucch_format1) { - // LOG_D(PHY,"[UE %d] Frame %d subframe %d Generating PUCCH for SR %d\n",ue->Mod_id,proc->frame_tx,subframe,sr); - } - - ue->sr[subframe] = sr; - -} - - -inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) __attribute__((always_inline)); -inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) { - - uint32_t x1, x2, s=0; - int i; - uint8_t c; - - x2 = (rnti) + ((uint32_t)(1+subframe)<<16)*(1+(fp->Nid_cell<<1)); //this is c_init in 36.211 Sec 6.3.1 - s = lte_gold_generic(&x1, &x2, 1); - for (i=0;i<19;i++) { - c = (uint8_t)((s>>i)&1); - btilde[i] = (((B>>i)&1) ^ c); - } -} - -inline void pucch2x_modulation(uint8_t *btilde,int16_t *d,int16_t amp) __attribute__((always_inline)); -inline void pucch2x_modulation(uint8_t *btilde,int16_t *d,int16_t amp) { - - int i; - - for (i=0;i<20;i++) - d[i] = btilde[i] == 1 ? -amp : amp; - -} - - - -uint32_t pucch_code[13] = {0xFFFFF,0x5A933,0x10E5A,0x6339C,0x73CE0, - 0xFFC00,0xD8E64,0x4F6B0,0x218EC,0x1B746, - 0x0FFFF,0x33FFF,0x3FFFC}; - - -void generate_pucch2x(int32_t **txdataF, - LTE_DL_FRAME_PARMS *fp, - uint8_t ncs_cell[20][7], - PUCCH_FMT_t fmt, - PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, - uint16_t n2_pucch, - uint8_t *payload, - int A, - int B2, - int16_t amp, - uint8_t subframe, - uint16_t rnti) { - - int i,j; - uint32_t B=0; - uint8_t btilde[20]; - int16_t d[22]; - uint8_t deltaPUCCH_Shift = fp->pucch_config_common.deltaPUCCH_Shift; - uint8_t NRB2 = fp->pucch_config_common.nRB_CQI; - uint8_t Ncs1 = fp->pucch_config_common.nCS_AN; - - uint32_t u0 = fp->pucch_config_common.grouphop[subframe<<1]; - uint32_t u1 = fp->pucch_config_common.grouphop[1+(subframe<<1)]; - uint32_t v0 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; - uint32_t v1 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; - - uint32_t z[12*14],*zptr; - uint32_t u,v,n; - uint8_t ns,N_UL_symb,nsymb_slot0,nsymb_pertti; - uint32_t nprime,l,n_cs; - int alpha_ind,data_ind; - int16_t ref_re,ref_im; - int m,re_offset,symbol_offset; - int32_t *txptr; - - if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) { - printf("[PHY] generate_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift); - return; - } - - if (Ncs1 > 7) { - printf("[PHY] generate_pucch: Illegal Ncs1 %d (should be 0...7)\n",Ncs1); - return; - } - - // pucch2x_encoding - for (i=0;i<A;i++) - if ((*payload & (1<<i)) > 0) - B=B^pucch_code[i]; - - // scrambling - pucch2x_scrambling(fp,subframe,rnti,B,btilde); - // modulation - pucch2x_modulation(btilde,d,amp); - - // add extra symbol for 2a/2b - d[20]=0; - d[21]=0; - if (fmt==pucch_format2a) - d[20] = (B2 == 0) ? amp : -amp; - else if (fmt==pucch_format2b) { - switch (B2) { - case 0: - d[20] = amp; - break; - case 1: - d[21] = -amp; - break; - case 2: - d[21] = amp; - break; - case 3: - d[20] = -amp; - break; - default: - AssertFatal(1==0,"Illegal modulation symbol %d for PUCCH %s\n",B2,pucch_format_string[fmt]); - break; - } - } - - -#ifdef DEBUG_PUCCH_TX - printf("[PHY] PUCCH2x: n2_pucch %d\n",n2_pucch); -#endif - - N_UL_symb = (fp->Ncp==0) ? 7 : 6; - data_ind = 0; - zptr = z; - nprime = 0; - for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) { - - if ((ns&1) == 0) - nprime = (n2_pucch < 12*NRB2) ? - n2_pucch % 12 : - (n2_pucch+Ncs1 + 1)%12; - else { - nprime = (n2_pucch < 12*NRB2) ? - ((12*(nprime+1)) % 13)-1 : - (10-n2_pucch)%12; - } - //loop over symbols in slot - for (l=0; l<N_UL_symb; l++) { - // Compute n_cs (36.211 p. 18) - n_cs = (ncs_cell[ns][l]+nprime)%12; - - alpha_ind = 0; - 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); - - if ((l!=1)&&(l!=5)) { //these are PUCCH data symbols - ((int16_t *)&zptr[n])[0] = ((int32_t)d[data_ind]*ref_re - (int32_t)d[data_ind+1]*ref_im)>>15; - ((int16_t *)&zptr[n])[1] = ((int32_t)d[data_ind]*ref_im + (int32_t)d[data_ind+1]*ref_re)>>15; - //LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n); - } - else { - 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; - - if ((l!=1)&&(l!=5)) //these are PUCCH data symbols so increment data index - data_ind+=2; - } // l - } //ns - - m = n2_pucch/12; - -#ifdef DEBUG_PUCCH_TX - LOG_D(PHY,"[PHY] PUCCH: n2_pucch %d m %d\n",n2_pucch,m); -#endif - - nsymb_slot0 = ((fp->Ncp==0) ? 7 : 6); - nsymb_pertti = nsymb_slot0 << 1; - - //nsymb = nsymb_slot0<<1; - - //for (j=0,l=0;l<(nsymb-1);l++) { - for (j=0,l=0; l<(nsymb_pertti); l++) { - - if ((l<nsymb_slot0) && ((m&1) == 0)) - re_offset = (m*6) + fp->first_carrier_offset; - else if ((l<nsymb_slot0) && ((m&1) == 1)) - re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12; - else if ((m&1) == 0) - re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12; - else - re_offset = ((m-1)*6) + fp->first_carrier_offset; - - if (re_offset > fp->ofdm_symbol_size) - re_offset -= (fp->ofdm_symbol_size); - - - - symbol_offset = (unsigned int)fp->ofdm_symbol_size*(l+(subframe*nsymb_pertti)); - txptr = &txdataF[0][symbol_offset]; - - //LOG_I(PHY,"ofdmSymb %d/%d, firstCarrierOffset %d, symbolOffset[sfn %d] %d, reOffset %d, &txptr: %x \n", l, nsymb, fp->first_carrier_offset, subframe, symbol_offset, re_offset, &txptr[0]); - - for (i=0; i<12; i++,j++) { - txptr[re_offset] = z[j]; - - re_offset++; - - if (re_offset==fp->ofdm_symbol_size) - re_offset -= (fp->ofdm_symbol_size); - -#ifdef DEBUG_PUCCH_TX - LOG_D(PHY,"[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]); -#endif - } - } -} - -/* PUCCH format3 >> */ -/* DFT */ -void pucchfmt3_Dft( int16_t *x, int16_t *y ) -{ - int16_t i, k; - int16_t tmp[2]; - int16_t calctmp[D_NSC1RB*2]={0}; - - for (i=0; i<D_NSC1RB; i++) { - for(k=0; k<D_NSC1RB; k++) { - tmp[0] = alphaTBL_re[(12-((i*k)%12))%12]; - tmp[1] = alphaTBL_im[(12-((i*k)%12))%12]; - - calctmp[2*i] += (((int32_t)x[2*k] * tmp[0] - (int32_t)x[2*k+1] * tmp[1])>>15); - calctmp[2*i+1] += (((int32_t)x[2*k+1] * tmp[0] + (int32_t)x[2*k] * tmp[1])>>15); - } - y[2*i] = (int16_t)( (double) calctmp[2*i] / sqrt(D_NSC1RB)); - y[2*i+1] = (int16_t)((double) calctmp[2*i+1] / sqrt(D_NSC1RB)); - } -} - -void generate_pucch3x(int32_t **txdataF, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t ncs_cell[20][7], - PUCCH_FMT_t fmt, - PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, - uint16_t n3_pucch, - uint8_t shortened_format, - uint8_t *payload, - int16_t amp, - uint8_t subframe, - uint16_t rnti) -{ - - uint32_t u, v; - uint16_t i, j, re_offset; - uint32_t z[12*14], *zptr; - uint32_t y_tilda[12*14]={}, *y_tilda_ptr; - uint8_t ns, nsymb, n_oc, n_oc0, n_oc1; - uint8_t N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6; - uint8_t m, l; - uint8_t n_cs; - int16_t tmp_re, tmp_im, W_re=0, W_im=0; - int32_t *txptr; - uint32_t symbol_offset; - - uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30; - uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30; - uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; - uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; - - // variables for channel coding - uint8_t chcod_tbl_idx = 0; - //uint8_t chcod_dt[48] = {}; - - // variables for Scrambling - uint32_t cinit = 0; - uint32_t x1; - uint32_t s,s0,s1; - uint8_t C[48] ={}; - uint8_t scr_dt[48]={}; - - // variables for Modulation - int16_t d_re[24]={}; - int16_t d_im[24]={}; - - // variables for orthogonal sequence selection - uint8_t N_PUCCH_SF0 = 5; - uint8_t N_PUCCH_SF1 = (shortened_format==0)? 5:4; - uint8_t first_slot = 0; - int16_t rot_re=0; - int16_t rot_im=0; - - uint8_t dt_offset; - uint8_t sym_offset; - int16_t y_re[14][12]; //={0}; - int16_t y_im[14][12]; //={0}; - - // DMRS - uint8_t alpha_idx=0; - uint8_t m_alpha_idx=0; - - // TODO - // "SR+ACK/NACK" length is only 7 bits. - // This restriction will be lifted in the future. - // "CQI/PMI/RI+ACK/NACK" will be supported in the future. - - // Channel Coding - for (uint8_t i=0; i<7; i++) { - chcod_tbl_idx += (payload[i]<<i); - } - - // Scrambling - cinit = (subframe + 1) * ((2 * frame_parms->Nid_cell + 1)<<16) + rnti; - s0 = lte_gold_generic(&x1,&cinit,1); - s1 = lte_gold_generic(&x1,&cinit,0); - - for (i=0; i<48; i++) { - s = (i<32)? s0:s1; - j = (i<32)? i:(i-32); - C[i] = ((s>>j)&1); - } - - for (i=0; i<48; i++) { - scr_dt[i] = chcod_tbl[chcod_tbl_idx][i] ^ C[i]; - } - - // Modulation - for (uint8_t i=0; i<48; i+=2){ - if (scr_dt[i]==0 && scr_dt[i+1]==0){ - d_re[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); - d_im[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); - } else if (scr_dt[i]==0 && scr_dt[i+1]==1) { - d_re[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); - d_im[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp) >>15); - } else if (scr_dt[i]==1 && scr_dt[i+1]==0) { - d_re[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); - d_im[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp)>>15); - } else if (scr_dt[i]==1 && scr_dt[i+1]==1) { - d_re[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); - d_im[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); - } else { - //***log Modulation Error! - } - } - - // Calculate Orthogonal Sequence index - n_oc0 = n3_pucch % N_PUCCH_SF1; - if (N_PUCCH_SF1 == 5) { - n_oc1 = (3 * n_oc0) % N_PUCCH_SF1; - } else { - n_oc1 = n_oc0 % N_PUCCH_SF1; - } - - y_tilda_ptr = y_tilda; - zptr = z; - - // loop over 2 slots - for (ns=(subframe<<1), u=u0, v=v0; ns<(2+(subframe<<1)); ns++, u=u1, v=v1) { - first_slot = (ns==(subframe<<1))?1:0; - - //loop over symbols in slot - for (l=0; l<N_UL_symb; l++) { - rot_re = RotTBL_re[(uint8_t) ncs_cell[ns][l]/64] ; - rot_im = RotTBL_im[(uint8_t) ncs_cell[ns][l]/64] ; - - // Comput W_noc(m) (36.211 p. 19) - if ( first_slot == 0 && shortened_format==1) { // second slot and shortened format - n_oc = n_oc1; - - if (l<1) { // data - W_re=W4_fmt3[n_oc][l]; - W_im=0; - } else if (l==1) { // DMRS - W_re=W2[0]; - W_im=0; - } else if (l>=2 && l<5) { // data - W_re=W4_fmt3[n_oc][l-1]; - W_im=0; - } else if (l==5) { // DMRS - W_re=W2[1]; - W_im=0; - } else if ((l>=N_UL_symb-2)) { // data - ; - } else { - //***log W Select Error! - } - } else { - if (first_slot == 1) { // 1st slot or 2nd slot and not shortened - n_oc=n_oc0; - } else { - n_oc=n_oc1; - } - - if (l<1) { // data - W_re=W5_fmt3_re[n_oc][l]; - W_im=W5_fmt3_im[n_oc][l]; - } else if (l==1) { // DMRS - W_re=W2[0]; - W_im=0; - } else if (l>=2 && l<5) { // data - W_re=W5_fmt3_re[n_oc][l-1]; - W_im=W5_fmt3_im[n_oc][l-1]; - } else if (l==5) { // DMRS - W_re=W2[1]; - W_im=0; - } else if ((l>=N_UL_symb-1)) { // data - W_re=W5_fmt3_re[n_oc][l-N_UL_symb+5]; - W_im=W5_fmt3_im[n_oc][l-N_UL_symb+5]; - } else { - //***log W Select Error! - } - } // W Selection end - - // Compute n_cs (36.211 p. 18) - n_cs = ncs_cell[ns][l]; - if (N_PUCCH_SF1 == 5) { - alpha_idx = (n_cs + Np5_TBL[n_oc]) % 12; - } else { - alpha_idx = (n_cs + Np4_TBL[n_oc]) % 12; - } - - // generate pucch data - dt_offset = (first_slot == 1) ? 0:12; - sym_offset = (first_slot == 1) ? 0:7; - - for (i=0; i<12; i++) { - // Calculate yn(i) - tmp_re = (((int32_t) (W_re*rot_re - W_im*rot_im)) >>15); - tmp_im = (((int32_t) (W_re*rot_im + W_im*rot_re)) >>15); - y_re[l+sym_offset][i] = (((int32_t) (tmp_re*d_re[i+dt_offset] - tmp_im*d_im[i+dt_offset]))>>15); - y_im[l+sym_offset][i] = (((int32_t) (tmp_re*d_im[i+dt_offset] + tmp_im*d_re[i+dt_offset]))>>15); - - // cyclic shift - ((int16_t *)&y_tilda_ptr[(l+sym_offset)*12+(i-(ncs_cell[ns][l]%12)+12)%12])[0] = y_re[l+sym_offset][i]; - ((int16_t *)&y_tilda_ptr[(l+sym_offset)*12+(i-(ncs_cell[ns][l]%12)+12)%12])[1] = y_im[l+sym_offset][i]; - - // DMRS - m_alpha_idx = (alpha_idx * i) % 12; - if (l==1 || l==5) { - ((int16_t *)&zptr[(l+sym_offset)*12+i])[0] =(((((int32_t) alphaTBL_re[m_alpha_idx]*ul_ref_sigs[u][v][0][i<<1] - (int32_t) alphaTBL_im[m_alpha_idx] * ul_ref_sigs[u][v][0][1+(i<<1)])>>15) * (int32_t)amp)>>15); - ((int16_t *)&zptr[(l+sym_offset)*12+i])[1] =(((((int32_t) alphaTBL_re[m_alpha_idx]*ul_ref_sigs[u][v][0][1+(i<<1)] + (int32_t) alphaTBL_im[m_alpha_idx] * ul_ref_sigs[u][v][0][i<<1])>>15) * (int32_t)amp)>>15); - } - } - - } // l loop - } // ns - - // DFT for pucch-data - for (l=0; l<14; l++) { - if (l==1 || l==5 || l==8 || l==12) { - ; - } else { - pucchfmt3_Dft((int16_t*)&y_tilda_ptr[l*12],(int16_t*)&zptr[l*12]); - } - } - - - // Mapping - m = n3_pucch / N_PUCCH_SF0; - - if (shortened_format == 1) { - nsymb = (N_UL_symb<<1) - 1; - } else { - nsymb = (N_UL_symb<<1); - } - - for (j=0,l=0; l<(nsymb); l++) { - - if ((l<7) && ((m&1) == 0)) - re_offset = (m*6) + frame_parms->first_carrier_offset; - else if ((l<7) && ((m&1) == 1)) - re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; - else if ((m&1) == 0) - re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; - else - re_offset = ((m-1)*6) + frame_parms->first_carrier_offset; - - if (re_offset > frame_parms->ofdm_symbol_size) - re_offset -= (frame_parms->ofdm_symbol_size); - - symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*(l+(subframe*14)); - txptr = &txdataF[0][symbol_offset]; - - for (i=0; i<12; i++,j++) { - txptr[re_offset++] = z[j]; - - if (re_offset==frame_parms->ofdm_symbol_size) - re_offset = 0; - -#ifdef DEBUG_PUCCH_TX - msg("[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]); -#endif - } - } - -} - -/* PUCCH format3 << */ - - -//#define Amax 13 -//void init_pucch2x_rx() {}; /* PUCCH format3 >> */ @@ -1278,7 +204,7 @@ uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX int32_t IP_CsData_allsfavg[NB_ANTENNAS_RX][14][4][2]; int32_t IP_allavg[D_NPUCCH_SF5]; //int16_t temp_ch[2]; - int16_t m[NUMBER_OF_UE_MAX], m_self, same_m_number; + int16_t m[NUMBER_OF_UE_MAX], m_self=0, same_m_number; uint16_t n3_pucch_sameRB[NUMBER_OF_UE_MAX]; int16_t n_oc0[NUMBER_OF_UE_MAX]; int16_t n_oc1[NUMBER_OF_UE_MAX]; diff --git a/openair1/PHY/LTE_TRANSPORT/pucch_common.c b/openair1/PHY/LTE_TRANSPORT/pucch_common.c new file mode 100644 index 0000000000000000000000000000000000000000..a9181a8b3dfe8107f42ad5b880b5eba3b5171d00 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/pucch_common.c @@ -0,0 +1,270 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/pucch_common.c +* \brief Top-level routines common to eNB/UE for the PUCCH physical channel V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "LAYER2/MAC/mac.h" + +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" + +#include "T.h" + +void init_ncs_cell(LTE_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]) +{ + + uint8_t ns,l,reset=1,i,N_UL_symb; + uint32_t x1,x2,j=0,s=0; + + N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6; + x2 = frame_parms->Nid_cell; + + for (ns=0; ns<20; ns++) { + + for (l=0; l<N_UL_symb; l++) { + ncs_cell[ns][l]=0; + + for (i=0; i<8; i++) { + if ((j%32) == 0) { + s = lte_gold_generic(&x1,&x2,reset); + // printf("s %x\n",s); + reset=0; + } + + if (((s>>(j%32))&1)==1) + ncs_cell[ns][l] += (1<<i); + + j++; + } + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH ncs_cell init (j %d): Ns %d, l %d => ncs_cell %d\n",j,ns,l,ncs_cell[ns][l]); +#endif + } + + } +} + +int16_t W4[3][4] = {{32767, 32767, 32767, 32767}, + {32767,-32768, 32767,-32768}, + {32767,-32768,-32768, 32767} +}; +int16_t W3_re[3][6] = {{32767, 32767, 32767}, + {32767,-16384,-16384}, + {32767,-16384,-16384} +}; + +int16_t W3_im[3][6] = {{0 ,0 ,0 }, + {0 , 28377,-28378}, + {0 ,-28378, 28377} +}; + +char *pucch_format_string[] = { + "format 1", + "format 1a", + "format 1b", + "pucch_format1b_csA2", + "pucch_format1b_csA3", + "pucch_format1b_csA4", + "format 2", + "format 2a", + "format 2b", + "pucch_format3" +}; + + + +uint8_t chcod_tbl[128][48] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1}, + {0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0}, + {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1}, + {1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1}, + {0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}, + {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0}, + {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1}, + {1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1}, + {0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0}, + {0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, + {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1}, + {1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1}, + {0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1}, + {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, + {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0}, + {0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1}, + {0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1}, + {1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0}, + {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0}, + {0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1}, + {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1}, + {1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0}, + {0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1}, + {0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1}, + {1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0}, + {0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0}, + {0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1}, + {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1}, + {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0}, + {0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1}, + {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1}, + {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0}, + {1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0}, + {0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1}, + {0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1}, + {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0}, + {1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0}, + {0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1}, + {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}, + {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1}, + {0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0}, + {0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0}, + {1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1}, + {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1}, + {0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, + {1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1}, + {0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0}, + {0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1}, + {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1}, + {0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0}, + {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1}, + {1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0}, + {1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0}, + {0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1}, + {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0}, + {0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, + {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0}, + {1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0}, + {0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1}, + {0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1}, + {1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0}, + {1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0}, + {0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1}, + {0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0}, + {1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1}, + {1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1}, + {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0}, + {0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1}, + {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1}, + {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1}, + {1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1}, + {0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0}, + {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0}, + {1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1}, + {1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1}, + {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0}, + {1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1}, + {1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1}, + {0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0}, + {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1}, + {1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1}, + {0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0}, + {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1}, + {1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1}, + {0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0}, + {0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0}, + {1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1}, + {1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1}, + {0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1}, + {1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0}, + {1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1}, + {0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0}, + {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1}, + {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, + {1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0}, + {1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0}, + {0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1}, + {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}, + {1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0}, + {1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}, + {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1} }; + +int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377}; +int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0,-16384,-28378,-32768,-28378,-16384}; + +// W5_TBL +int16_t W5_fmt3_re[5][5] = { {32767, 32767, 32767, 32767, 32767}, + {32767, 10125, -26509, -26509, 10125}, + {32767, -26509, 10125, 10125, -26509}, + {32767, -26509, 10125, 10125, -26509}, + {32767, 10125, -26509, -26509, 10125} }; + +int16_t W5_fmt3_im[5][5] = { {0, 0, 0, 0, 0}, + {0, 31163, 19259, -19259, -31163}, + {0, 19259, -31163, 31163, -19259}, + {0, -19259, 31163, -31163, 19259}, + {0, -31163, -19259, 19259, 31163} }; + +int16_t W4_fmt3[4][4] = { {32767, 32767, 32767, 32767}, + {32767, -32767, 32767, -32767}, + {32767, 32767, -32767, -32767}, + {32767, -32767, -32767, 32767} }; + +// W2 TBL +int16_t W2[2] = {32767, 32767}; + +// e^j*pai*floor (ncs_cell(ns,l)/64)/2 +int16_t RotTBL_re[4] = {32767, 0, -32767, 0}; +int16_t RotTBL_im[4] = {0, 32767, 0, -32767}; + +//np4_tbl, np5_tbl +uint8_t Np5_TBL[5] = {0, 3, 6, 8, 10}; +uint8_t Np4_TBL[4] = {0, 3, 6, 9}; + +// alpha_TBL +int16_t alphaTBL_re[12] = {32767, 28377, 16383, 0, -16383, -28377, -32767, -28377, -16383, 0, 16383, 28377}; +int16_t alphaTBL_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0, -16383, -28377, -32767, -28377, -16383}; + diff --git a/openair1/PHY/LTE_TRANSPORT/pucch_extern.h b/openair1/PHY/LTE_TRANSPORT/pucch_extern.h new file mode 100644 index 0000000000000000000000000000000000000000..899b90430670af54af65a918d859689646e1129c --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/pucch_extern.h @@ -0,0 +1,78 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/pucch.c +* \brief Top-level routines for generating and decoding the PUCCH physical channel V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ + +#include <stdint.h> + +/* PUCCH format3 >> */ +#define D_I 0 +#define D_Q 1 +#define D_IQDATA 2 +#define D_NSLT1SF 2 +#define D_NSYM1SLT 7 +#define D_NSYM1SF 2*7 +#define D_NSC1RB 12 +#define D_NRB1PUCCH 2 +#define D_NPUCCH_SF5 5 +#define D_NPUCCH_SF4 4 + +extern int16_t W4[3][4]; + +extern int16_t W3_re[3][6]; + + +extern int16_t W3_im[3][6]; + +extern int16_t alpha_re[12]; +extern int16_t alpha_im[12]; + +extern char *pucch_format_string[]; + +extern uint8_t chcod_tbl[128][48]; + +extern int16_t W5_fmt3_re[5][5]; + +extern int16_t W5_fmt3_im[5][5]; + +extern int16_t W4_fmt3[4][4]; + +extern int16_t W2[2]; + +extern int16_t RotTBL_re[4]; +extern int16_t RotTBL_im[4]; + +//np4_tbl, np5_tbl +extern uint8_t Np5_TBL[5]; +extern uint8_t Np4_TBL[4]; + +// alpha_TBL +extern int16_t alphaTBL_re[12]; +extern int16_t alphaTBL_im[12]; diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c index 9934b71d78b0165c32d9b4df855e97779c43ee33..ab4656716bcc509cfddf46ba96582c81adcc89fd 100644 --- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c @@ -20,7 +20,7 @@ */ /*! \file PHY/LTE_TRANSPORT/rar_tools.c -* \brief Routine for filling the PUSCH/ULSCH data structures based on a random-access response (RAR) SDU from MAC. Note this is both for UE and eNB. V8.6 2009-03 +* \brief Routine for filling the PUSCH/ULSCH data structures based on a random-access response (RAR) SDU from MAC. Note this is for eNB. * \author R. Knopp * \date 2011 * \version 0.1 @@ -29,14 +29,12 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/defs.h" -#include "SCHED/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" +#include "LAYER2/MAC/mac.h" #include "UTIL/LOG/vcd_signal_dumper.h" - +#include "PHY/LTE_TRANSPORT/transport_proto.h" #include "assertions.h" extern uint16_t RIV2nb_rb_LUT6[32]; @@ -194,159 +192,3 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, return(0); } -int8_t delta_PUSCH_msg2[8] = {-6,-4,-2,0,2,4,6,8}; - -int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue, - UE_rxtx_proc_t *proc, - unsigned char eNB_id ) -{ - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_RAR,VCD_FUNCTION_IN); - - // RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)rar_pdu; - uint8_t transmission_mode = ue->transmission_mode[eNB_id]; - unsigned char *rar_pdu = ue->dlsch_ra[eNB_id]->harq_processes[0]->b; - unsigned char subframe = ue->ulsch_Msg3_subframe[eNB_id]; - LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - PHY_MEASUREMENTS *meas = &ue->measurements; - - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - // int current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; - - uint8_t *rar = (uint8_t *)(rar_pdu+1); - uint8_t harq_pid = subframe2harq_pid(frame_parms,proc->frame_tx,subframe); - uint16_t rballoc; - uint8_t cqireq; - uint16_t *RIV2nb_rb_LUT, *RIV2first_rb_LUT; - uint16_t RIV_max = 0; - - LOG_D(PHY,"[eNB][RAPROC] Frame %d: generate_ue_ulsch_params_from_rar: subframe %d (harq_pid %d)\n",proc->frame_tx,subframe,harq_pid); - - switch (frame_parms->N_RB_DL) { - case 6: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT6[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT6[0]; - RIV_max = RIV_max6; - break; - - case 25: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT25[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT25[0]; - RIV_max = RIV_max25; - break; - - case 50: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT50[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT50[0]; - RIV_max = RIV_max50; - break; - - case 100: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT100[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT100[0]; - RIV_max = RIV_max100; - break; - - default: - DevParam(frame_parms->N_RB_DL, eNB_id, harq_pid); - break; - } - - - - ulsch->harq_processes[harq_pid]->TPC = (rar[3]>>2)&7;//rar->TPC; - - rballoc = (((uint16_t)(rar[1]&7))<<7)|(rar[2]>>1); - cqireq=rar[3]&1; - - if (rballoc>RIV_max) { - LOG_D(PHY,"rar_tools.c: ERROR: rb_alloc (%x) > RIV_max\n",rballoc); - return(-1); - } - - ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT[rballoc]; - ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT[rballoc]; - - AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb >0, "nb_rb == 0\n"); - - ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb]; - - AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb <= 6,"unlikely rb count for RAR grant : nb_rb > 6\n"); - - // ulsch->harq_processes[harq_pid]->Ndi = 1; - if (ulsch->harq_processes[harq_pid]->round == 0) - ulsch->harq_processes[harq_pid]->status = ACTIVE; - - if (cqireq==1) { - ulsch->O_RI = 1; - - if (meas->rank[eNB_id] == 1) { - ulsch->uci_format = wideband_cqi_rank2_2A; - ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; - ulsch->o_RI[0] = 1; - } else { - ulsch->uci_format = wideband_cqi_rank1_2A; - ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; - ulsch->o_RI[0] = 0; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - fill_CQI(ulsch,meas,eNB_id,0,ue->frame_parms.N_RB_DL,0, transmission_mode,ue->sinr_eff); - - if (((proc->frame_tx % 100) == 0) || (proc->frame_tx < 10)) - print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL); - } else { - ulsch->O_RI = 0; - ulsch->O = 0; - } - - ulsch->harq_processes[harq_pid]->O_ACK = 0;//2; - - ulsch->beta_offset_cqi_times8 = 18; - ulsch->beta_offset_ri_times8 = 10; - ulsch->beta_offset_harqack_times8 = 16; - - ulsch->Nsymb_pusch = 12-(frame_parms->Ncp<<1); - ulsch->rnti = (((uint16_t)rar[4])<<8)+rar[5]; //rar->t_crnti; - - if (ulsch->harq_processes[harq_pid]->round == 0) { - ulsch->harq_processes[harq_pid]->status = ACTIVE; - ulsch->harq_processes[harq_pid]->rvidx = 0; - ulsch->harq_processes[harq_pid]->mcs = ((rar[2]&1)<<3)|(rar[3]>>5); - ulsch->harq_processes[harq_pid]->TPC = (rar[3]>>2)&7; - //ulsch->harq_processes[harq_pid]->TBS = dlsch_tbs25[ulsch->harq_processes[harq_pid]->mcs][ulsch->harq_processes[harq_pid]->nb_rb-1]; - ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; - ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; - ulsch->harq_processes[harq_pid]->Nsymb_initial = 9; - ulsch->harq_processes[harq_pid]->round = 0; - } else { - ulsch->harq_processes[harq_pid]->rvidx = 0; - ulsch->harq_processes[harq_pid]->round++; - } - - // initialize power control based on PRACH power - ulsch->f_pusch = delta_PUSCH_msg2[ulsch->harq_processes[harq_pid]->TPC] + - get_deltaP_rampup(ue->Mod_id,ue->CC_id); - LOG_D(PHY,"[UE %d][PUSCH PC] Initializing f_pusch to %d dB, TPC %d (delta_PUSCH_msg2 %d dB), deltaP_rampup %d dB\n", - ue->Mod_id,ulsch->f_pusch,ulsch->harq_processes[harq_pid]->TPC,delta_PUSCH_msg2[ulsch->harq_processes[harq_pid]->TPC], - get_deltaP_rampup(ue->Mod_id,ue->CC_id)); - - - //#ifdef DEBUG_RAR - LOG_D(PHY,"ulsch ra (UE): harq_pid %d\n",harq_pid); - LOG_D(PHY,"ulsch ra (UE): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); - LOG_D(PHY,"ulsch ra (UE): first_rb %x\n",ulsch->harq_processes[harq_pid]->first_rb); - LOG_D(PHY,"ulsch ra (UE): nb_rb %d\n",ulsch->harq_processes[harq_pid]->nb_rb); - LOG_D(PHY,"ulsch ra (UE): round %d\n",ulsch->harq_processes[harq_pid]->round); - LOG_D(PHY,"ulsch ra (UE): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); - LOG_D(PHY,"ulsch ra (UE): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); - LOG_D(PHY,"ulsch ra (UE): TPC %d\n",ulsch->harq_processes[harq_pid]->TPC); - LOG_D(PHY,"ulsch ra (UE): O %d\n",ulsch->O); - LOG_D(PHY,"ulsch ra (UE): ORI %d\n",ulsch->O_RI); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_RAR,VCD_FUNCTION_OUT); - - //#endif - return(0); -} - diff --git a/openair1/PHY/LTE_TRANSPORT/sss.c b/openair1/PHY/LTE_TRANSPORT/sss.c index 17a4680c54f7a19beee1b91225b9ef54095ea672..bf03c185ef9664790957fafbb22a2295c8e24bfd 100644 --- a/openair1/PHY/LTE_TRANSPORT/sss.c +++ b/openair1/PHY/LTE_TRANSPORT/sss.c @@ -29,9 +29,9 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "transport_eNB.h" +#include "PHY/phy_extern.h" //#define DEBUG_SSS @@ -82,383 +82,3 @@ int generate_sss(int32_t **txdataF, return(0); } -int pss_ch_est(PHY_VARS_UE *ue, - int32_t pss_ext[4][72], - int32_t sss_ext[4][72]) -{ - - int16_t *pss; - int16_t *pss_ext2,*sss_ext2,*sss_ext3,tmp_re,tmp_im,tmp_re2,tmp_im2; - uint8_t aarx,i; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - - switch (ue->common_vars.eNb_id) { - - case 0: - pss = &primary_synch0[10]; - break; - - case 1: - pss = &primary_synch1[10]; - break; - - case 2: - pss = &primary_synch2[10]; - break; - - default: - pss = &primary_synch0[10]; - break; - } - - sss_ext3 = (int16_t*)&sss_ext[0][5]; - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - sss_ext2 = (int16_t*)&sss_ext[aarx][5]; - pss_ext2 = (int16_t*)&pss_ext[aarx][5]; - - for (i=0; i<62; i++) { - - // This is H*(PSS) = R* \cdot PSS - tmp_re = (int16_t)(((pss_ext2[i<<1] * (int32_t)pss[i<<1])>>15) + ((pss_ext2[1+(i<<1)] * (int32_t)pss[1+(i<<1)])>>15)); - tmp_im = (int16_t)(((pss_ext2[i<<1] * (int32_t)pss[1+(i<<1)])>>15) - ((pss_ext2[1+(i<<1)] * (int32_t)pss[(i<<1)])>>15)); - // printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im); - // This is R(SSS) \cdot H*(PSS) - tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i<<1])>>15) - ((tmp_im * (int32_t)sss_ext2[1+(i<<1)]>>15))); - tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[1+(i<<1)])>>15) + ((tmp_im * (int32_t)sss_ext2[(i<<1)]>>15))); - - // printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]); - // printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2); - // MRC on RX antennas - if (aarx==0) { - sss_ext3[i<<1] = tmp_re2; - sss_ext3[1+(i<<1)] = tmp_im2; - } else { - sss_ext3[i<<1] += tmp_re2; - sss_ext3[1+(i<<1)] += tmp_im2; - } - } - } - - // sss_ext now contains the compensated SSS - return(0); -} - - -int _do_pss_sss_extract(PHY_VARS_UE *ue, - int32_t pss_ext[4][72], - int32_t sss_ext[4][72], - uint8_t doPss, uint8_t doSss, - uint8_t subframe) // add flag to indicate extracting only PSS, only SSS, or both -{ - - - - uint16_t rb,nb_rb=6; - uint8_t i,aarx; - int32_t *pss_rxF,*pss_rxF_ext; - int32_t *sss_rxF,*sss_rxF_ext; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - uint8_t next_thread_id = ue->current_thread_id[subframe]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe]+1); - - int rx_offset = frame_parms->ofdm_symbol_size-3*12; - uint8_t pss_symb,sss_symb; - - int32_t **rxdataF; - - //LOG_I(PHY,"do_pss_sss_extract subframe %d \n",subframe); - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - if (frame_parms->frame_type == FDD) { - pss_symb = 6-frame_parms->Ncp; - sss_symb = pss_symb-1; - - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; - pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; - sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; - - } else { - pss_symb = 2; - sss_symb = frame_parms->symbols_per_tti-1; - - if(subframe==5 || subframe==0) - { - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; - sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; - - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; - pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; - } - else if(subframe==6 || subframe==1) - { - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; - pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; - - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; - sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; - } - else - { - AssertFatal(0,""); - } - - } - //printf("extract_rbs: symbol_mod=%d, rx_offset=%d, ch_offset=%d\n",symbol_mod, - // (rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))*2, - // LTE_CE_OFFSET+ch_offset+(symbol_mod*(frame_parms->ofdm_symbol_size))); - - pss_rxF_ext = &pss_ext[aarx][0]; - sss_rxF_ext = &sss_ext[aarx][0]; - - for (rb=0; rb<nb_rb; rb++) { - // skip DC carrier - if (rb==3) { - if(frame_parms->frame_type == FDD) - { - sss_rxF = &rxdataF[aarx][(1 + (sss_symb*(frame_parms->ofdm_symbol_size)))]; - pss_rxF = &rxdataF[aarx][(1 + (pss_symb*(frame_parms->ofdm_symbol_size)))]; - } - else - { - if(subframe==5 || subframe==0) - { - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; - sss_rxF = &rxdataF[aarx][(1 + (sss_symb*(frame_parms->ofdm_symbol_size)))]; - - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; - pss_rxF = &rxdataF[aarx][(1 + (pss_symb*(frame_parms->ofdm_symbol_size)))]; - } - else if(subframe==6 || subframe==1) - { - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; - pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; - - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; - sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; - } - else - { - AssertFatal(0,""); - } - } - } - - for (i=0; i<12; i++) { - if (doPss) {pss_rxF_ext[i]=pss_rxF[i];} - if (doSss) {sss_rxF_ext[i]=sss_rxF[i];} - } - - pss_rxF+=12; - sss_rxF+=12; - pss_rxF_ext+=12; - sss_rxF_ext+=12; - } - - } - - return(0); -} - -int pss_sss_extract(PHY_VARS_UE *phy_vars_ue, - int32_t pss_ext[4][72], - int32_t sss_ext[4][72], - uint8_t subframe) -{ - return _do_pss_sss_extract(phy_vars_ue, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe); -} - -int pss_only_extract(PHY_VARS_UE *phy_vars_ue, - int32_t pss_ext[4][72], - uint8_t subframe) -{ - static int32_t dummy[4][72]; - return _do_pss_sss_extract(phy_vars_ue, pss_ext, dummy, 1 /* doPss */, 0 /* doSss */, subframe); -} - - -int sss_only_extract(PHY_VARS_UE *phy_vars_ue, - int32_t sss_ext[4][72], - uint8_t subframe) -{ - static int32_t dummy[4][72]; - return _do_pss_sss_extract(phy_vars_ue, dummy, sss_ext, 0 /* doPss */, 1 /* doSss */, subframe); -} - - -int16_t phase_re[7] = {16383, 25101, 30791, 32767, 30791, 25101, 16383}; -int16_t phase_im[7] = {-28378, -21063, -11208, 0, 11207, 21062, 28377}; - - -int rx_sss(PHY_VARS_UE *ue,int32_t *tot_metric,uint8_t *flip_max,uint8_t *phase_max) -{ - - uint8_t i; - int32_t pss_ext[4][72]; - int32_t sss0_ext[4][72],sss5_ext[4][72]; - uint8_t Nid2 = ue->common_vars.eNb_id; - uint8_t flip,phase; - uint16_t Nid1; - int16_t *sss0,*sss5; - LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - int32_t metric; - int16_t *d0,*d5; - - if (frame_parms->frame_type == FDD) { -#ifdef DEBUG_SSS - - if (frame_parms->Ncp == NORMAL) - msg("[PHY][UE%d] Doing SSS for FDD Normal Prefix\n",ue->Mod_id); - else - msg("[PHY][UE%d] Doing SSS for FDD Extended Prefix\n",ue->Mod_id); - -#endif - // Do FFTs for SSS/PSS - // SSS - slot_fep(ue, - (frame_parms->symbols_per_tti/2)-2, // second to last symbol of - 0, // slot 0 - ue->rx_offset, - 0, - 1); - // PSS - slot_fep(ue, - (frame_parms->symbols_per_tti/2)-1, // last symbol of - 0, // slot 0 - ue->rx_offset, - 0, - 1); - } else { // TDD -#ifdef DEBUG_SSS - if (ue->frame_parms->Ncp == NORMAL) - msg("[PHY][UE%d] Doing SSS for TDD Normal Prefix\n",ue->Mod_id); - else - msg("[PHY][UE%d] Doing SSS for TDD Extended Prefix\n",ue->Mod_id); - -#endif - // SSS - slot_fep(ue, - (frame_parms->symbols_per_tti>>1)-1, // last symbol of - 1, // slot 1 - ue->rx_offset, - 0, - 1); - // PSS - slot_fep(ue, - 2, // symbol 2 of - 2, // slot 2 - ue->rx_offset, - 0, - 1); - } - // pss sss extract for subframe 0 - pss_sss_extract(ue, - pss_ext, - sss0_ext,0); - /* - write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_tti,1,1); - write_output("rxdataF0.m","rxF0",&ue->common_vars.rxdataF[0][0],2*14*ue->frame_parms.ofdm_symbol_size,2,1); - write_output("pss_ext0.m","pssext0",pss_ext,72,1,1); - write_output("sss0_ext0.m","sss0ext0",sss0_ext,72,1,1); - */ - - // get conjugated channel estimate from PSS (symbol 6), H* = R* \cdot PSS - // and do channel estimation and compensation based on PSS - - pss_ch_est(ue, - pss_ext, - sss0_ext); - - // write_output("sss0_comp0.m","sss0comp0",sss0_ext,72,1,1); - - if (ue->frame_parms.frame_type == FDD) { // FDD - - // SSS - slot_fep(ue, - (frame_parms->symbols_per_tti/2)-2, - 10, - ue->rx_offset, - 0,1); - // PSS - slot_fep(ue, - (frame_parms->symbols_per_tti/2)-1, - 10, - ue->rx_offset, - 0,1); - } else { // TDD - // SSS - slot_fep(ue, - (frame_parms->symbols_per_tti>>1)-1, - 11, - ue->rx_offset, - 0, - 1); - // PSS - slot_fep(ue, - 2, - 12, - ue->rx_offset, - 0, - 1); - } - - // pss sss extract for subframe 5 - pss_sss_extract(ue, - pss_ext, - sss5_ext,5); - - // write_output("sss5_ext0.m","sss5ext0",sss5_ext,72,1,1); - // get conjugated channel estimate from PSS (symbol 6), H* = R* \cdot PSS - // and do channel estimation and compensation based on PSS - - pss_ch_est(ue, - pss_ext, - sss5_ext); - - - - // now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h - - *tot_metric = -99999999; - - - sss0 = (int16_t*)&sss0_ext[0][5]; - sss5 = (int16_t*)&sss5_ext[0][5]; - - for (flip=0; flip<2; flip++) { // d0/d5 flip in RX frame - for (phase=0; phase<7; phase++) { // phase offset between PSS and SSS - for (Nid1 = 0 ; Nid1 <= 167; Nid1++) { // 168 possible Nid1 values - metric = 0; - - if (flip==0) { - d0 = &d0_sss[62*(Nid2 + (Nid1*3))]; - d5 = &d5_sss[62*(Nid2 + (Nid1*3))]; - } else { - d5 = &d0_sss[62*(Nid2 + (Nid1*3))]; - d0 = &d5_sss[62*(Nid2 + (Nid1*3))]; - } - - // This is the inner product using one particular value of each unknown parameter - for (i=0; i<62; i++) { - metric += (int16_t)(((d0[i]*((((phase_re[phase]*(int32_t)sss0[i<<1])>>19)-((phase_im[phase]*(int32_t)sss0[1+(i<<1)])>>19)))) + - (d5[i]*((((phase_re[phase]*(int32_t)sss5[i<<1])>>19)-((phase_im[phase]*(int32_t)sss5[1+(i<<1)])>>19)))))); - } - - // if the current metric is better than the last save it - if (metric > *tot_metric) { - *tot_metric = metric; - ue->frame_parms.Nid_cell = Nid2+(3*Nid1); - *phase_max = phase; - *flip_max=flip; -#ifdef DEBUG_SSS - msg("(flip,phase,Nid1) (%d,%d,%d), metric_phase %d tot_metric %d, phase_max %d, flip_max %d\n",flip,phase,Nid1,metric,*tot_metric,*phase_max,*flip_max); -#endif - - } - } - } - } - - return(0); -} - diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h new file mode 100644 index 0000000000000000000000000000000000000000..167e2b111a566a7929e1f76cc3003a41623ea756 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h @@ -0,0 +1,282 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/transport_commont.h +* \brief data structures for PDSCH/DLSCH/PUSCH/ULSCH physical and transport channel descriptors (TX/RX) common to both eNB/UE +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr, florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it +* \note +* \warning +*/ +#ifndef __TRANSPORT_COMMON__H__ +#define __TRANSPORT_COMMON__H__ +#include "PHY/defs_common.h" +#include "PHY/impl_defs_lte.h" +#include "dci.h" +#include "mdci.h" +//#include "uci.h" +#ifndef STANDALONE_COMPILE +#include "UTIL/LISTS/list.h" +#endif + +#define MOD_TABLE_QPSK_OFFSET 1 +#define MOD_TABLE_16QAM_OFFSET 5 +#define MOD_TABLE_64QAM_OFFSET 21 +#define MOD_TABLE_PSS_OFFSET 85 + +// structures below implement 36-211 and 36-212 + +/** @addtogroup _PHY_TRANSPORT_ + * @{ + */ + + + +#define NSOFT 1827072 +#define LTE_NULL 2 + +// maximum of 3 segments before each coding block if data length exceeds 6144 bits. + +#define MAX_NUM_DLSCH_SEGMENTS 16 +#define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS +#define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768) +#define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768) + +#define MAX_NUM_CHANNEL_BITS (14*1200*6) // 14 symbols, 1200 REs, 12 bits/RE +#define MAX_NUM_RE (14*1200) + +#if !defined(SI_RNTI) +#define SI_RNTI (rnti_t)0xffff +#endif +#if !defined(M_RNTI) +#define M_RNTI (rnti_t)0xfffd +#endif +#if !defined(P_RNTI) +#define P_RNTI (rnti_t)0xfffe +#endif +#if !defined(CBA_RNTI) +#define CBA_RNTI (rnti_t)0xfff4 +#endif +#if !defined(C_RNTI) +#define C_RNTI (rnti_t)0x1234 +#endif +// These are the codebook indexes according to Table 6.3.4.2.3-1 of 36.211 +//1 layer +#define PMI_2A_11 0 +#define PMI_2A_1m1 1 +#define PMI_2A_1j 2 +#define PMI_2A_1mj 3 +//2 layers +#define PMI_2A_R1_10 0 +#define PMI_2A_R1_11 1 +#define PMI_2A_R1_1j 2 + +typedef enum { SEARCH_EXIST=0, + SEARCH_EXIST_OR_FREE} find_type_t; + +typedef enum { + SCH_IDLE=0, + ACTIVE, + CBA_ACTIVE, + DISABLED +} SCH_status_t; + + + + +#ifdef Rel14 +typedef enum { + CEmodeA = 0, + CEmodeB = 1 +} CEmode_t; +#endif + +#define PUSCH_x 2 +#define PUSCH_y 3 + +typedef enum { + pucch_format1=0, + pucch_format1a, + pucch_format1b, + pucch_format1b_csA2, + pucch_format1b_csA3, + pucch_format1b_csA4, + pucch_format2, + pucch_format2a, + pucch_format2b, + pucch_format3 // PUCCH format3 +} PUCCH_FMT_t; + +typedef enum { + SR, + HARQ, + CQI, + HARQ_SR, + HARQ_CQI, + SR_CQI, + HARQ_SR_CQI +} UCI_type_t; + +#ifdef Rel14 +typedef enum { + NOCE, + CEMODEA, + CEMODEB +} UE_type_t; +#endif + + + + + +typedef enum { + SI_PDSCH=0, + RA_PDSCH, + P_PDSCH, + PDSCH, + PDSCH1, + PMCH +} PDSCH_t; + +typedef enum { + rx_standard=0, + rx_IC_single_stream, + rx_IC_dual_stream, + rx_SIC_dual_stream +} RX_type_t; + + +typedef enum { + DCI_COMMON_SPACE, + DCI_UE_SPACE +} dci_space_t; + +typedef struct { + uint8_t f_ra; + uint8_t t0_ra; + uint8_t t1_ra; + uint8_t t2_ra; +} PRACH_TDD_PREAMBLE_MAP_elem; +typedef struct { + uint8_t num_prach; + PRACH_TDD_PREAMBLE_MAP_elem map[6]; +} PRACH_TDD_PREAMBLE_MAP; + +#ifdef Rel14 + +typedef struct { + uint16_t slss_id; + uint8_t *slmib; +} SLSS_t; + +typedef struct { + // SL Configuration + /// Number of SL resource blocks (1-100) + uint32_t N_SL_RB; + /// prb-start (0-99) + uint32_t prb_Start; + /// prb-End (0-99) + uint32_t prb_End; + /// SL-OffsetIndicator (0-10239) + uint32_t SL_OffsetIndicator; + /// PSCCH subframe bitmap, first 64-bits (up to 40 bits for Rel 12) + uint64_t bitmap1; + /// PSCCH subframe bitmap, 2nd 64-bits (up to 100 bits for Rel 14) + uint64_t bitmap2; + + // SCI parameters + /// npscch resource index + uint32_t n_pscch; + /// format of SCI (0,1) + uint32_t format; + /// SCI0 frequency hopping flag + uint32_t freq_hopping_flag; + /// SCI0 Resource Block Coding + uint32_t resource_block_coding; + /// SCI0 Time Resource Pattern for SLSCH + uint32_t time_resource_pattern; + /// SCI0 MCS for SLSCH + uint32_t mcs; + /// SCI0 Timing advance indication for SLSCH + uint32_t timing_advance_indication; + /// SCI0 Group Destination ID for SLSCH + uint32_t group_destination_id; + + // SLSCH Parameters + /// Number of Subbands (36.213 14.1.1.2) + uint32_t Nsb; + /// N_RB_HO (36.213 14.1.1.2) + uint32_t N_RB_HO; + /// n_ss_PSSCH (36.211 9.2.4) + uint32_t n_ss_PSSCH; + /// n_ssf_PSSCH + uint32_t n_ssf_PSSCH; + /// cinit (36.331 hoppingParameter-r12) + uint32_t cinit; + /// redundancy version + uint32_t rvidx; + /// n_prime_VRB (36.213 14.1.1.2.1) + uint32_t n_prime_VRB; + /// M_RB_PSSCH_RP (36.213 14.1.3 + uint32_t M_RB_PSSCH_RP; + /// n_prime_PRB (36.213 14.1.1.4 + uint32_t n_prime_PRB; + /// m_nprime_PRB_PSSCH (36.213 14.1.3) + uint32_t m_nprime_PRB_PSCCH; + /// payload length + int payload_length; + /// pointer to payload + uint8_t *payload; +} SLSCH_t; + +typedef struct { + /// payload length + int payload_length; + uint8_t payload[100]; +} SLDCH_t; + +#define TTI_SYNC 0 +#define SLSS 1 +#define SLDCH 2 +#define SLSCH 3 + +typedef struct UE_tport_header_s { + int packet_type; + uint16_t absSF; +} UE_tport_header_t; + +typedef struct UE_tport_s { + UE_tport_header_t header; + union { + SLSS_t slss; + SLDCH_t sldch; + SLSCH_t slsch; + }; + uint8_t payload[1500]; +} UE_tport_t; + +#endif + +/**@}*/ +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h new file mode 100644 index 0000000000000000000000000000000000000000..0cc59360b612c57a7846abe5d4378a0517b791a7 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h @@ -0,0 +1,296 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/transport_proto.h + * \brief Function prototypes for eNB PHY physical/transport channel processing and generation V8.6 2009-03 + * \author R. Knopp, F. Kaltenberger + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_COMMON_PROTO__H__ +#define __LTE_TRANSPORT_COMMON_PROTO__H__ +#include "PHY/defs_common.h" + + + + +// Functions below implement minor procedures from 36-211 and 36-212 + +/** \brief Compute Q (modulation order) based on I_MCS PDSCH. Implements table 7.1.7.1-1 from 36.213. + @param I_MCS */ +uint8_t get_Qm(uint8_t I_MCS); + +/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213. + @param I_MCS */ +uint8_t get_Qm_ul(uint8_t I_MCS); + +/** \brief Compute I_TBS (transport-block size) based on I_MCS for PDSCH. Implements table 7.1.7.1-1 from 36.213. + @param I_MCS */ +uint8_t get_I_TBS(uint8_t I_MCS); + +/** \brief Compute I_TBS (transport-block size) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213. + @param I_MCS */ +unsigned char get_I_TBS_UL(unsigned char I_MCS); + +/** \brief Compute Q (modulation order) based on downlink I_MCS. Implements table 7.1.7.1-1 from 36.213. + @param I_MCS + @param nb_rb + @return Transport block size */ +uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb); + +/** \brief Compute Q (modulation order) based on uplink I_MCS. Implements table 7.1.7.1-1 from 36.213. + @param I_MCS + @param nb_rb + @return Transport block size */ +uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb); + +/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type + @param N_RB_DL number of PRB on DL + @param indicator for even/odd slot + @param vrb vrb index + @param Ngap Gap indicator +*/ +uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap); + +/* \brief Return prb for a given vrb index + @param vrb_type VRB type (0=localized,1=distributed) + @param rb_alloc_dci rballoc field from DCI +*/ +uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci); + + +/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type + @returns Transmission mode (1-7) +*/ +uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti); + + +/* \brief + @param ra_header Header of resource allocation (0,1) (See sections 7.1.6.1/7.1.6.2 of 36.213 Rel8.6) + @param rb_alloc Bitmap allocation from DCI (format 1,2) + @returns number of physical resource blocks +*/ +uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL); + +int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode); + +int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe); +int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol); + + +#ifndef modOrder +#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS +#endif + +/** \fn uint8_t I_TBS2I_MCS(uint8_t I_TBS); + \brief This function maps I_tbs to I_mcs according to Table 7.1.7.1-1 in 3GPP TS 36.213 V8.6.0. Where there is two supported modulation orders for the same I_TBS then either high or low modulation is chosen by changing the equality of the two first comparisons in the if-else statement. + \param I_TBS Index of Transport Block Size + \return I_MCS given I_TBS +*/ +uint8_t I_TBS2I_MCS(uint8_t I_TBS); + +/** \fn uint8_t SE2I_TBS(float SE, + uint8_t N_PRB, + uint8_t symbPerRB); + \brief This function maps a requested throughput in number of bits to I_tbs. The throughput is calculated as a function of modulation order, RB allocation and number of symbols per RB. The mapping orginates in the "Transport block size table" (Table 7.1.7.2.1-1 in 3GPP TS 36.213 V8.6.0) + \param SE Spectral Efficiency (before casting to integer, multiply by 1024, remember to divide result by 1024!) + \param N_PRB Number of PhysicalResourceBlocks allocated \sa lte_frame_parms->N_RB_DL + \param symbPerRB Number of symbols per resource block allocated to this channel + \return I_TBS given an SE and an N_PRB +*/ +uint8_t SE2I_TBS(float SE, + uint8_t N_PRB, + uint8_t symbPerRB); +/** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 36.211 v8.6.0. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence. + @param frame_parms LTE DL Frame Parameters + @param soundingrs_ul_config_dedicated Dynamic configuration from RRC during Connection Establishment + @param txdataF pointer to the frequency domain TX signal + @returns 0 on success*/ + +int generate_srs(LTE_DL_FRAME_PARMS *frame_parms, + SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated, + int *txdataF, + int16_t amp, + uint32_t subframe); + + +/*! + \brief This function generates the downlink reference signal for the PUSCH according to 36.211 v8.6.0. The DRS occuies the RS defined by rb_alloc and the symbols 2 and 8 for extended CP and 3 and 10 for normal CP. +*/ + + +/*! + \brief This function initializes the Group Hopping, Sequence Hopping and nPRS sequences for PUCCH/PUSCH according to 36.211 v8.6.0. It should be called after configuration of UE (reception of SIB2/3) and initial configuration of eNB (or after reconfiguration of cell-specific parameters). + @param frame_parms Pointer to a LTE_DL_FRAME_PARMS structure (eNB or UE)*/ +void init_ul_hopping(LTE_DL_FRAME_PARMS *frame_parms); + + +int32_t compareints (const void * a, const void * b); + +uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe); + +int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci); + +void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms); + +void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms); + +uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi); + +void generate_RIV_tables(void); + +/** \brief This routine provides the relationship between a PHICH TXOp and its corresponding PUSCH subframe (Table 8.3.-1 from 36.213). + @param frame_parms Pointer to DL frame configuration parameters + @param subframe Subframe of received/transmitted PHICH + @returns subframe of PUSCH transmission +*/ +uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); + +/** \brief This routine provides the relationship between a PHICH TXOp and its corresponding PUSCH frame (Table 8.3.-1 from 36.213). + @param frame_parms Pointer to DL frame configuration parameters + @param frame Frame of received/transmitted PHICH + @param subframe Subframe of received/transmitted PHICH + @returns frame of PUSCH transmission +*/ +int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe); + +uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); + +int get_nCCE_offset_l1(int *CCE_table, + const unsigned char L, + const int nCCE, + const int common_dci, + const unsigned short rnti, + const unsigned char subframe); + +uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi); + +uint16_t get_nquad(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi); + +uint8_t get_mi(LTE_DL_FRAME_PARMS *frame,uint8_t subframe); + +uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe); + +uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); + +void init_ncs_cell(LTE_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]); + +/*! + \brief Check for PRACH TXop in subframe + @param frame_parms Pointer to LTE_DL_FRAME_PARMS + @param frame frame index to check + @param subframe subframe index to check + @returns 0 on success +*/ +int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t subframe); + +/*! + \brief Helper for MAC, returns number of available PRACH in TDD for a particular configuration index + @param frame_parms Pointer to LTE_DL_FRAME_PARMS structure + @returns 0-5 depending on number of available prach +*/ +uint8_t get_num_prach_tdd(module_id_t Mod_id); + +/*! + \brief Return the PRACH format as a function of the Configuration Index and Frame type. + @param prach_ConfigIndex PRACH Configuration Index + @param frame_type 0-FDD, 1-TDD + @returns 0-1 accordingly +*/ +uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type); + +/*! + \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index + @param frame_parms Pointer to LTE_DL_FRAME_PARMS structure + @returns 0-5 depending on number of available prach +*/ +uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index); + +/*! + \brief Comp ute DFT of PRACH ZC sequences. Used for generation of prach in UE and reception of PRACH in eNB. + @param rootSequenceIndex PRACH root sequence + #param prach_ConfigIndex PRACH Configuration Index + @param zeroCorrelationZoneConfig PRACH ncs_config + @param highSpeedFlat PRACH High-Speed Flag + @param frame_type TDD/FDD flag + @param Xu DFT output +*/ +void compute_prach_seq(uint16_t rootSequenceIndex, + uint8_t prach_ConfigIndex, + uint8_t zeroCorrelationZoneConfig, + uint8_t highSpeedFlag, + lte_frame_type_t frame_type, + uint32_t X_u[64][839]); + + +void init_prach_tables(int N_ZC); + +/*! + \brief Return the status of MBSFN in this frame/subframe + @param frame Frame index + @param subframe Subframe index + @param frame_parms Pointer to frame parameters + @returns 1 if subframe is for MBSFN +*/ +int is_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); + + +/** \brief This routine expands a single (wideband) PMI to subband PMI bitmap similar to the one used in the UCI and in the dlsch_modulation routine + @param frame_parms Pointer to DL frame configuration parameters + @param wideband_pmi (0,1,2,3 for rank 0 and 0,1 for rank 1) + @param rank (0 or 1) + @returns subband PMI bitmap +*/ +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank); + +uint64_t pmi2hex_2Ar1(uint32_t pmi); + +uint64_t pmi2hex_2Ar2(uint32_t pmi); + +uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb); + +// DL power control functions +double get_pa_dB(uint8_t pa); + +void init_scrambling_lut(void); + +void init_unscrambling_lut(void); + + +uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t prach_ConfigIndex, + uint8_t n_ra_prboffset, + uint8_t tdd_mapindex, uint16_t Nf); + +uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe); +uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); + +uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL); + +void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2); + +int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs); + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h similarity index 55% rename from openair1/PHY/LTE_TRANSPORT/defs.h rename to openair1/PHY/LTE_TRANSPORT/transport_eNB.h index aa465cfa572a208234f735799d2d8093a130ff32..d1dd595d3599ad248f0776f5834dc8cb6670a6d8 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -29,21 +29,18 @@ * \note * \warning */ -#ifndef __LTE_TRANSPORT_DEFS__H__ -#define __LTE_TRANSPORT_DEFS__H__ -#include "PHY/defs.h" +#ifndef __TRANSPORT_ENB__H__ +#define __TRANSPORT_ENB__H__ +#include "transport_common.h" +//#include "PHY/defs_eNB.h" #include "PHY/impl_defs_lte.h" #include "dci.h" #include "mdci.h" -#include "uci.h" +#include "uci_common.h" #ifndef STANDALONE_COMPILE #include "UTIL/LISTS/list.h" #endif -#define MOD_TABLE_QPSK_OFFSET 1 -#define MOD_TABLE_16QAM_OFFSET 5 -#define MOD_TABLE_64QAM_OFFSET 21 -#define MOD_TABLE_PSS_OFFSET 85 // structures below implement 36-211 and 36-212 @@ -53,62 +50,6 @@ -#define NSOFT 1827072 -#define LTE_NULL 2 - -// maximum of 3 segments before each coding block if data length exceeds 6144 bits. - -#define MAX_NUM_DLSCH_SEGMENTS 16 -#define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS -#define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768) -#define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768) - -#define MAX_NUM_CHANNEL_BITS (14*1200*6) // 14 symbols, 1200 REs, 12 bits/RE -#define MAX_NUM_RE (14*1200) - -#if !defined(SI_RNTI) -#define SI_RNTI (rnti_t)0xffff -#endif -#if !defined(M_RNTI) -#define M_RNTI (rnti_t)0xfffd -#endif -#if !defined(P_RNTI) -#define P_RNTI (rnti_t)0xfffe -#endif -#if !defined(CBA_RNTI) -#define CBA_RNTI (rnti_t)0xfff4 -#endif -#if !defined(C_RNTI) -#define C_RNTI (rnti_t)0x1234 -#endif -// These are the codebook indexes according to Table 6.3.4.2.3-1 of 36.211 -//1 layer -#define PMI_2A_11 0 -#define PMI_2A_1m1 1 -#define PMI_2A_1j 2 -#define PMI_2A_1mj 3 -//2 layers -#define PMI_2A_R1_10 0 -#define PMI_2A_R1_11 1 -#define PMI_2A_R1_1j 2 - -typedef enum { SEARCH_EXIST=0, - SEARCH_EXIST_OR_FREE} find_type_t; - -typedef enum { - SCH_IDLE=0, - ACTIVE, - CBA_ACTIVE, - DISABLED -} SCH_status_t; - -#ifdef Rel14 -typedef enum { - CEmodeA = 0, - CEmodeB = 1 -} CEmode_t; -#endif - typedef struct { /// Status Flag indicating for this DLSCH (idle,active,disabled) SCH_status_t status; @@ -195,85 +136,12 @@ typedef struct { #endif } LTE_DL_eNB_HARQ_t; -typedef struct { - /// Indicator of first transmission - uint8_t first_tx; - /// Last Ndi received for this process on DCI (used for C-RNTI only) - uint8_t DCINdi; - /// Flag indicating that this ULSCH has a new packet (start of new round) - // uint8_t Ndi; - /// Status Flag indicating for this ULSCH (idle,active,disabled) - SCH_status_t status; - /// Subframe scheduling indicator (i.e. Transmission opportunity indicator) - uint8_t subframe_scheduling_flag; - /// Subframe cba scheduling indicator (i.e. Transmission opportunity indicator) - uint8_t subframe_cba_scheduling_flag; - /// First Allocated RB - uint16_t first_rb; - /// Current Number of RBs - uint16_t nb_rb; - /// Last TPC command - uint8_t TPC; - /// Transport block size - uint32_t TBS; - /// The payload + CRC size in bits, "B" from 36-212 - uint32_t B; - /// Length of ACK information (bits) - uint8_t O_ACK; - /// Pointer to the payload - uint8_t *b; - /// Pointers to transport block segments - uint8_t *c[MAX_NUM_ULSCH_SEGMENTS]; - /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) - uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS]; - /// Index of current HARQ round for this ULSCH - uint8_t round; - /// MCS format of this ULSCH - uint8_t mcs; - /// Redundancy-version of the current sub-frame - uint8_t rvidx; - /// Turbo-code outputs (36-212 V8.6 2009-03, p.12 - uint8_t d[MAX_NUM_ULSCH_SEGMENTS][(96+3+(3*6144))]; - /// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17) - uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144]; - /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) - uint32_t C; - /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Cminus; - /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Cplus; - /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Kminus; - /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Kplus; - /// Total number of bits across all segments - uint32_t sumKr; - /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t F; - /// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27) - uint16_t Msc_initial; - /// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27) - uint8_t Nsymb_initial; - /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - uint8_t n_DMRS; - /// n_DMRS2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1) - uint8_t n_DMRS2; - /// Flag to indicate that this is a control only ULSCH (i.e. no MAC SDU) - uint8_t control_only; - /// Flag to indicate that this is a calibration ULSCH (i.e. no MAC SDU and filled with TDD calibration information) - // int calibration_flag; - /// Number of soft channel bits - uint32_t G; - - // decode phich - uint8_t decode_phich; -} LTE_UL_UE_HARQ_t; typedef struct { /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) int32_t *txdataF[8]; /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers? - int32_t **ue_spec_bf_weights[4]; + int32_t **ue_spec_bf_weights[4]; /// dl channel estimates (estimated from ul channel estimates) int32_t **calib_dl_ch_estimates; /// Allocated RNTI (0 means DLSCH_t is not currently used) @@ -315,7 +183,7 @@ typedef struct { /// amplitude of PDSCH (compared to RS) in symbols containing pilots int16_t sqrt_rho_b; #ifndef PHY_TX_THREAD -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// indicator that this DLSCH corresponds to SIB1-BR, needed for c_init for scrambling uint8_t sib1_br_flag; /// initial absolute subframe (see 36.211 Section 6.3.1), needed for c_init for scrambling @@ -325,81 +193,7 @@ typedef struct { #endif } LTE_eNB_DLSCH_t; -#define PUSCH_x 2 -#define PUSCH_y 3 -typedef struct { - /// Current Number of Symbols - uint8_t Nsymb_pusch; - /// SRS active flag - uint8_t srs_active; - /// Pointers to 8 HARQ processes for the ULSCH - LTE_UL_UE_HARQ_t *harq_processes[8]; - /// Pointer to CQI data (+1 for 8 bits crc) - uint8_t o[1+MAX_CQI_BYTES]; - /// Length of CQI data (bits) - uint8_t O; - /// Format of CQI data - UCI_format_t uci_format; - /// Rank information - uint8_t o_RI[2]; - /// Length of rank information (bits) - uint8_t O_RI; - /// Pointer to ACK - uint8_t o_ACK[4]; - /// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37) - uint8_t O_CQI_MIN; - /// ACK/NAK Bundling flag - uint8_t bundling; - /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) - uint8_t e[MAX_NUM_CHANNEL_BITS]; - /// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) - uint8_t h[MAX_NUM_CHANNEL_BITS]; - /// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14) - uint8_t b_tilde[MAX_NUM_CHANNEL_BITS]; - /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14) - int32_t d[MAX_NUM_RE]; - /// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15) - int32_t z[MAX_NUM_RE]; - /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) - uint8_t q[MAX_CQI_PAYLOAD]; - /// coded and interleaved CQI bits - uint8_t o_w[(MAX_CQI_BITS+8)*3]; - /// coded CQI bits - uint8_t o_d[96+((MAX_CQI_BITS+8)*3)]; - /// coded ACK bits - uint8_t q_ACK[MAX_ACK_PAYLOAD]; - /// coded RI bits - uint8_t q_RI[MAX_RI_PAYLOAD]; - /// beta_offset_cqi times 8 - uint16_t beta_offset_cqi_times8; - /// beta_offset_ri times 8 - uint16_t beta_offset_ri_times8; - /// beta_offset_harqack times 8 - uint16_t beta_offset_harqack_times8; - /// power_offset - uint8_t power_offset; - // for cooperative communication - uint8_t cooperation_flag; - /// RNTI attributed to this ULSCH - uint16_t rnti; - /// f_PUSCH parameter for PUSCH power control - int16_t f_pusch; - /// Po_PUSCH - target output power for PUSCH - int16_t Po_PUSCH; - /// PHR - current power headroom (based on last PUSCH transmission) - int16_t PHR; - /// Po_SRS - target output power for SRS - int16_t Po_SRS; - /// num active cba group - uint8_t num_active_cba_groups; - /// num dci found for cba - uint8_t num_cba_dci[10]; - /// allocated CBA RNTI - uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; - /// UL max-harq-retransmission - uint8_t Mlimit; -} LTE_UE_ULSCH_t; typedef struct { /// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK) @@ -427,7 +221,7 @@ typedef struct { /// is done after a new scheduling uint16_t previous_first_rb; /// Current Number of RBs - uint16_t nb_rb; + uint16_t nb_rb; /// Current Modulation order uint8_t Qm; /// Transport block size @@ -524,38 +318,6 @@ typedef struct { int32_t delta_TF; } LTE_UL_eNB_HARQ_t; - -typedef enum { - pucch_format1=0, - pucch_format1a, - pucch_format1b, - pucch_format1b_csA2, - pucch_format1b_csA3, - pucch_format1b_csA4, - pucch_format2, - pucch_format2a, - pucch_format2b, - pucch_format3 // PUCCH format3 -} PUCCH_FMT_t; - -typedef enum { - SR, - HARQ, - CQI, - HARQ_SR, - HARQ_CQI, - SR_CQI, - HARQ_SR_CQI -} UCI_type_t; - -#ifdef Rel14 -typedef enum { - NOCE, - CEMODEA, - CEMODEB -} UE_type_t; -#endif - typedef struct { uint8_t active; /// Absolute frame for this UCI @@ -570,7 +332,7 @@ typedef struct { uint8_t srs_active; /// PUCCH format to use PUCCH_FMT_t pucch_fmt; - /// number of PUCCH antenna ports + /// number of PUCCH antenna ports uint8_t num_antenna_ports; /// number of PUCCH resources uint8_t num_pucch_resources; @@ -586,7 +348,7 @@ typedef struct { uint8_t tdd_bundling; /// Received Energy uint32_t stat; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// non BL/CE, CEmodeA, CEmodeB UE_type_t ue_type; /// Indicates the symbols that are left empty due to eMTC retuning. @@ -606,124 +368,6 @@ typedef struct { #endif } LTE_eNB_UCI; -typedef struct { - /// HARQ process mask, indicates which processes are currently active - uint16_t harq_mask; - /// Pointers to 8 HARQ processes for the ULSCH - LTE_UL_eNB_HARQ_t *harq_processes[8]; - /// Maximum number of HARQ rounds - uint8_t Mlimit; - /// Maximum number of iterations used in eNB turbo decoder - uint8_t max_turbo_iterations; - /// ACK/NAK Bundling flag - uint8_t bundling; - /// beta_offset_cqi times 8 - uint16_t beta_offset_cqi_times8; - /// beta_offset_ri times 8 - uint16_t beta_offset_ri_times8; - /// beta_offset_harqack times 8 - uint16_t beta_offset_harqack_times8; - /// Flag to indicate that eNB awaits UE Msg3 - uint8_t Msg3_active; - /// RNTI attributed to this ULSCH - uint16_t rnti; - /// cyclic shift for DM RS - uint8_t cyclicShift; - /// cooperation flag - uint8_t cooperation_flag; - /// num active cba group - uint8_t num_active_cba_groups; - /// allocated CBA RNTI for this ulsch - uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; -#ifdef LOCALIZATION - /// epoch timestamp in millisecond - int32_t reference_timestamp_ms; - /// aggregate physical states every n millisecond - int32_t aggregation_period_ms; - /// a set of lists used for localization - struct list loc_rss_list[10], loc_rssi_list[10], loc_subcarrier_rss_list[10], loc_timing_advance_list[10], loc_timing_update_list[10]; - struct list tot_loc_rss_list, tot_loc_rssi_list, tot_loc_subcarrier_rss_list, tot_loc_timing_advance_list, tot_loc_timing_update_list; -#endif -} LTE_eNB_ULSCH_t; - -typedef struct { - /// Indicator of first transmission - uint8_t first_tx; - /// Last Ndi received for this process on DCI (used for C-RNTI only) - uint8_t DCINdi; - /// DLSCH status flag indicating - SCH_status_t status; - /// Transport block size - uint32_t TBS; - /// The payload + CRC size in bits - uint32_t B; - /// Pointer to the payload - uint8_t *b; - /// Pointers to transport block segments - uint8_t *c[MAX_NUM_DLSCH_SEGMENTS]; - /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) - uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS]; - /// Index of current HARQ round for this DLSCH - uint8_t round; - /// MCS format for this DLSCH - uint8_t mcs; - /// Qm (modulation order) for this DLSCH - uint8_t Qm; - /// Redundancy-version of the current sub-frame - uint8_t rvidx; - /// MIMO mode for this DLSCH - MIMO_mode_t mimo_mode; - /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - int16_t w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)]; - /// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - double w_abs[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)]; - /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - int16_t *d[MAX_NUM_DLSCH_SEGMENTS]; - /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) - uint32_t C; - /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Cminus; - /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Cplus; - /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Kminus; - /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t Kplus; - /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) - uint32_t F; - /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17) - uint8_t Nl; - /// current delta_pucch - int8_t delta_PUCCH; - /// Number of soft channel bits - uint32_t G; - /// Current Number of RBs - uint16_t nb_rb; - /// Current subband PMI allocation - uint16_t pmi_alloc; - /// Current RB allocation (even slots) - uint32_t rb_alloc_even[4]; - /// Current RB allocation (odd slots) - uint32_t rb_alloc_odd[4]; - /// distributed/localized flag - vrb_t vrb_type; - /// downlink power offset field - uint8_t dl_power_off; - /// trials per round statistics - uint32_t trials[8]; - /// error statistics per round - uint32_t errors[8]; - /// codeword this transport block is mapped to - uint8_t codeword; -} LTE_DL_UE_HARQ_t; - -typedef struct { - /// time-based localization, relying on TA and TOA - double time_based; - /// power-based localization, relying on RSS and RSSI - double power_based; -} eNB_UE_estimated_distances; - typedef struct { /// UL RSSI per receive antenna int32_t UL_rssi[NB_ANTENNAS_RX]; @@ -796,92 +440,38 @@ typedef struct { int total_TBS_last; /// Bitrate on the PDSCH [bps] unsigned int dlsch_bitrate; - // unsigned int total_transmitted_bits; -#ifdef LOCALIZATION - eNB_UE_estimated_distances distance; - int32_t *subcarrier_rssi; -#endif } LTE_eNB_UE_stats; typedef struct { - /// HARQ process id - uint8_t harq_id; - /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX - uint8_t ack; - /// send status (for PUCCH) - uint8_t send_harq_status; - /// nCCE (for PUCCH) - uint8_t nCCE; - /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched - uint8_t vDAI_DL; - /// DAI value detected from DCI0/4. 0xff indicates not touched - uint8_t vDAI_UL; -} harq_status_t; - -typedef struct { - /// RNTI - uint16_t rnti; - /// Active flag for DLSCH demodulation - uint8_t active; - /// Transmission mode - uint8_t mode1_flag; - /// amplitude of PDSCH (compared to RS) in symbols without pilots - int16_t sqrt_rho_a; - /// amplitude of PDSCH (compared to RS) in symbols containing pilots - int16_t sqrt_rho_b; - /// Current HARQ process id threadRx Odd and threadRx Even - uint8_t current_harq_pid; - /// Current subband antenna selection - uint32_t antenna_alloc; - /// Current subband RI allocation - uint32_t ri_alloc; - /// Current subband CQI1 allocation - uint32_t cqi_alloc1; - /// Current subband CQI2 allocation - uint32_t cqi_alloc2; - /// saved subband PMI allocation from last PUSCH/PUCCH report - uint16_t pmi_alloc; - /// HARQ-ACKs - harq_status_t harq_ack[10]; - /// Pointers to up to 8 HARQ processes - LTE_DL_UE_HARQ_t *harq_processes[8]; - /// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17 - uint8_t Mdlharq; - /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) - uint8_t Kmimo; - /// Nsoft parameter related to UE Category - uint32_t Nsoft; - /// Maximum number of Turbo iterations + /// HARQ process mask, indicates which processes are currently active + uint16_t harq_mask; + /// Pointers to 8 HARQ processes for the ULSCH + LTE_UL_eNB_HARQ_t *harq_processes[8]; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Maximum number of iterations used in eNB turbo decoder uint8_t max_turbo_iterations; - /// number of iterations used in last turbo decoding - uint8_t last_iteration_cnt; - /// accumulated tx power adjustment for PUCCH - int8_t g_pucch; -} LTE_UE_DLSCH_t; - - - -typedef enum { - SI_PDSCH=0, - RA_PDSCH, - P_PDSCH, - PDSCH, - PDSCH1, - PMCH -} PDSCH_t; - -typedef enum { - rx_standard=0, - rx_IC_single_stream, - rx_IC_dual_stream, - rx_SIC_dual_stream -} RX_type_t; - - -typedef enum { - DCI_COMMON_SPACE, - DCI_UE_SPACE -} dci_space_t; + /// ACK/NAK Bundling flag + uint8_t bundling; + /// beta_offset_cqi times 8 + uint16_t beta_offset_cqi_times8; + /// beta_offset_ri times 8 + uint16_t beta_offset_ri_times8; + /// beta_offset_harqack times 8 + uint16_t beta_offset_harqack_times8; + /// Flag to indicate that eNB awaits UE Msg3 + uint8_t Msg3_active; + /// RNTI attributed to this ULSCH + uint16_t rnti; + /// cyclic shift for DM RS + uint8_t cyclicShift; + /// cooperation flag + uint8_t cooperation_flag; + /// num active cba group + uint8_t num_active_cba_groups; + /// allocated CBA RNTI for this ulsch + uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; +} LTE_eNB_ULSCH_t; /**@}*/ diff --git a/openair1/PHY/LTE_TRANSPORT/extern.h b/openair1/PHY/LTE_TRANSPORT/transport_extern.h similarity index 95% rename from openair1/PHY/LTE_TRANSPORT/extern.h rename to openair1/PHY/LTE_TRANSPORT/transport_extern.h index e791bec9a0c27f45fd047acc46f510d590684f69..6a9fa49405a9bb3d8d3161aedc4ab4b1159b44c7 100644 --- a/openair1/PHY/LTE_TRANSPORT/extern.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_extern.h @@ -30,7 +30,7 @@ extern short *ul_ref_sigs_rx[30][2][33]; extern unsigned short dftsizes[33]; extern unsigned short ref_primes[33]; -extern int qam64_table[8],qam16_table[4]; +extern int qam64_table[8],qam16_table[4],qpsk_table[2]; extern unsigned char cs_ri_normal[4]; extern unsigned char cs_ri_extended[4]; @@ -48,3 +48,5 @@ extern int16_t d0_sss[504*62],d5_sss[504*62]; extern uint8_t wACK[5][4]; extern int8_t wACK_RX[5][4]; + +extern uint32_t bitrev_cc_dci[32]; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h new file mode 100644 index 0000000000000000000000000000000000000000..a97b0ff6ae6f3aaae4dc76bb413f0f690496a077 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -0,0 +1,622 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/transport_proto.h + * \brief Function prototypes for eNB PHY physical/transport channel processing and generation V8.6 2009-03 + * \author R. Knopp, F. Kaltenberger + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_PROTO__H__ +#define __LTE_TRANSPORT_PROTO__H__ +#include "PHY/defs_eNB.h" +#include <math.h> +#include "nfapi_interface.h" +#include "transport_common_proto.h" + +// Functions below implement 36-211 and 36-212 + +/** @addtogroup _PHY_TRANSPORT_ + * @{ + */ + +/** \fn free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch,unsigned char N_RB_DL) + \brief This function frees memory allocated for a particular DLSCH at eNB + @param dlsch Pointer to DLSCH to be removed +*/ +void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch); + +void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + +/** \fn new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms) + \brief This function allocates structures for a particular DLSCH at eNB + @returns Pointer to DLSCH to be removed + @param Kmimo Kmimo factor from 36-212/36-213 + @param Mdlharq Maximum number of HARQ rounds (36-212/36-213) + @param Nsoft Soft-LLR buffer size from UE-Category + @params N_RB_DL total number of resource blocks (determine the operating BW) + @param abstraction_flag Flag to indicate abstracted interface + @param frame_parms Pointer to frame descriptor structure +*/ +LTE_eNB_DLSCH_t *new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms); + +void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + +/** \fn free_eNB_ulsch(LTE_eNB_DLSCH_t *dlsch) + \brief This function frees memory allocated for a particular ULSCH at eNB + @param ulsch Pointer to ULSCH to be removed +*/ +void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch); + +LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); + +int dlsch_encoding_all(PHY_VARS_eNB *eNB, + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *te_wait_stats, + time_stats_t *te_main_stats, + time_stats_t *te_wakeup_stats0, + time_stats_t *te_wakeup_stats1, + time_stats_t *i_stats); + +/** \fn dlsch_encoding(PHY_VARS_eNB *eNB, + uint8_t *input_buffer, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe) + \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are: + - CRC computation and addition + - Code block segmentation and sub-block CRC addition + - Channel coding (Turbo coding) + - Rate matching (sub-block interleaving, bit collection, selection and transmission + - Code block concatenation + @param eNB Pointer to eNB PHY context + @param input_buffer Pointer to input buffer for sub-frame + @param frame_parms Pointer to frame descriptor structure + @param num_pdcch_symbols Number of PDCCH symbols in this subframe + @param dlsch Pointer to dlsch to be encoded + @param frame Frame number + @param subframe Subframe number + @param rm_stats Time statistics for rate-matching + @param te_stats Time statistics for turbo-encoding + @param i_stats Time statistics for interleaving + @returns status +*/ +int32_t dlsch_encoding(PHY_VARS_eNB *eNB, + uint8_t *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats); + + + + +/** \fn dlsch_encoding_2threads(PHY_VARS_eNB *eNB, + uint8_t *input_buffer, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe) + \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). This version spawns 1 worker thread. The implemented functions are: + - CRC computation and addition + - Code block segmentation and sub-block CRC addition + - Channel coding (Turbo coding) + - Rate matching (sub-block interleaving, bit collection, selection and transmission + - Code block concatenation + @param eNB Pointer to eNB PHY context + @param input_buffer Pointer to input buffer for sub-frame + @param num_pdcch_symbols Number of PDCCH symbols in this subframe + @param dlsch Pointer to dlsch to be encoded + @param frame Frame number + @param subframe Subframe number + @param rm_stats Time statistics for rate-matching + @param te_stats Time statistics for turbo-encoding + @param i_stats Time statistics for interleaving + @returns status +*/ +int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB, + uint8_t *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *te_wait_stats, + time_stats_t *te_main_stats, + time_stats_t *te_wakeup_stats0, + time_stats_t *te_wakeup_stats1, + time_stats_t *i_stats, + int worker_num); + +// Functions below implement 36-211 + +/** \fn allocate_REs_in_RB(int32_t **txdataF, + uint32_t *jj, + uint32_t *jj2, + uint16_t re_offset, + uint32_t symbol_offset, + LTE_DL_eNB_HARQ_t *dlsch0_harq, + LTE_DL_eNB_HARQ_t *dlsch1_harq, + uint8_t pilots, + int16_t amp, + int16_t *qam_table_s, + uint32_t *re_allocated, + uint8_t skip_dc, + uint8_t skip_half, + uint8_t use2ndpilots, + LTE_DL_FRAME_PARMS *frame_parms); + + \brief Fills RB with data + \param txdataF pointer to output data (frequency domain signal) + \param jj index to output (from CW 1) + \param jj index to output (from CW 2) + \param re_offset index of the first RE of the RB + \param symbol_offset index to the OFDM symbol + \param dlsch0_harq Pointer to Transport block 0 HARQ structure + \param dlsch0_harq Pointer to Transport block 1 HARQ structure + \param pilots =1 if symbol_offset is an OFDM symbol that contains pilots, 0 otherwise + \param amp Amplitude for symbols + \param qam_table_s0 pointer to scaled QAM table for Transport Block 0 (by rho_a or rho_b) + \param qam_table_s1 pointer to scaled QAM table for Transport Block 1 (by rho_a or rho_b) + \param re_allocated pointer to allocation counter + \param skip_dc offset for positive RBs + \param skip_half indicate that first or second half of RB must be skipped for PBCH/PSS/SSS + \param use2ndpilots Set to use the pilots from antenna port 1 for PDSCH + \param frame_parms Frame parameter descriptor +*/ + +int32_t allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, + int32_t **txdataF, + uint32_t *jj, + uint32_t *jj2, + uint16_t re_offset, + uint32_t symbol_offset, + LTE_DL_eNB_HARQ_t *dlsch0_harq, + LTE_DL_eNB_HARQ_t *dlsch1_harq, + uint8_t pilots, + int16_t amp, + uint8_t precoder_index, + int16_t *qam_table_s0, + int16_t *qam_table_s1, + uint32_t *re_allocated, + uint8_t skip_dc, + uint8_t skip_half, + uint8_t lprime, + uint8_t mprime, + uint8_t Ns, + int *P1_SHIFT, + int *P2_SHIFT); + + +/** \fn int32_t dlsch_modulation(int32_t **txdataF, + int16_t amp, + uint32_t sub_frame_offset, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch); + + \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for DLSCH. + @param txdataF Table of pointers for frequency-domain TX signals + @param amp Amplitude of signal + @param sub_frame_offset Offset of this subframe in units of subframes (usually 0) + @param frame_parms Pointer to frame descriptor + @param num_pdcch_symbols Number of PDCCH symbols in this subframe + @param dlsch0 Pointer to Transport Block 0 DLSCH descriptor for this allocation + @param dlsch1 Pointer to Transport Block 0 DLSCH descriptor for this allocation +*/ +int32_t dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, + int32_t **txdataF, + int16_t amp, + int frame, + uint32_t sub_frame_offset, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch0, + LTE_eNB_DLSCH_t *dlsch1); + +int32_t dlsch_modulation_SIC(int32_t **sic_buffer, + uint32_t sub_frame_offset, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch0, + int G); +/* + \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH. + @param txdataF Table of pointers for frequency-domain TX signals + @param amp Amplitude of signal + @param subframe_offset Offset of this subframe in units of subframes (usually 0) + @param frame_parms Pointer to frame descriptor + @param dlsch Pointer to DLSCH descriptor for this allocation +*/ +int mch_modulation(int32_t **txdataF, + int16_t amp, + uint32_t subframe_offset, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_eNB_DLSCH_t *dlsch); + +/** \brief Top-level generation function for eNB TX of MBSFN + @param phy_vars_eNB Pointer to eNB variables + @param a Pointer to transport block + @param abstraction_flag + +*/ +void generate_mch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t *a); + +/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) + @param phy_vars_eNB Pointer to eNB variables + @param proc Pointer to RXn-TXnp4 proc information + @param mcs MCS for MBSFN + @param ndi new data indicator + @param rdvix +*/ +void fill_eNB_dlsch_MCH(PHY_VARS_eNB *phy_vars_eNB,int mcs,int ndi,int rvidx); + +/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) + @param phy_vars_ue Pointer to UE variables + @param mcs MCS for MBSFN + @param eNB_id index of eNB in ue variables +*/ + +/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) + for N subframes. + @param phy_vars_eNB Pointer to eNB variables + @param txdataF Table of pointers for frequency-domain TX signals + @param amp Amplitude of signal + @param N Number of sub-frames to generate +*/ +void generate_pilots(PHY_VARS_eNB *phy_vars_eNB, + int32_t **txdataF, + int16_t amp, + uint16_t N); + +/** + \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) for one slot only + @param phy_vars_eNB Pointer to eNB variables + @param txdataF Table of pointers for frequency-domain TX signals + @param amp Amplitude of signal + @param slot index (0..19) + @param first_pilot_only (0 no) +*/ +int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB, + int32_t **txdataF, + int16_t amp, + uint16_t slot, + int first_pilot_only); + +int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB, + eNB_rxtx_proc_t *proc, + int32_t **txdataF, + int16_t amp); + +void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB, + uint8_t UE_id, + int32_t **txdataF, + int16_t amp, + uint16_t Ntti, + uint8_t beamforming_mode); + +int32_t generate_pss(int32_t **txdataF, + int16_t amp, + LTE_DL_FRAME_PARMS *frame_parms, + uint16_t l, + uint16_t Ns); + + +int32_t generate_sss(int32_t **txdataF, + short amp, + LTE_DL_FRAME_PARMS *frame_parms, + unsigned short symbol, + unsigned short slot_offset); + +int32_t generate_pbch(LTE_eNB_PBCH *eNB_pbch, + int32_t **txdataF, + int32_t amp, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t *pbch_pdu, + uint8_t frame_mod4); + + + + +/*! \brief DCI Encoding. This routine codes an arbitrary DCI PDU after appending the 8-bit 3GPP CRC. It then applied sub-block interleaving and rate matching. + \param a Pointer to DCI PDU (coded in bytes) + \param A Length of DCI PDU in bits + \param E Length of DCI PDU in coded bits + \param e Pointer to sequence + \param rnti RNTI for CRC scrambling*/ +void dci_encoding(uint8_t *a, + uint8_t A, + uint16_t E, + uint8_t *e, + uint16_t rnti); + +/*! \brief Top-level DCI entry point. This routine codes an set of DCI PDUs and performs PDCCH modulation, interleaving and mapping. + \param num_dci Number of pdcch symbols + \param num_dci Number of DCI pdus to encode + \param dci_alloc Allocation vectors for each DCI pdu + \param n_rnti n_RNTI (see ) + \param amp Amplitude of QPSK symbols + \param frame_parms Pointer to DL Frame parameter structure + \param txdataF Pointer to tx signal buffers + \param sub_frame_offset subframe offset in frame + @returns Number of PDCCH symbols +*/ + +uint8_t generate_dci_top(uint8_t num_pdcch_symbols, + uint8_t num_dci, + DCI_ALLOC_t *dci_alloc, + uint32_t n_rnti, + int16_t amp, + LTE_DL_FRAME_PARMS *frame_parms, + int32_t **txdataF, + uint32_t sub_frame_offset); + + +void generate_64qam_table(void); +void generate_16qam_table(void); + + + + + + + + +void ulsch_extract_rbs_single(int32_t **rxdataF, + int32_t **rxdataF_ext, + uint32_t first_rb, + uint32_t nb_rb, + uint8_t l, + uint8_t Ns, + LTE_DL_FRAME_PARMS *frame_parms); + + + + + +void fill_dci_and_dlsch(PHY_VARS_eNB *eNB, + int frame, + int subframe, + eNB_rxtx_proc_t *proc, + DCI_ALLOC_t *dci_alloc, + nfapi_dl_config_dci_dl_pdu *pdu); + +void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu); + +void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, + nfapi_hi_dci0_dci_pdu *pdu); + +void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe); + +int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, + unsigned char *rar_pdu, + uint32_t frame, + unsigned char subframe); + +int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB, + eNB_rxtx_proc_t *proc, + void *dci_pdu, + rnti_t rnti, + DCI_format_t dci_format, + uint8_t UE_id, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + uint16_t cba_rnti, + uint8_t use_srs); + + +void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id,int round); + + + + + +void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + uint8_t *b, + uint8_t *bt); + + +void generate_pcfich(uint8_t num_pdcch_symbols, + int16_t amp, + LTE_DL_FRAME_PARMS *frame_parms, + int32_t **txdataF, + uint8_t subframe); + + + + + +void init_transport_channels(uint8_t); + + + +void rx_ulsch(PHY_VARS_eNB *eNB, + eNB_rxtx_proc_t *proc, + uint8_t UE_id); + + +int ulsch_decoding_data_all(PHY_VARS_eNB *eNB, + int UE_id, + int harq_pid, + int llr8_flag); + +/*! + \brief Decoding of PUSCH/ACK/RI/ACK from 36-212. + @param phy_vars_eNB Pointer to eNB top-level descriptor + @param proc Pointer to RXTX proc variables + @param UE_id ID of UE transmitting this PUSCH + @param subframe Index of subframe for PUSCH + @param control_only_flag Receive PUSCH with control information only + @param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213 + @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used + @returns 0 on success +*/ +unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB, + eNB_rxtx_proc_t *proc, + uint8_t UE_id, + uint8_t control_only_flag, + uint8_t Nbundled, + uint8_t llr8_flag); + +/*! + \brief Decoding of ULSCH data component from 36-212. This one spawns 1 worker thread in parallel,half of the segments in each thread. + @param phy_vars_eNB Pointer to eNB top-level descriptor + @param UE_id ID of UE transmitting this PUSCH + @param harq_pid HARQ process ID + @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used + @returns 0 on success +*/ +int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB, + int UE_id, + int harq_pid, + int llr8_flag); + +/*! + \brief Decoding of ULSCH data component from 36-212. This one is single thread. + @param phy_vars_eNB Pointer to eNB top-level descriptor + @param UE_id ID of UE transmitting this PUSCH + @param harq_pid HARQ process ID + @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used + @returns 0 on success +*/ +int ulsch_decoding_data(PHY_VARS_eNB *eNB, + int UE_id, + int harq_pid, + int llr8_flag); + +void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB, + eNB_rxtx_proc_t *proc, + int16_t amp); + + + + + + + +void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi); + +void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + int8_t* llr, + uint32_t length); + + +void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, + int mbsfn_flag, + LTE_eNB_DLSCH_t *dlsch, + int hard_pid, + int G, + uint8_t q, + uint16_t frame, + uint8_t Ns); + + + +uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, + PUCCH_FMT_t fmt, + uint8_t UE_id, + uint16_t n1_pucch, + uint16_t n2_pucch, + uint8_t shortened_format, + uint8_t *payload, + int frame, + uint8_t subframe, + uint8_t pucch1_thres); + + +/*! + \brief Process PRACH waveform + @param phy_vars_eNB Pointer to eNB top-level descriptor. If NULL, then this is an RRU + @param ru Pointer to RU top-level descriptor. If NULL, then this is an eNB and we make use of the RU_list + @param max_preamble most likely preamble + @param max_preamble_energy Estimated Energy of most likely preamble + @param max_preamble_delay Estimated Delay of most likely preamble + @param Nf System frame number + @param tdd_mapindex Index of PRACH resource in Table 5.7.1-4 (TDD) + @param br_flag indicator to act on eMTC PRACH + @returns 0 on success + +*/ +void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru, + uint16_t *max_preamble, + uint16_t *max_preamble_energy, + uint16_t *max_preamble_delay, + uint16_t Nf, uint8_t tdd_mapindex +#ifdef Rel14 + , + uint8_t br_flag +#endif + ); + + +void init_unscrambling_lut(void); + + + +uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots); + +uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode); + + + +double computeRhoA_eNB(uint8_t pa, + LTE_eNB_DLSCH_t *dlsch_eNB, + int dl_power_off, + uint8_t n_antenna_port); + +double computeRhoB_eNB(uint8_t pa, + uint8_t pb, + uint8_t n_antenna_port, + LTE_eNB_DLSCH_t *dlsch_eNB, + int dl_power_off); + + + +void conv_eMTC_rballoc(uint16_t resource_block_coding, + uint32_t N_RB_DL, + uint32_t *rb_alloc); + +int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); + +int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); + +int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type); + +/**@}*/ +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/vars.h b/openair1/PHY/LTE_TRANSPORT/transport_vars.h similarity index 88% rename from openair1/PHY/LTE_TRANSPORT/vars.h rename to openair1/PHY/LTE_TRANSPORT/transport_vars.h index 4b6fa920ea76b863d1e6d2b0f5b8dae19c9c9ea1..611028e1e9805d748de9c9c4f77ba0b8856b2170 100644 --- a/openair1/PHY/LTE_TRANSPORT/vars.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_vars.h @@ -62,7 +62,7 @@ unsigned char ue_power_offsets[25] = {14,11,9,8,7,6,6,5,4,4,4,3,3,3,2,2,2,1,1,1, short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1}; short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; -int qam64_table[8],qam16_table[4]; +int qam64_table[8],qam16_table[4],qpsk_table[2]; unsigned char cs_ri_normal[4] = {1,4,7,10}; unsigned char cs_ri_extended[4] = {0,3,5,8}; @@ -78,3 +78,11 @@ char dci_format_strings[15][13] = {"0","1","1A","1B","1C","1D","1E_2A_M10PRB", uint8_t wACK[5][4] = {{1,1,1,1},{1,0,1,0},{1,1,0,0},{1,0,0,1},{0,0,0,0}}; int8_t wACK_RX[5][4] = {{-1,-1,-1,-1},{-1,1,-1,1},{-1,-1,1,1},{-1,1,1,-1},{1,1,1,1}}; + +uint32_t bitrev_cc_dci[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30}; + +uint8_t pcfich_b[4][32]= {{0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1}, + {1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0}, + {1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +}; diff --git a/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..6f2dd0f989cb90fc65ac8a658a6ad9ca78db7051 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h @@ -0,0 +1,324 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __UCI_NB_IOT__H__ +#define __UCI_NB_IOT__H__ +//#include "PHY/types_NB_IoT.h" + + + +typedef enum { + ue_selected_NB_IoT, + wideband_cqi_rank1_2A_NB_IoT, //wideband_cqi_rank1_2A, + wideband_cqi_rank2_2A_NB_IoT, //wideband_cqi_rank2_2A, + HLC_subband_cqi_nopmi_NB_IoT, //HLC_subband_cqi_nopmi, + HLC_subband_cqi_rank1_2A_NB_IoT, //HLC_subband_cqi_rank1_2A, + HLC_subband_cqi_rank2_2A_NB_IoT, //HLC_subband_cqi_rank2_2A, + HLC_subband_cqi_modes123_NB_IoT, //HLC_subband_cqi_modes123 + HLC_subband_cqi_mcs_CBA_NB_IoT, // MCS and RNTI, for contention-based acces + unknown_cqi_NB_IoT// +} UCI_format_NB_IoT_t; + +// **********************************************1.5 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t pmi:12; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_1_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint16_t padding:2; + uint16_t pmi:6; + uint16_t cqi2:4; + uint16_t cqi1:4; +} +wideband_cqi_rank2_2A_1_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_1_5MHz_NB_IoT 14 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t pmi:2; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:31; + uint64_t pmi:1; + uint64_t diffcqi2:12; + uint64_t cqi2:4; + uint64_t diffcqi1:12; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT 33 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT 21 + + +// **********************************************5 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t pmi:14; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint16_t padding:1; + uint16_t pmi:7; + uint16_t cqi2:4; + uint16_t cqi1:4; +} +wideband_cqi_rank2_2A_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_5MHz_NB_IoT 15 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:12; + uint32_t pmi:2; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_5MHz_NB_IoT 20 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:27; + uint64_t pmi:1; + uint64_t diffcqi2:14; + uint64_t cqi2:4; + uint64_t diffcqi1:14; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_5MHz_NB_IoT 37 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT 21 + +// **********************************************10 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t pmi:18; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_10MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:15; + uint32_t pmi:9; + uint32_t cqi2:4; + uint32_t cqi1:4; +} +wideband_cqi_rank2_2A_10MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_10MHz_NB_IoT 17 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:8; + uint32_t pmi:2; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_10MHz_NB_IoT 24 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:19; + uint64_t pmi:1; + uint64_t diffcqi2:18; + uint64_t cqi2:4; + uint64_t diffcqi1:18; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_10MHz_NB_IoT 45 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT 21 + +// **********************************************20 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t pmi:26; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_20MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_20MHz_NB_IoT 20 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t pmi:13; + uint32_t cqi2:4; + uint32_t cqi1:4; +} +wideband_cqi_rank2_2A_20MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_20MHz_NB_IoT 21 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_20MHz_NB_IoT 30 + +typedef struct __attribute__((packed)) +{ + // uint32_t padding:12; + uint32_t pmi:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_20MHz_NB_IoT 32 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:3; + uint64_t pmi:1; + uint64_t diffcqi2:26; + uint64_t cqi2:4; + uint64_t diffcqi1:26; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_20MHz_NB_IoT 61 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_20MHz_NB_IoT 30 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT; + +#define sizeof_HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT 21 + +#define MAX_CQI_PAYLOAD_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8*20) +#define MAX_CQI_BITS_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8) +#define MAX_CQI_BYTES_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)) +#define MAX_ACK_PAYLOAD_NB_IoT 18 +#define MAX_RI_PAYLOAD_NB_IoT 6 + +#endif \ No newline at end of file diff --git a/openair1/PHY/LTE_TRANSPORT/uci.h b/openair1/PHY/LTE_TRANSPORT/uci_common.h similarity index 99% rename from openair1/PHY/LTE_TRANSPORT/uci.h rename to openair1/PHY/LTE_TRANSPORT/uci_common.h index c7741533da543b909aa00bbaad4151274b210595..78555d4928c2f8b45f95092212ddc9ff36c924cd 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci.h +++ b/openair1/PHY/LTE_TRANSPORT/uci_common.h @@ -19,6 +19,8 @@ * contact@openairinterface.org */ +#ifndef __UCI_COMMON__H +#define __UCI_COMMON__H #include "PHY/types.h" @@ -318,3 +320,5 @@ HLC_subband_cqi_mcs_CBA_20MHz; #define MAX_CQI_BYTES (sizeof(HLC_subband_cqi_rank2_2A_20MHz)) #define MAX_ACK_PAYLOAD 18 #define MAX_RI_PAYLOAD 6 + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index 14b55569b8e40ede3b99e75356ef443ecffe76af..88c652133b783bb627f708985c08c0d4004ca707 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -29,765 +29,13 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" #ifdef DEBUG_UCI_TOOLS #include "PHY/vars.h" #endif //#define DEBUG_UCI 1 -uint64_t pmi2hex_2Ar1(uint32_t pmi) -{ - - uint64_t pmil = (uint64_t)pmi; - - return ((pmil&3) + (((pmil>>2)&3)<<4) + (((pmil>>4)&3)<<8) + (((pmil>>6)&3)<<12) + - (((pmil>>8)&3)<<16) + (((pmil>>10)&3)<<20) + (((pmil>>12)&3)<<24) + - (((pmil>>14)&3)<<28) + (((pmil>>16)&3)<<32) + (((pmil>>18)&3)<<36) + - (((pmil>>20)&3)<<40) + (((pmil>>22)&3)<<44) + (((pmil>>24)&3)<<48)); -} - -uint64_t pmi2hex_2Ar2(uint32_t pmi) -{ - - uint64_t pmil = (uint64_t)pmi; - return ((pmil&1) + (((pmil>>1)&1)<<4) + (((pmil>>2)&1)<<8) + (((pmil>>3)&1)<<12) + - (((pmil>>4)&1)<<16) + (((pmil>>5)&1)<<20) + (((pmil>>6)&1)<<24) + - (((pmil>>7)&1)<<28) + (((pmil>>8)&1)<<32) + (((pmil>>9)&1)<<36) + - (((pmil>>10)&1)<<40) + (((pmil>>11)&1)<<44) + (((pmil>>12)&1)<<48)); -} - -uint64_t cqi2hex(uint32_t cqi) -{ - - uint64_t cqil = (uint64_t)cqi; - return ((cqil&3) + (((cqil>>2)&3)<<4) + (((cqil>>4)&3)<<8) + (((cqil>>6)&3)<<12) + - (((cqil>>8)&3)<<16) + (((cqil>>10)&3)<<20) + (((cqil>>12)&3)<<24) + - (((cqil>>14)&3)<<28) + (((cqil>>16)&3)<<32) + (((cqil>>18)&3)<<36) + - (((cqil>>20)&3)<<40) + (((cqil>>22)&3)<<44) + (((cqil>>24)&3)<<48)); -} - -//void do_diff_cqi(uint8_t N_RB_DL, -// uint8_t *DL_subband_cqi, -// uint8_t DL_cqi, -// uint32_t diffcqi1) { -// -// uint8_t nb_sb,i,offset; -// -// // This is table 7.2.1-3 from 36.213 (with k replaced by the number of subbands, nb_sb) -// switch (N_RB_DL) { -// case 6: -// nb_sb=0; -// break; -// case 15: -// nb_sb = 4; -// case 25: -// nb_sb = 7; -// break; -// case 50: -// nb_sb = 9; -// break; -// case 75: -// nb_sb = 10; -// break; -// case 100: -// nb_sb = 13; -// break; -// default: -// nb_sb=0; -// break; -// } -// -// memset(DL_subband_cqi,0,13); -// -// for (i=0;i<nb_sb;i++) { -// offset = (DL_cqi>>(2*i))&3; -// if (offset == 3) -// DL_subband_cqi[i] = DL_cqi - 1; -// else -// DL_subband_cqi[i] = DL_cqi + offset; -// } -//} - - -void do_diff_cqi(uint8_t N_RB_DL, - uint8_t *DL_subband_cqi, - uint8_t DL_cqi, - uint32_t diffcqi1) -{ - - uint8_t nb_sb,i,offset; - - // This is table 7.2.1-3 from 36.213 (with k replaced by the number of subbands, nb_sb) - switch (N_RB_DL) { - case 6: - nb_sb=1; - break; - - case 15: - nb_sb = 4; - break; - - case 25: - nb_sb = 7; - break; - - case 50: - nb_sb = 9; - break; - - case 75: - nb_sb = 10; - break; - - case 100: - nb_sb = 13; - break; - - default: - nb_sb=0; - break; - } - - memset(DL_subband_cqi,0,13); - - for (i=0; i<nb_sb; i++) { - offset = (diffcqi1>>(2*i))&3; - - if (offset == 3) - DL_subband_cqi[i] = DL_cqi - 1; - else - DL_subband_cqi[i] = DL_cqi + offset; - } -} - -void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode) -{ - - //unsigned char rank; - //UCI_format fmt; - //uint8_t N_RB_DL = 25; - uint8_t i; - LOG_D(PHY,"[eNB][UCI] N_RB_DL %d uci format %d\n", N_RB_DL,uci_format); - - switch(N_RB_DL) { - case 6: - switch(uci_format) { - case wideband_cqi_rank1_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_pmi_single = ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi; - break; - - case wideband_cqi_rank2_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - stats->DL_pmi_dual = ((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi; - break; - - case HLC_subband_cqi_nopmi: - stats->DL_cqi[0] = (((HLC_subband_cqi_nopmi_1_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],((HLC_subband_cqi_nopmi_1_5MHz *)o)->diffcqi1); - break; - - case HLC_subband_cqi_rank1_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1)); - stats->DL_pmi_single = ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->pmi; - break; - - case HLC_subband_cqi_rank2_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1)); - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[1],stats->DL_cqi[1],(((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2)); - stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi; - break; - - case unknown_cqi: - default: - LOG_N(PHY,"[eNB][UCI] received unknown uci (rb %d)\n",N_RB_DL); - break; - } - - break; - - case 25: - - switch(uci_format) { - case wideband_cqi_rank1_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank1_2A_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_pmi_single = ((wideband_cqi_rank1_2A_5MHz *)o)->pmi; - break; - - case wideband_cqi_rank2_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank2_2A_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((wideband_cqi_rank2_2A_5MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - stats->DL_pmi_dual = ((wideband_cqi_rank2_2A_5MHz *)o)->pmi; - //this translates the 2-layer PMI into a single layer PMI for the first codeword - //the PMI for the second codeword will be stats->DL_pmi_single^0x1555 - stats->DL_pmi_single = 0; - for (i=0;i<7;i++) - stats->DL_pmi_single = stats->DL_pmi_single | (((stats->DL_pmi_dual&(1<i))>>i)*2)<<2*i; - break; - - case HLC_subband_cqi_nopmi: - stats->DL_cqi[0] = (((HLC_subband_cqi_nopmi_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],((HLC_subband_cqi_nopmi_5MHz *)o)->diffcqi1); - break; - - case HLC_subband_cqi_rank1_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - stats->DL_pmi_single = ((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi; - break; - - case HLC_subband_cqi_rank2_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1)); - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[1],stats->DL_cqi[1],(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2)); - stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi; - break; - - case unknown_cqi: - default: - LOG_N(PHY,"[eNB][UCI] received unknown uci (rb %d)\n",N_RB_DL); - break; - } - - break; - - case 50: - switch(uci_format) { - case wideband_cqi_rank1_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank1_2A_10MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_pmi_single = ((wideband_cqi_rank1_2A_10MHz *)o)->pmi; - break; - - case wideband_cqi_rank2_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank2_2A_10MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((wideband_cqi_rank2_2A_10MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - stats->DL_pmi_dual = ((wideband_cqi_rank2_2A_10MHz *)o)->pmi; - break; - - case HLC_subband_cqi_nopmi: - stats->DL_cqi[0] = (((HLC_subband_cqi_nopmi_10MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],((HLC_subband_cqi_nopmi_10MHz *)o)->diffcqi1); - break; - - case HLC_subband_cqi_rank1_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1)); - stats->DL_pmi_single = ((HLC_subband_cqi_rank1_2A_10MHz *)o)->pmi; - break; - - case HLC_subband_cqi_rank2_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1)); - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[1],stats->DL_cqi[1],(((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2)); - stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi; - break; - - case unknown_cqi: - default: - LOG_N(PHY,"[eNB][UCI] received unknown uci (RB %d)\n",N_RB_DL); - break; - } - - break; - - case 100: - switch(uci_format) { - case wideband_cqi_rank1_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank1_2A_20MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_pmi_single = ((wideband_cqi_rank1_2A_20MHz *)o)->pmi; - break; - - case wideband_cqi_rank2_2A: - stats->DL_cqi[0] = (((wideband_cqi_rank2_2A_20MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((wideband_cqi_rank2_2A_20MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - stats->DL_pmi_dual = ((wideband_cqi_rank2_2A_20MHz *)o)->pmi; - break; - - case HLC_subband_cqi_nopmi: - stats->DL_cqi[0] = (((HLC_subband_cqi_nopmi_20MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],((HLC_subband_cqi_nopmi_20MHz *)o)->diffcqi1); - break; - - case HLC_subband_cqi_rank1_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1)); - stats->DL_pmi_single = ((HLC_subband_cqi_rank1_2A_20MHz *)o)->pmi; - break; - - case HLC_subband_cqi_rank2_2A: - stats->DL_cqi[0] = (((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1); - - if (stats->DL_cqi[0] > 24) - stats->DL_cqi[0] = 24; - - stats->DL_cqi[1] = (((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2); - - if (stats->DL_cqi[1] > 24) - stats->DL_cqi[1] = 24; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1)); - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[1],stats->DL_cqi[1],(((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2)); - stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi; - break; - - case unknown_cqi: - default: - LOG_N(PHY,"[eNB][UCI] received unknown uci (RB %d)\n",N_RB_DL); - break; - } - - break; - - default: - LOG_N(PHY,"[eNB][UCI] unknown RB %d\n",N_RB_DL); - break; - } - - /* - switch (tmode) { - - case 1: - case 2: - case 3: - case 5: - case 6: - case 7: - default: - fmt = hlc_cqi; - break; - case 4: - fmt = wideband_cqi; - break; - } - - rank = o_RI[0]; - //printf("extract_CQI: rank = %d\n",rank); - - switch (fmt) { - - case wideband_cqi: //and subband pmi - if (rank == 0) { - stats->DL_cqi[0] = (((wideband_cqi_rank1_2A_5MHz *)o)->cqi1); - if (stats->DL_cqi[0] > 15) - stats->DL_cqi[0] = 15; - stats->DL_pmi_single = ((wideband_cqi_rank1_2A_5MHz *)o)->pmi; - } - else { - stats->DL_cqi[0] = (((wideband_cqi_rank2_2A_5MHz *)o)->cqi1); - if (stats->DL_cqi[0] > 15) - stats->DL_cqi[0] = 15; - stats->DL_cqi[1] = (((wideband_cqi_rank2_2A_5MHz *)o)->cqi2); - if (stats->DL_cqi[1] > 15) - stats->DL_cqi[1] = 15; - stats->DL_pmi_dual = ((wideband_cqi_rank2_2A_5MHz *)o)->pmi; - } - break; - case hlc_cqi: - if (tmode > 2) { - if (rank == 0) { - stats->DL_cqi[0] = (((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - if (stats->DL_cqi[0] > 15) - stats->DL_cqi[0] = 15; - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - stats->DL_pmi_single = ((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi; - } - else { - stats->DL_cqi[0] = (((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1); - if (stats->DL_cqi[0] > 15) - stats->DL_cqi[0] = 15; - stats->DL_cqi[1] = (((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2); - if (stats->DL_cqi[1] > 15) - stats->DL_cqi[1] = 15; - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1)); - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[1],stats->DL_cqi[1],(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2)); - stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi; - } - } - else { - stats->DL_cqi[0] = (((HLC_subband_cqi_nopmi_5MHz *)o)->cqi1); - if (stats->DL_cqi[0] > 15) - stats->DL_cqi[0] = 15; - - do_diff_cqi(N_RB_DL,stats->DL_subband_cqi[0],stats->DL_cqi[0],((HLC_subband_cqi_nopmi_5MHz *)o)->diffcqi1); - - } - break; - default: - break; - } - */ - -} - - -void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL) -{ - - - switch(uci_format) { - case wideband_cqi_rank1_2A: -#ifdef DEBUG_UCI - LOG_D(PHY,"[PRINT CQI] flat_LA %d\n", flag_LA); - switch(N_RB_DL) { - case 6: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, - ((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, - ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi, - pmi2hex_2Ar1(((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi)); - break; - - case 25: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, - ((wideband_cqi_rank1_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, - ((wideband_cqi_rank1_2A_5MHz *)o)->pmi, - pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)o)->pmi)); - break; - - case 50: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, - ((wideband_cqi_rank1_2A_10MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, - ((wideband_cqi_rank1_2A_10MHz *)o)->pmi, - pmi2hex_2Ar1(((wideband_cqi_rank1_2A_10MHz *)o)->pmi)); - break; - - case 100: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, - ((wideband_cqi_rank1_2A_20MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, - ((wideband_cqi_rank1_2A_20MHz *)o)->pmi, - pmi2hex_2Ar1(((wideband_cqi_rank1_2A_20MHz *)o)->pmi)); - break; - } - -#endif //DEBUG_UCI - break; - - case wideband_cqi_rank2_2A: -#ifdef DEBUG_UCI - switch(N_RB_DL) { - case 6: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi)); - break; - - case 25: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_5MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_5MHz *)o)->pmi)); - break; - - case 50: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_10MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_10MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_10MHz *)o)->pmi)); - break; - - case 100: - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_20MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_20MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_20MHz *)o)->pmi)); - break; - } - -#endif //DEBUG_UCI - break; - - case HLC_subband_cqi_nopmi: -#ifdef DEBUG_UCI - switch(N_RB_DL) { - case 6: - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1)); - break; - - case 25: - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - break; - - case 50: - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1)); - break; - - case 100: - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1)); - break; - } - -#endif //DEBUG_UCI - break; - - case HLC_subband_cqi_rank1_2A: -#ifdef DEBUG_UCI - switch(N_RB_DL) { - case 6: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); - break; - - case 25: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); - break; - - case 50: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); - break; - - case 100: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); - break; - } - -#endif //DEBUG_UCI - break; - - case HLC_subband_cqi_rank2_2A: -#ifdef DEBUG_UCI - switch(N_RB_DL) { - case 6: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi); - break; - - case 25: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi); - break; - - case 50: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi); - break; - - case 100: - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2)); - LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi); - break; - } - -#endif //DEBUG_UCI - break; - - case ue_selected: -#ifdef DEBUG_UCI - LOG_W(PHY,"[PRINT CQI] ue_selected CQI not supported yet!!!\n"); -#endif //DEBUG_UCI - break; - - default: -#ifdef DEBUG_UCI - LOG_E(PHY,"[PRINT CQI] unsupported CQI mode (%d)!!!\n",uci_format); -#endif //DEBUG_UCI - break; - } - - /* - switch (tmode) { - - case 1: - case 2: - case 3: - case 5: - case 6: - case 7: - default: - fmt = hlc_cqi; - break; - case 4: - fmt = wideband_cqi; - break; - } - - switch (fmt) { - - case wideband_cqi: - if (rank == 0) { - #ifdef DEBUG_UCI - msg("[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id,((wideband_cqi_rank1_2A_5MHz *)o)->cqi1); - msg("[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id,((wideband_cqi_rank1_2A_5MHz *)o)->pmi,pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)o)->pmi)); - #endif //DEBUG_UCI - } - else { - #ifdef DEBUG_UCI - msg("[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_5MHz *)o)->cqi1); - msg("[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_5MHz *)o)->cqi2); - msg("[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_5MHz *)o)->pmi)); - #endif //DEBUG_UCI - } - break; - case hlc_cqi: - if (tmode > 2) { - if (rank == 0) { - #ifdef DEBUG_UCI - msg("[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - msg("[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - msg("[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); - #endif //DEBUG_UCI - } - else { - #ifdef DEBUG_UCI - msg("[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1); - msg("[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2); - msg("[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1)); - msg("[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2)); - msg("[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi); - #endif //DEBUG_UCI - } - } - else { - #ifdef DEBUG_UCI - msg("[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); - msg("[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); - #endif //DEBUG_UCI - } - break; - case ue_selected: - #ifdef DEBUG_UCI - msg("dci_tools.c: print_CQI ue_selected CQI not supported yet!!!\n"); - #endif //DEBUG_UCI - break; - } - */ - -} - int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type) { uint16_t i; diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 32fab5f4a20b4da07fc43a851f34eb0a55477ede..2083d1630984fe45d323542954c365b9e6915a9f 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -30,22 +30,22 @@ * \warning */ -//#include "defs.h" - -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/CODING/extern.h" -#include "extern.h" -#include "SCHED/extern.h" -#ifdef OPENAIR2 -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" -#include "RRC/LITE/extern.h" -#include "PHY_INTERFACE/extern.h" -#endif + +#include <syscall.h> +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/CODING/coding_extern.h" +#include "SCHED/sched_eNB.h" +#include "LAYER2/MAC/mac.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface.h" #include "UTIL/LOG/vcd_signal_dumper.h" //#define DEBUG_ULSCH_DECODING +#include "targets/RT/USER/rt_wrapper.h" +#include "transport_proto.h" + +extern int codingw; void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) { @@ -221,8 +221,6 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) - - int ulsch_decoding_data_2thread0(td_params* tdp) { PHY_VARS_eNB *eNB = tdp->eNB; @@ -242,27 +240,12 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { uint32_t E=0; uint32_t Gp,GpmodC,Nl=1; uint32_t C = ulsch_harq->C; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; @@ -385,7 +368,9 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -427,13 +412,20 @@ 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; + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + thread_top_init("td_thread",1,200000,250000,500000); + pthread_setname_np( pthread_self(),"td processing"); + LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid)); + //wait_sync("td_thread"); while (!oai_exit) { if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break; + if(oai_exit) break; ((td_params*)param)->ret = ulsch_decoding_data_2thread0((td_params*)param); @@ -463,22 +455,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr int G = ulsch_harq->G; unsigned int E; int Cby2; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; struct timespec wait; @@ -487,9 +464,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) { @@ -608,7 +585,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr start_meas(&eNB->ulsch_turbo_decoding_stats); ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -649,6 +628,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr break; } stop_meas(&eNB->ulsch_turbo_decoding_stats); + //printf("/////////////////////////////////////////**************************loop for %d time in ulsch_decoding main\n",r); } // wait for worker to finish @@ -670,27 +650,12 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) int G = ulsch_harq->G; unsigned int E; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = *decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = *decoder8; for (r=0; r<ulsch_harq->C; r++) { @@ -773,7 +738,9 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) start_meas(&eNB->ulsch_turbo_decoding_stats); ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -821,6 +788,20 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) return(ret); } +int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) +{ + int ret = 0; + /*if(codingw) + { + ret = ulsch_decoding_data_2thread(eNB,UE_id,harq_pid,llr8_flag); + } + else*/ + { + ret = ulsch_decoding_data(eNB,UE_id,harq_pid,llr8_flag); + } + return ret; +} + static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) { diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 93f92062eacdffb9a79561a868a0e6eb48cebaa2..7a34c4fc8ab04bd6364d818b189eefa81c0fe8a8 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -30,12 +30,14 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "defs.h" -#include "extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "transport_eNB.h" //#define DEBUG_ULSCH #include "PHY/sse_intrin.h" +#include "transport_common_proto.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" +#include "PHY/MODULATION/modulation_eNB.h" #include "T.h" @@ -725,8 +727,8 @@ void ulsch_extract_rbs_single(int32_t **rxdataF, //uint8_t symbol = l+Ns*frame_parms->symbols_per_tti/2; uint8_t symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame - AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<3), - "nb_antennas_rx not in (1-2)\n"); + AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<5), + "nb_antennas_rx not in (1-4)\n"); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { @@ -1106,7 +1108,7 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext, int ulsch_power_LUT[750]; -void init_ulsch_power_LUT() { +void init_ulsch_power_LUT(void) { int i; @@ -1129,7 +1131,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, uint32_t l,i; int32_t avgs; uint8_t log2_maxh=0,aarx; - int32_t avgU[2]; + int32_t avgU[eNB->frame_parms.nb_antennas_rx]; // uint8_t harq_pid = ( ulsch->RRCConnRequest_flag== 0) ? subframe2harq_pid_tdd(frame_parms->tdd_config,subframe) : 0; @@ -1214,7 +1216,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, avgs = 0; for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) - avgs = cmax(avgs,avgU[(aarx<<1)]); + avgs = cmax(avgs,avgU[aarx]); // log2_maxh = 4+(log2_approx(avgs)/2); @@ -1351,35 +1353,54 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, } - void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id) { + void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id,int round) { uint32_t nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12; uint8_t harq_pid; + char fname[100],vname[100]; harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe); - printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", - subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, + printf("Dumping ULSCH in subframe %d with harq_pid %d, round %d for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", + subframe,harq_pid,round,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm, eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch); - write_output("/tmp/ulsch_d.m","ulsch_dseq",&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], + sprintf(fname,"/tmp/ulsch_r%d_d",round); + sprintf(vname,"/tmp/ulsch_r%d_dseq",round); + write_output(fname,vname,&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus*3,1,0); - if (eNB->common_vars.rxdata) write_output("/tmp/rxsig0.m","rxs0", &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1); + if (eNB->common_vars.rxdata) { + sprintf(fname,"/tmp/rxsig0_r%d.m",round); + sprintf(vname,"rxs0_r%d",round); + write_output(fname,vname, &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) - if (eNB->common_vars.rxdata) write_output("/tmp/rxsig1.m","rxs1", &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1); - - - write_output("/tmp/rxsigF0.m","rxsF0", &eNB->common_vars.rxdataF[0][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) + if (eNB->common_vars.rxdata) { + sprintf(fname,"/tmp/rxsig1_r%d.m",round); + sprintf(vname,"rxs1_r%d",round); + write_output(fname,vname, &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1); + } + } - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/rxsigF1.m","rxsF1", &eNB->common_vars.rxdataF[1][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + sprintf(fname,"/tmp/rxsigF0_r%d.m",round); + sprintf(vname,"rxsF0_r%d",round); + write_output(fname,vname, (void*)&eNB->common_vars.rxdataF[0][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); - write_output("/tmp/rxsigF0_ext.m","rxsF0_ext", &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/rxsigF1_r%d.m",round); + sprintf(vname,"rxsF1_r%d",round); + write_output(vname,fname, &eNB->common_vars.rxdataF[1][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + } - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/rxsigF1_ext.m","rxsF1_ext", &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/rxsigF0_ext_r%d.m",round); + sprintf(vname,"rxsF0_ext_r%d",round); + write_output(fname,vname, &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/rxsigF1_ext_r%d.m",round); + sprintf(vname,"rxsF1_ext_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_ext[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + } /* if (eNB->srs_vars[UE_id].srs_ch_estimates) write_output("/tmp/srs_est0.m","srsest0",eNB->srs_vars[UE_id].srs_ch_estimates[0],eNB->frame_parms.ofdm_symbol_size,1,1); @@ -1387,17 +1408,28 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, if (eNB->srs_vars[UE_id].srs_ch_estimates) write_output("/tmp/srs_est1.m","srsest1",eNB->srs_vars[UE_id].srs_ch_estimates[1],eNB->frame_parms.ofdm_symbol_size,1,1); */ - write_output("/tmp/drs_est0.m","drsest0",eNB->pusch_vars[UE_id]->drs_ch_estimates[0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/drs_est0_r%d.m",round); + sprintf(vname,"drsest0_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/drs_est1.m","drsest1",eNB->pusch_vars[UE_id]->drs_ch_estimates[1],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/drs_est1_r%d.m",round); + sprintf(vname,"drsest1_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[1],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + } - write_output("/tmp/ulsch_rxF_comp0.m","ulsch0_rxF_comp0",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/ulsch0_rxF_comp0_r%d.m",round); + sprintf(vname,"ulsch0_rxF_comp0_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_rxF_comp1.m","ulsch0_rxF_comp1",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); - write_output("/tmp/ulsch_rxF_llr.m","ulsch_llr",eNB->pusch_vars[UE_id]->llr, + sprintf(fname,"/tmp/ulsch_rxF_llr_r%d.m",round); + sprintf(vname,"ulsch_llr_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->llr, eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm *eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch,1,0); - write_output("/tmp/ulsch_ch_mag.m","ulsch_ch_mag",&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/ulsch_ch_mag_r%d.m",round); + sprintf(vname,"ulsch_ch_mag_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_ch_mag1.m","ulsch_ch_mag1",&eNB->pusch_vars[UE_id]->ul_ch_mag[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); //#endif } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..82dedd9bc999895101ce99aeb0b00879227e8867 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -0,0 +1,5160 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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_UE_TRANSPORT/dci_tools_ue.c + * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler. + * \author R. Knopp + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ + +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "SCHED_UE/sched_UE.h" +#ifdef DEBUG_DCI_TOOLS +#include "PHY/phy_vars.h" +#endif +#include "assertions.h" + + +//#define DEBUG_HARQ + + +#include "LAYER2/MAC/mac.h" + +//#define DEBUG_DCI + +#include "../LTE_TRANSPORT/dci_tools_common_extern.h" +#include "../LTE_TRANSPORT/transport_proto.h" +#include "transport_proto_ue.h" +#include "../LTE_TRANSPORT/transport_common_proto.h" +#include "SCHED/sched_common.h" + +extern uint16_t beta_cqi[16]; +extern uint16_t beta_ri[16]; +extern uint16_t beta_ack[16]; + +void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + uint8_t harq_pid=0; + uint32_t rballoc=0; + uint8_t vrb_type=0; + uint8_t mcs=0; + uint8_t rv=0; + uint8_t ndi=0; + uint8_t TPC=0; + + uint8_t dai=0; + + switch (N_RB_DL) { + case 6: + if (frame_type == TDD) { + vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; + // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } + break; + + case 25: + + if (frame_type == TDD) { + vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai; + //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } + + break; + + case 50: + if (frame_type == TDD) { + vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai; + // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, vrb_type %d, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,vrb_type,rballoc,ndi,rv,TPC); + } + break; + + case 100: + if (frame_type == TDD) { + vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai; + // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } + break; + } + + pdci_info_extarcted->vrb_type = vrb_type; + pdci_info_extarcted->mcs1 = mcs; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->rv1 = rv; + pdci_info_extarcted->ndi1 = ndi; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->harq_pid = harq_pid; + pdci_info_extarcted->dai = dai; +} + +void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t mcs=0; + + switch (N_RB_DL) { + case 6: + mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); + + break; + + case 25: + mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); + + break; + + case 50: + mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6); + + break; + + case 100: + mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6); + break; + + default: + AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",N_RB_DL); + break; + } + + pdci_info_extarcted->mcs1 = mcs; + pdci_info_extarcted->rballoc = rballoc; +} + +void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t mcs=0; + uint8_t rah=0; + uint8_t rv=0; + uint8_t TPC=0; + uint8_t ndi=0; + uint8_t harq_pid=0; + + switch (N_RB_DL) { + case 6: + if (frame_type == TDD) { + mcs = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + + case 25: + if (frame_type == TDD) { + mcs = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + + case 50: + if (frame_type == TDD) { + mcs = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + + case 100: + if (frame_type == TDD) { + mcs = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + } + + pdci_info_extarcted->mcs1 = mcs; + pdci_info_extarcted->rah = rah; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->rv1 = rv; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->ndi1 = ndi; + pdci_info_extarcted->harq_pid = harq_pid; + +} + +void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t rah=0; + uint8_t mcs1=0; + uint8_t mcs2=0; + uint8_t rv1=0; + uint8_t rv2=0; + uint8_t ndi1=0; + uint8_t ndi2=0; + uint8_t tbswap=0; + uint8_t tpmi=0; + uint8_t harq_pid=0; + uint8_t TPC=0; + + switch (N_RB_DL) { + + case 6: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + + case 25: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + + case 50: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + + case 100: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + } + + pdci_info_extarcted->rah = rah; + pdci_info_extarcted->mcs1 = mcs1; + pdci_info_extarcted->mcs2 = mcs2; + pdci_info_extarcted->rv1 = rv1; + pdci_info_extarcted->rv2 = rv2; + pdci_info_extarcted->harq_pid = harq_pid; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->tb_swap = tbswap; + pdci_info_extarcted->tpmi = tpmi; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->ndi1 = ndi1; + pdci_info_extarcted->ndi2 = ndi2; + +} + +void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t rah=0; + uint8_t mcs1=0; + uint8_t mcs2=0; + uint8_t rv1=0; + uint8_t rv2=0; + uint8_t ndi1=0; + uint8_t ndi2=0; + uint8_t tbswap=0; + uint8_t tpmi=0; + uint8_t harq_pid=0; + uint8_t TPC=0; + + AssertFatal( (nb_antenna_ports_eNB == 2) || (nb_antenna_ports_eNB == 4), "unsupported nb_antenna_ports_eNB %d\n", nb_antenna_ports_eNB); + switch (N_RB_DL) { + + case 6: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + + break; + + case 25: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + break; + + case 50: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + + break; + + case 100: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + + break; + } + + pdci_info_extarcted->mcs1 = mcs1; + pdci_info_extarcted->mcs2 = mcs2; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->rah = rah; + pdci_info_extarcted->rv1 = rv1; + pdci_info_extarcted->rv2 = rv2; + pdci_info_extarcted->ndi1 = ndi1; + pdci_info_extarcted->ndi2 = ndi2; + pdci_info_extarcted->harq_pid = harq_pid; + pdci_info_extarcted->tb_swap = tbswap; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->tpmi = tpmi; +} + +int check_dci_format1_1a_coherency(DCI_format_t dci_format, + uint8_t N_RB_DL, + uint16_t rnti, + uint16_t tc_rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + uint32_t frame, + uint8_t subframe, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_UE_HARQ_t *pdlsch0_harq) +{ + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t TPC = pdci_info_extarcted->TPC; + uint8_t rah = pdci_info_extarcted->rah; +#ifdef DEBUG_DCI + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t ndi1 = pdci_info_extarcted->ndi1; +#endif + + uint8_t NPRB = 0; + long long int RIV_max = 0; + +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, subframe, dci_format); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti %x\n", rnti); + LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid %d\n", harq_pid); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); + LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); +#endif + + + // I- check dci content minimum coherency + if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0) + { + return(0); + } + + if(harq_pid>=8) + { + // LOG_I(PHY,"bad harq id \n"); + return(0); + } + + if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) ) + { + // LOG_I(PHY,"bad dci format \n"); + return(0); + } + + + if( mcs1 > 28) + { + if(pdlsch0_harq->round == 0) + { + // LOG_I(PHY,"bad dci mcs + round \n"); + return(0); + } + + if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + // LOG_I(PHY,"bad dci mcs + rnti \n"); + return(0); + } + } + + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + NPRB = (TPC&1) + 2; + switch (N_RB_DL) { + case 6: + RIV_max = RIV_max6; + break; + case 25: + RIV_max = RIV_max25; + break; + case 50: + RIV_max = RIV_max50; + break; + case 100: + RIV_max = RIV_max100; + break; + } + } + else + { + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + if(rah) + RIV_max = RIV_max6; + else + RIV_max = 0x3F; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + if(rah) + RIV_max = RIV_max25; + else + RIV_max = 0x1FFF; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + if(rah) + RIV_max = RIV_max50; + else + RIV_max = 0x1FFFF; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + if(rah) + RIV_max = RIV_max100; + else + RIV_max = 0x1FFFFFF; + break; + } + } + + + if(dci_format == format1) + { + NPRB = conv_nprb(rah, rballoc, N_RB_DL); + } + + + if(rballoc > RIV_max) + { + // LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); + // DCI false detection + return(0); + } + + if(NPRB == 0) + { + // DCI false detection + // LOG_I(PHY,"bad NPRB = 0 \n"); + return(0); + } + + // this a retransmission + if(pdlsch0_harq->round>0) + { + // compare old TBS to new TBS + if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1])) + { + // this is an eNB issue + // retransmisison but old and new TBS are different !!! + // work around, consider it as a new transmission + LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n"); + pdlsch0_harq->round = 0; + //return(0); // ?? to cross check + } + } + + return(1); +} + +int check_dci_format1c_coherency(uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + uint16_t rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + LTE_DL_UE_HARQ_t *pdlsch0_harq) +{ + uint32_t rballoc = pdci_info_extarcted->rballoc; + + uint8_t NPRB = 0; + uint32_t RIV_max = 0; + + // I- check dci content minimum coherency + + if((rnti!=si_rnti) && (rnti!=p_rnti) && (rnti!=ra_rnti)) + return(0); + + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + RIV_max = RIV_max6; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + RIV_max = RIV_max25; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + RIV_max = RIV_max50; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + RIV_max = RIV_max100; + break; + } + + if(rballoc > RIV_max) + { + // DCI false detection + return(0); + } + + if(NPRB == 0) + { + // DCI false detection + return(0); + } + + return(1); +} + +int check_dci_format2_2a_coherency(DCI_format_t dci_format, + uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + uint16_t rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + LTE_DL_UE_HARQ_t *pdlsch0_harq, + LTE_DL_UE_HARQ_t *pdlsch1_harq) +{ + uint8_t rah = pdci_info_extarcted->rah; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t mcs2 = pdci_info_extarcted->mcs2; + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t rv2 = pdci_info_extarcted->rv2; + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + +#ifdef DEBUG_DCI + uint8_t ndi1 = pdci_info_extarcted->ndi1; + uint8_t ndi2 = pdci_info_extarcted->ndi2; +#endif + + uint8_t NPRB = 0; + long long RIV_max = 0; + +#ifdef DEBUG_DCI + LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format); + LOG_I(PHY, "extarcted dci - rnti %d \n", rnti); + LOG_I(PHY, "extarcted dci - rah %d \n", rah); + LOG_I(PHY, "extarcted dci - mcs1 %d \n", mcs1); + LOG_I(PHY, "extarcted dci - mcs2 %d \n", mcs2); + LOG_I(PHY, "extarcted dci - rv1 %d \n", rv1); + LOG_I(PHY, "extarcted dci - rv2 %d \n", rv2); + //LOG_I(PHY, "extarcted dci - ndi1 %d \n", ndi1); + //LOG_I(PHY, "extarcted dci - ndi2 %d \n", ndi2); + LOG_I(PHY, "extarcted dci - rballoc %x \n", rballoc); + LOG_I(PHY, "extarcted dci - harq pid %d \n", harq_pid); + LOG_I(PHY, "extarcted dci - round0 %d \n", pdlsch0_harq->round); + LOG_I(PHY, "extarcted dci - round1 %d \n", pdlsch1_harq->round); +#endif + + // I- check dci content minimum coherency + if(harq_pid>=8) + { + // LOG_I(PHY,"bad harq pid\n"); + return(0); + } + + if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) ) + { + // LOG_I(PHY,"bad rnti\n"); + return(0); + } + + + if( mcs1 > 28) + { + if(pdlsch0_harq->round == 0) + { + // LOG_I(PHY,"bad mcs1\n"); + return(0); + } + } + + if( mcs2 > 28) + { + if(pdlsch1_harq->round == 0) + { + // LOG_I(PHY,"bad mcs2\n"); + return(0); + } + } + + + if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0)) + { + // DCI false detection + // LOG_I(PHY,"bad rv1\n"); + return(0); + } + + if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0)) + { + // DCI false detection + // LOG_I(PHY,"bad rv2\n"); + return(0); + } + + + switch (N_RB_DL) { + case 6: + if (rah == 0) + { + //RBG = 1; + RIV_max = 0x3F; + } + else + { + RIV_max = RIV_max6; + } + break; + case 25: + if (rah == 0) + { + //RBG = 2; + RIV_max = 0x1FFF; + } + else + { + RIV_max = RIV_max25; + } + break; + case 50: + if (rah == 0) + { + //RBG = 3; + RIV_max = 0x1FFFF; + } + else + { + RIV_max = RIV_max50; + } + break; + case 100: + if (rah == 0) + { + //RBG = 4; + RIV_max = 0x1FFFFFF; + } + else + { + RIV_max = RIV_max100; + } + break; + } + + NPRB = conv_nprb(rah, + rballoc, + N_RB_DL); + + + + if( (rballoc > RIV_max) && (rah == 1) ) + { + // DCI false detection + // LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); + return(0); + } + + if(NPRB == 0) + { + // DCI false detection + // LOG_I(PHY,"bad NPRB\n"); + return(0); + } + + return(1); +} + +void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDCCH *pdcch_vars, + LTE_UE_PDSCH *pdsch_vars, + LTE_DL_UE_HARQ_t *dlsch0_harq, + uint8_t nb_rb_alloc, + uint8_t subframe) +{ + uint32_t pbch_pss_sss_re; + uint32_t crs_re; + uint32_t granted_re; + uint32_t data_re; + uint32_t llr_offset; + uint8_t symbol; + uint8_t symbol_mod; + + pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0; + + LOG_D(PHY,"compute_llr_offset: nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm); + + //dlsch0_harq->rb_alloc_even; + //dlsch0_harq->rb_alloc_odd; + + for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++) + { + symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; + if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp)) + { + if (frame_parms->nb_antennas_tx == 2) + crs_re = 4; + else + crs_re = 2; + } + else + { + crs_re = 0; + } + + granted_re = nb_rb_alloc * (12-crs_re); + pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol); + pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12); + data_re = granted_re - pbch_pss_sss_re; + llr_offset = data_re * dlsch0_harq->Qm * 2; + + pdsch_vars->llr_length[symbol] = data_re; + if(symbol < (frame_parms->symbols_per_tti-1)) + pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset; + + LOG_D(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb); + LOG_D(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re); + LOG_D(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re); + LOG_D(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re); + + + + LOG_D(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol, + pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]); + } +} +void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, + uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDCCH *pdcch_vars, + LTE_UE_PDSCH *pdsch_vars, + uint8_t subframe, + uint16_t rnti, + uint16_t tc_rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + LTE_DL_UE_HARQ_t *pdlsch0_harq, + LTE_UE_DLSCH_t *pdlsch0) +{ + + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint8_t vrb_type = pdci_info_extarcted->vrb_type; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t ndi1 = pdci_info_extarcted->ndi1; + uint8_t TPC = pdci_info_extarcted->TPC; + uint8_t rah = pdci_info_extarcted->rah; + uint8_t dai = pdci_info_extarcted->dai; + + + uint8_t NPRB = 0; + uint8_t NPRB4TBS = 0; + + if(dci_format == format1A) + { + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc]; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc]; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc]; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc]; + break; + } + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + NPRB4TBS = (TPC&1) + 2; + } + else + { + NPRB4TBS = NPRB; + /* + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + break; + } + + */ + } + } + else // format1 + { + NPRB = conv_nprb(rah, rballoc, N_RB_DL); + NPRB4TBS=NPRB; + } + + pdlsch0->current_harq_pid = harq_pid; + pdlsch0->active = 1; + pdlsch0->rnti = rnti; + if(dci_format == format1A) + pdlsch0->harq_ack[subframe].vDAI_DL = dai+1; + + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + pdlsch0_harq->round = 0; + pdlsch0_harq->status = ACTIVE; + } + else //CRNTI + { + if (rnti == tc_rnti) { + //fix for standalone Contention Resolution Id + pdlsch0_harq->DCINdi = (uint8_t)-1; + LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n", + rnti,harq_pid,pdlsch0_harq->DCINdi); + } + + // NDI has been toggled or this is the first transmission + if ((ndi1!=pdlsch0_harq->DCINdi) || (pdlsch0_harq->first_tx==1)) + { + pdlsch0_harq->round = 0; + pdlsch0_harq->first_tx = 0; + pdlsch0_harq->status = ACTIVE; + + }else if (rv1 != 0 ) + //NDI has not been toggled but rv was increased by eNB: retransmission + { + if (pdlsch0_harq->status == SCH_IDLE) + //packet was actually decoded in previous transmission (ACK was missed by eNB) + //However, the round is not a good check as it might have been decoded in a retransmission prior to this one. + { + // LOG_D(PHY,"skip pdsch decoding and report ack\n"); + // skip pdsch decoding and report ack + //pdlsch0_harq->status = SCH_IDLE; + pdlsch0->active = 0; + pdlsch0->harq_ack[subframe].ack = 1; + pdlsch0->harq_ack[subframe].harq_id = harq_pid; + pdlsch0->harq_ack[subframe].send_harq_status = 1; + + //pdlsch0_harq->first_tx = 0; + } + else //normal retransmission + { + // nothing special to do + } + } + else + { + pdlsch0_harq->status = ACTIVE; + } + } + + pdlsch0_harq->DCINdi = ndi1; + pdlsch0_harq->mcs = mcs1; + pdlsch0_harq->rvidx = rv1; + pdlsch0_harq->nb_rb = NPRB; + + pdlsch0_harq->codeword = 0; + pdlsch0_harq->Nl = 1; + pdlsch0_harq->mimo_mode = frame_parms->nb_antenna_ports_eNB == 1 ?SISO : ALAMOUTI; + pdlsch0_harq->dl_power_off = 1; //no power offset + pdlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC &3]; + + // compute resource allocation + if(dci_format == format1A) + { + switch (N_RB_DL) { + case 6: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; + } + break; + + case 25: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; + } + break; + + case 50: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; + } else { // DISTRIBUTED + if ((rballoc&(1<<10)) == 0) { + rballoc = rballoc&(~(1<<10)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } + else { + rballoc = rballoc&(~(1<<10)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } + } + break; + + case 100: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; + } else { + if ((rballoc&(1<<10)) == 0) { //Gap 1 + rballoc = rballoc&(~(1<<12)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + } + else { //Gap 2 + rballoc = rballoc&(~(1<<12)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + } + } + break; + } + } + else // format1 + { + conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,pdlsch0_harq->rb_alloc_even); + pdlsch0_harq->rb_alloc_odd[0]= pdlsch0_harq->rb_alloc_even[0]; + pdlsch0_harq->rb_alloc_odd[1]= pdlsch0_harq->rb_alloc_even[1]; + pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2]; + pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3]; + } + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + pdlsch0_harq->TBS = TBStable[mcs1][NPRB4TBS-1]; + pdlsch0_harq->Qm = 2; + } + else + { + if(mcs1 < 29) + { + pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB4TBS-1]; + pdlsch0_harq->Qm = get_Qm(mcs1); + } + } + + compute_llr_offset(frame_parms, + pdcch_vars, + pdsch_vars, + pdlsch0_harq, + NPRB, + subframe); +} + +void prepare_dl_decoding_format1C(uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDCCH *pdcch_vars, + LTE_UE_PDSCH *pdsch_vars, + uint32_t rnti, + uint32_t si_rnti, + uint32_t ra_rnti, + uint32_t p_rnti, + uint32_t frame, + uint8_t subframe, + LTE_DL_UE_HARQ_t *pdlsch0_harq, + LTE_UE_DLSCH_t *pdlsch0) +{ + + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t Ngap = pdci_info_extarcted->Ngap; + + pdlsch0_harq->round = 0; + pdlsch0_harq->first_tx = 1; + pdlsch0_harq->vrb_type = DISTRIBUTED; + + if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321 + if (((frame&1) == 0) && (subframe == 5)) + pdlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 + else + pdlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs + } + else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3 + pdlsch0_harq->rvidx = 0; + } + + + pdlsch0_harq->Nl = 1; + pdlsch0_harq->mimo_mode = frame_parms->nb_antenna_ports_eNB == 1 ?SISO : ALAMOUTI; + pdlsch0_harq->dl_power_off = 1; //no power offset + + pdlsch0_harq->codeword = 0; + pdlsch0_harq->mcs = mcs1; + pdlsch0_harq->TBS = TBStable1C[mcs1]; + pdlsch0_harq->Qm = 2; + + + pdlsch0->current_harq_pid = harq_pid; + pdlsch0->active = 1; + pdlsch0->rnti = rnti; + + switch (N_RB_DL) { + case 6: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; + + break; + + case 25: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; + break; + + case 50: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc]; + if (Ngap == 0) { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; + } + break; + + case 100: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc]; + if (Ngap==0) { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + } + break; + + default: + AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL); + break; + } + + compute_llr_offset(frame_parms, + pdcch_vars, + pdsch_vars, + pdlsch0_harq, + pdlsch0_harq->nb_rb, + subframe); + +} + +void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq) +{ + +switch (tpmi) { + case 0: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + break; + case 1: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + break; + case 2: // PUSCH precoding + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + if (tbswap==0){ + dlsch0_harq->pmi_alloc = pmi_alloc; + dlsch1_harq->pmi_alloc = pmi_alloc^0x1555; + } else { + dlsch1_harq->pmi_alloc = pmi_alloc; + dlsch0_harq->pmi_alloc = pmi_alloc^0x1555; + } +#ifdef DEBUG_HARQ + printf ("\n \n compute_precoding_info_2cw pmi_alloc_new = %d\n", dlsch0_harq->pmi_alloc); + #endif + break; + default: + break; + } +} + +void compute_precoding_info_1cw(uint8_t tpmi, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch_harq) +{ + +switch (tpmi) { + case 0 : + dlsch_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); + break; + case 2: + dlsch_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; + case 3: + dlsch_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + break; + case 4: + dlsch_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; + case 5: + dlsch_harq->mimo_mode = PUSCH_PRECODING0; + dlsch_harq->pmi_alloc = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); + break; + case 6: + dlsch_harq->mimo_mode = PUSCH_PRECODING1; + dlsch_harq->pmi_alloc = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); + break; + } + #ifdef DEBUG_HARQ + printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi); + #endif + } + +void compute_precoding_info_format2A(uint8_t tpmi, + uint8_t nb_antenna_ports_eNB, + uint8_t tb0_active, + uint8_t tb1_active, + LTE_DL_UE_HARQ_t *dlsch0_harq, + LTE_DL_UE_HARQ_t *dlsch1_harq) +{ + + dlsch0_harq->dl_power_off = 0; + dlsch1_harq->dl_power_off = 0; + + if (nb_antenna_ports_eNB == 2) { + if ((tb0_active==1) && (tb1_active==1)) { + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + } else { + dlsch0_harq->mimo_mode = ALAMOUTI; + dlsch1_harq->mimo_mode = ALAMOUTI; + } + } else if (nb_antenna_ports_eNB == 4) { // 4 antenna case + if ((tb0_active==1) && (tb1_active==1)) { + switch (tpmi) { + case 0: // one layer per transport block + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + break; + + case 1: // one-layers on TB 0, two on TB 1 + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + break; + + case 2: // two-layers on TB 0, two on TB 1 + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + break; + + case 3: // + LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n"); + break; + } + } else if (tb0_active == 1) { + switch (tpmi) { + case 0: // one layer per transport block + dlsch0_harq->mimo_mode = ALAMOUTI; + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + + case 1: // two-layers on TB 0 + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + break; + + case 2: // two-layers on TB 0, two on TB 1 + case 3: // + LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); + break; + } + } else if (tb1_active == 1) { + switch (tpmi) { + case 0: // one layer per transport block + dlsch0_harq->mimo_mode = ALAMOUTI; + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + + case 1: // two-layers on TB 0 + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + break; + + case 2: // two-layers on TB 0, two on TB 1 + case 3: // + LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); + break; + } + } + } + // printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active); + //printf("UE (%x/%d): Subframe %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, + // dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status); + //printf("TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS); + +} + +void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDCCH *pdcch_vars, + LTE_UE_PDSCH *pdsch_vars, + uint16_t rnti, + uint8_t subframe, + LTE_DL_UE_HARQ_t *dlsch0_harq, + LTE_DL_UE_HARQ_t *dlsch1_harq, + LTE_UE_DLSCH_t *pdlsch0, + LTE_UE_DLSCH_t *pdlsch1) +{ + + uint8_t rah = pdci_info_extarcted->rah; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t mcs2 = pdci_info_extarcted->mcs2; + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t rv2 = pdci_info_extarcted->rv2; + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t tbswap = pdci_info_extarcted->tb_swap; + uint8_t tpmi = pdci_info_extarcted->tpmi; + uint8_t TPC = pdci_info_extarcted->TPC; + uint8_t ndi1 = pdci_info_extarcted->ndi1; + uint8_t ndi2 = pdci_info_extarcted->ndi2; + + uint8_t TB0_active = 1; + uint8_t TB1_active = 1; + + // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc); + + + if ((rv1 == 1) && (mcs1 == 0)) { + TB0_active=0; + } + if ((rv2 == 1) && (mcs2 == 0)) { + TB1_active=0; + } + +#ifdef DEBUG_HARQ + printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active); +#endif + + dlsch0_harq->mcs = mcs1; + dlsch1_harq->mcs = mcs2; + dlsch0_harq->rvidx = rv1; + dlsch1_harq->rvidx = rv2; + dlsch0_harq->DCINdi = ndi1; + dlsch1_harq->DCINdi = ndi2; + + dlsch0_harq->codeword = 0; + dlsch1_harq->codeword = 1; + dlsch0_harq->Nl = 1; + dlsch1_harq->Nl = 1; + dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + + pdlsch0->current_harq_pid = harq_pid; + pdlsch0->harq_ack[subframe].harq_id = harq_pid; + pdlsch1->current_harq_pid = harq_pid; + pdlsch1->harq_ack[subframe].harq_id = harq_pid; + + // assume two CW are active + dlsch0_harq->status = ACTIVE; + dlsch1_harq->status = ACTIVE; + pdlsch0->active = 1; + pdlsch1->active = 1; + pdlsch0->rnti = rnti; + pdlsch1->rnti = rnti; + + + if (TB0_active && TB1_active && tbswap==1) { + dlsch0_harq->codeword = 1; + dlsch1_harq->codeword = 0; + } + + + if (!TB0_active && TB1_active){ + dlsch1_harq->codeword = 0; + } + + if (TB0_active && !TB1_active){ + dlsch0_harq->codeword = 0; + } + + + if (TB0_active==0) { + dlsch0_harq->status = SCH_IDLE; + pdlsch0->active = 0; + #ifdef DEBUG_HARQ + printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); + #endif + } + + if (TB1_active==0) { + dlsch1_harq->status = SCH_IDLE; + pdlsch1->active = 0; + } + +#ifdef DEBUG_HARQ + printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); +#endif + + // compute resource allocation + if (TB0_active == 1){ + + dlsch0_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch0_harq->rb_alloc_even); + + dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; + dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; + dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; + dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; + + if (TB1_active == 1){ + dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; + dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0]; + dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1]; + dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; + dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; + + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + + //dlsch0_harq->Nl = 1; + //dlsch1_harq->Nl = 1; + } + } else if ((TB0_active == 0) && (TB1_active == 1)){ + + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch1_harq->rb_alloc_even); + + dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3]; + dlsch1_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); + } + + + // compute precoding matrix + mimo mode + if(dci_format == format2) + { + if ((TB0_active) && (TB1_active)){ //two CW active + compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq); + + // printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); + } else if ((TB0_active) && (!TB1_active)) { // only CW 0 active + compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq); + } else { + compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq); + // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi); + } + //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); + if ((frame_parms->nb_antenna_ports_eNB == 1) && (TB0_active)) + dlsch0_harq->mimo_mode = SISO; + } + else + { + compute_precoding_info_format2A( tpmi, + frame_parms->nb_antenna_ports_eNB, + TB0_active, + TB1_active, + dlsch0_harq, + dlsch1_harq); + } + // printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); + // reset round + compute Qm + if (TB0_active) { + // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx); + if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { + dlsch0_harq->round = 0; + dlsch0_harq->status = ACTIVE; + dlsch0_harq->DCINdi = ndi1; + + //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n", + // subframe,harq_pid,dlsch0_harq->round); + if ( dlsch0_harq->first_tx==1) { + // LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); + dlsch0_harq->first_tx = 0; + } + } + /*else if (rv1 != 0 ) + //NDI has not been toggled but rv was increased by eNB: retransmission + { + if(dlsch0_harq->status == SCH_IDLE) { + // skip pdsch decoding and report ack + //dlsch0_harq->status = SCH_IDLE; + pdlsch0->active = 0; + pdlsch0->harq_ack[subframe].ack = 1; + pdlsch0->harq_ack[subframe].harq_id = harq_pid; + pdlsch0->harq_ack[subframe].send_harq_status = 1; + }*/ + + // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest + // PDCCH for the same trasport block using Imcs in [0 .. 28] + if(dlsch0_harq->mcs <= 28) + { + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + LOG_D(PHY,"[UE] DLSCH: New TBS CW0 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); + } + else + { + LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW0 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); + } + //if(dlsch0_harq->Nl == 2) + //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; + if (mcs1 <= 28) + dlsch0_harq->Qm = get_Qm(mcs1); + else if (mcs1<=31) + dlsch0_harq->Qm = (mcs1-28)<<1; + } + + // printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); + + if (TB1_active) { + // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx); + if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { + dlsch1_harq->round = 0; + dlsch1_harq->status = ACTIVE; + dlsch1_harq->DCINdi = ndi2; + //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n", + // subframe,harq_pid,dlsch0_harq->round); + if (dlsch1_harq->first_tx==1) { + // LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); + dlsch1_harq->first_tx = 0; + } + } + /*else if (rv1 != 0 ) + //NDI has not been toggled but rv was increased by eNB: retransmission + { + if(dlsch1_harq->status == SCH_IDLE) { + // skip pdsch decoding and report ack + //dlsch1_harq->status = SCH_IDLE; + pdlsch1->active = 0; + pdlsch1->harq_ack[subframe].ack = 1; + pdlsch1->harq_ack[subframe].harq_id = harq_pid; + pdlsch1->harq_ack[subframe].send_harq_status = 1; + } + }*/ + + // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest + // PDCCH for the same trasport block using Imcs in [0 .. 28] + if(dlsch1_harq->mcs <= 28) + { + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; + LOG_D(PHY,"[UE] DLSCH: New TBS CW1 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); + } + else + { + LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW1 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); + } + if (mcs2 <= 28) + dlsch1_harq->Qm = get_Qm(mcs2); + else if (mcs1<=31) + dlsch1_harq->Qm = (mcs2-28)<<1; + } + + + compute_llr_offset(frame_parms, + pdcch_vars, + pdsch_vars, + dlsch0_harq, + dlsch0_harq->nb_rb, + subframe); + + + /* #ifdef DEBUG_HARQ + printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); + printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active); + if (dlsch0 != NULL && dlsch1 != NULL) + printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status); + else if (dlsch0 == NULL && dlsch1 != NULL) + printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status); + else if (dlsch0 != NULL && dlsch1 == NULL) + printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status); + #endif*/ +} + +int generate_ue_dlsch_params_from_dci(int frame, + uint8_t subframe, + void *dci_pdu, + uint16_t rnti, + DCI_format_t dci_format, + LTE_UE_PDCCH *pdcch_vars, + LTE_UE_PDSCH *pdsch_vars, + LTE_UE_DLSCH_t **dlsch, + LTE_DL_FRAME_PARMS *frame_parms, + PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + uint8_t beamforming_mode, + uint16_t tc_rnti) +{ + + uint8_t harq_pid=0; + uint8_t frame_type=frame_parms->frame_type; + uint8_t tpmi=0; + LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; + LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; + + DCI_INFO_EXTRACTED_t dci_info_extarcted; + uint8_t status=0; + + 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, + frame%1024, + subframe, + (dci_format==format0? "Format 0":( + dci_format==format1? "format 1":( + dci_format==format1A? "format 1A":( + dci_format==format1B? "format 1B":( + dci_format==format1C? "format 1C":( + dci_format==format1D? "format 1D":( + dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":( + dci_format==format2? "format 2":( + dci_format==format2A? "format 2A":( + dci_format==format2B? "format 2B":( + dci_format==format2C? "format 2C":( + dci_format==format2D? "format 2D":( + dci_format==format3? "format 3": "UNKNOWN" + )))))))))))))); + #endif + + memset(&dci_info_extarcted,0,sizeof(dci_info_extarcted)); + switch (dci_format) { + + case format0: // This is an ULSCH allocation so nothing here, inform MAC + LOG_E(PHY,"format0 not possible\n"); + return(-1); + break; + + case format1A: + { + // extract dci infomation +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d extarct dci info \n", frame, subframe); +#endif + extract_dci1A_info(frame_parms->N_RB_DL, + frame_type, + dci_pdu, + &dci_info_extarcted); + + + // check dci content + dlsch0 = dlsch[0]; + dlsch0->active = 0; + dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d check dci coherency \n", frame, subframe); +#endif + status = check_dci_format1_1a_coherency(format1A, + frame_parms->N_RB_DL, + rnti, + tc_rnti, + si_rnti, + ra_rnti, + p_rnti,frame,subframe, + &dci_info_extarcted, + dlsch0_harq); + if(status == 0) + { + printf("bad DCI 1A !!! \n"); + return(-1); + } + + // dci is correct ==> update internal structure and prepare dl decoding +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe); +#endif + prepare_dl_decoding_format1_1A(format1A, + frame_parms->N_RB_DL, + &dci_info_extarcted, + frame_parms, + pdcch_vars, + pdsch_vars, + subframe, + rnti, + tc_rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch0); + + + + break; + } + case format1C: + { + // extract dci infomation +#ifdef DEBUG_DL_DECODING + LOG_I(PHY,"[DCI Format-1C] extact dci information \n"); +#endif + extract_dci1C_info(frame_parms->N_RB_DL, + frame_type, + dci_pdu, + &dci_info_extarcted); + + + // check dci content +#ifdef DEBUG_DL_DECODING + LOG_I(PHY,"[DCI Format-1C] check dci content \n"); +#endif + dlsch0 = dlsch[0]; + dlsch0->active = 0; + dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; + + status = check_dci_format1c_coherency(frame_parms->N_RB_DL, + &dci_info_extarcted, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq); + if(status == 0) + return(-1); + + // dci is correct ==> update internal structure and prepare dl decoding +#ifdef DEBUG_DL_DECODING + LOG_I(PHY,"[DCI Format-1C] prepare downlink decoding \n"); +#endif + prepare_dl_decoding_format1C(frame_parms->N_RB_DL, + &dci_info_extarcted, + frame_parms, + pdcch_vars, + pdsch_vars, + rnti, + si_rnti, + ra_rnti, + p_rnti, + frame, + subframe, + dlsch0_harq, + dlsch0); + + break; + } + + case format1: + { + // extract dci infomation +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d extarct dci info \n", frame, subframe); +#endif + extract_dci1_info(frame_parms->N_RB_DL, + frame_type, + dci_pdu, + &dci_info_extarcted); + + // check dci content + dlsch0 = dlsch[0]; + dlsch0->active = 0; + dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; + +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d check dci coherency \n", frame, subframe); +#endif + status = check_dci_format1_1a_coherency(format1, + frame_parms->N_RB_DL, + rnti, + tc_rnti, + si_rnti, + ra_rnti, + p_rnti,frame,subframe, + &dci_info_extarcted, + dlsch0_harq); + if(status == 0) + { + printf("bad DCI 1 !!! \n"); + return(-1); + } + + + // dci is correct ==> update internal structure and prepare dl decoding +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe); +#endif + prepare_dl_decoding_format1_1A(format1, + frame_parms->N_RB_DL, + &dci_info_extarcted, + frame_parms, + pdcch_vars, + pdsch_vars, + subframe, + rnti, + tc_rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch0); + break; + } + + case format2: + { + // extract dci infomation + //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame, subframe); + extract_dci2_info(frame_parms->N_RB_DL, + frame_type, + frame_parms->nb_antenna_ports_eNB, + dci_pdu, + &dci_info_extarcted); + + + // check dci content + dlsch[0]->active = 1; + dlsch[1]->active = 1; + + dlsch0 = dlsch[0]; + dlsch1 = dlsch[1]; + + dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; + dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; + // printf("before coherency dlsch[1]->pmi_alloc %d\n",dlsch[1]->pmi_alloc); + // printf("before coherency dlsch1->pmi_alloc %d\n",dlsch1->pmi_alloc); + // printf("before coherency dlsch1_harq->pmi_alloc %d\n",dlsch1_harq->pmi_alloc); + + //LOG_I(PHY,"[DCI-format2] check dci content \n"); + status = check_dci_format2_2a_coherency(format2, + frame_parms->N_RB_DL, + &dci_info_extarcted, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch1_harq); + if(status == 0) + return(-1); + + + // dci is correct ==> update internal structure and prepare dl decoding + //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n"); + prepare_dl_decoding_format2_2A(format2, + &dci_info_extarcted, + frame_parms, + pdcch_vars, + pdsch_vars, + rnti, + subframe, + dlsch0_harq, + dlsch1_harq, + dlsch0, + dlsch1); + } + break; + + case format2A: + { + // extract dci infomation + LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe); + extract_dci2A_info(frame_parms->N_RB_DL, + frame_type, + frame_parms->nb_antenna_ports_eNB, + dci_pdu, + &dci_info_extarcted); + + // check dci content + //LOG_I(PHY,"[DCI-format2A] check dci content \n"); + //LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid); + //dlsch[0]->active = 0; + //dlsch[1]->active = 0; + + if (dci_info_extarcted.tb_swap == 0) { + dlsch0 = dlsch[0]; + dlsch1 = dlsch[1]; + } else { + dlsch0 = dlsch[1]; + dlsch1 = dlsch[0]; + } + dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; + dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; + + //LOG_I(PHY,"[DCI-format2A] check dci content \n"); + status = check_dci_format2_2a_coherency(format2A, + frame_parms->N_RB_DL, + &dci_info_extarcted, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch1_harq); + if(status == 0) + return(-1); + + // dci is correct ==> update internal structure and prepare dl decoding + //LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n"); + prepare_dl_decoding_format2_2A(format2A, + &dci_info_extarcted, + frame_parms, + pdcch_vars, + pdsch_vars, + rnti, + subframe, + dlsch0_harq, + dlsch1_harq, + dlsch0, + dlsch1); + } + break; + + case format1E_2A_M10PRB: + if (!dlsch[0]) return -1; + + harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; + + if (harq_pid>=8) { + LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); + return(-1); + } + + dlsch[0]->current_harq_pid = harq_pid; + dlsch[0]->harq_ack[subframe].harq_id = harq_pid; + + /* + tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap; + if (tbswap == 0) { + dlsch0 = dlsch[0]; + dlsch1 = dlsch[1]; + } + else{ + dlsch0 = dlsch[1]; + dlsch1 = dlsch[0]; + } + */ + dlsch0 = dlsch[0]; + + dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; + conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL, + dlsch0_harq->rb_alloc_even); + + dlsch0_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_even[0]; + dlsch0_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_even[1]; + dlsch0_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_even[2]; + dlsch0_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_even[3]; + /* + dlsch1_harq->rb_alloc_even[0] = dlsch0_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_even[1] = dlsch0_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_even[2] = dlsch0_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_even[3] = dlsch0_harq->rb_alloc_even[3]; + */ + dlsch0_harq->nb_rb = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc, + frame_parms->N_RB_DL); + //dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + + dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; + dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->TPC&3]; + + + + /* + if (dlsch0_harq->mcs>20) { + printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs); + return(-1); + } + */ + + //dlsch1_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2; + dlsch0_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv; + //dlsch1_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2; + + // check if either TB is disabled (see 36-213 V8.6 p. 26) + + if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { + dlsch0_harq->status = DISABLED; + } + + //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { + //dlsch1_harq->status = DISABLED; + //} + dlsch0_harq->Nl = 1; + + //dlsch0->layer_index = tbswap; + //dlsch1->layer_index = 1-tbswap; + + + // Fix this + tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi; + // printf("ue: tpmi %d\n",tpmi); + + switch (tpmi) { + case 0 : + dlsch0_harq->mimo_mode = ALAMOUTI; + break; + + case 1: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); + break; + + case 2: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; + + case 3: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + + break; + + case 4: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; + + case 5: + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; + + + case 6: + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + LOG_E(PHY,"Unsupported TPMI\n"); + return(-1); + break; + } + + + if (frame_parms->nb_antenna_ports_eNB == 1) + dlsch0_harq->mimo_mode = SISO; + + + if ((dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) || + (dlsch0_harq->first_tx==1)) { + + dlsch0_harq->round = 0; + dlsch0_harq->first_tx = 0; + dlsch0_harq->status = ACTIVE; + } + /* + else if (dlsch0_harq->status == SCH_IDLE) { // we got same ndi for a previously decoded process, + // this happens if either another harq process in the same + // is NAK or an ACK was not received + + dlsch0->harq_ack[subframe].ack = 1; + dlsch0->harq_ack[subframe].harq_id = harq_pid; + dlsch0->harq_ack[subframe].send_harq_status = 1; + dlsch0->active = 0; + return(0); + } + */ + + dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi; + dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; + + if (dlsch0_harq->nb_rb>1) { + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + } else + dlsch0_harq->TBS =0; + + dlsch0->rnti = rnti; + //dlsch1->rnti = rnti; + + dlsch0->active = 1; + //dlsch1->active = 1; + + dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; + //dlsch1_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; + + + break; + + default: + LOG_E(PHY,"format %d not yet implemented\n",dci_format); + return(-1); + break; + } + +#ifdef UE_DEBUG_TRACE + + if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { + LOG_I(PHY,"dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe); + LOG_I(PHY,"PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti); + LOG_D(PHY,"PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb); + LOG_D(PHY,"PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); + LOG_I(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",dci_info_extarcted.harq_pid); + LOG_I(PHY,"PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); + LOG_D(PHY,"PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); + LOG_D(PHY,"PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); + LOG_D(PHY,"PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx); + LOG_D(PHY,"PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS); + LOG_D(PHY,"PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); + LOG_D(PHY,"PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); + } +#endif + +#if T_TRACER + if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) + { + T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe), + T_INT(dlsch[0]->rnti), T_INT(dci_format), + T_INT(harq_pid), + T_INT(dlsch0_harq->mcs), + T_INT(dlsch0_harq->TBS)); + } +#endif + + + // compute DL power control parameters + if (dlsch0_harq != NULL){ + computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); + computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off); + } + + if (dlsch1_harq != NULL) { + computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); + computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off); + } + + + return(0); +} + + + +int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb) +{ + int nb_subbands = 0; + int32_t pmi_alloc_new = 0, pmi_new = 0, pmi_old = 0; + int i; + + switch (nb_rb) { + case 6: + nb_subbands = 6; + break; + default: + case 25: + nb_subbands = 7; + break; + case 50: + nb_subbands = 9; + break; + case 100: + nb_subbands = 13; + break; + } + + for (i = 0; i < nb_subbands; i++) { + pmi_old = (pmi_alloc >> i)&1; + + if (pmi_old == 0) + if (tpmi == 5) + pmi_new = 0; + else + pmi_new = 1; + else + if (tpmi == 5) + pmi_new = 2; + else + pmi_new = 3; + + pmi_alloc_new|=pmi_new<<(2*i); + + } +#ifdef DEBUG_HARQ +printf(" [DCI UE] pmi_alloc_old %d, pmi_alloc_new %d pmi_old %d , pmi_new %d\n", pmi_alloc, pmi_alloc_new,pmi_old, pmi_new ); +#endif +return(pmi_alloc_new); + +} + +uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) +{ + + int i, aarx; + uint16_t pmiq=0; + uint32_t pmivect = 0; + uint8_t rank = meas->rank[eNB_id]; + int pmi_re,pmi_im; + int nb_subbands=0; + + + switch (nb_rb) { + case 6: + nb_subbands = 6; + break; + default: + case 25: + nb_subbands = 7; + break; + case 50: + nb_subbands = 9; + break; + case 100: + nb_subbands = 13; + break; + } + + + for (i=0; i<nb_subbands; i++) { + pmi_re = 0; + pmi_im = 0; + + if (rank == 0) { + for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) { + pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; + pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; + } + + // pmi_re = meas->subband_pmi_re[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]]; + // pmi_im = meas->subband_pmi_im[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]]; + + // printf("pmi => (%d,%d)\n",pmi_re,pmi_im); + if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) + pmiq = PMI_2A_11; + else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) + pmiq = PMI_2A_1j; + else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) + pmiq = PMI_2A_1m1; + else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) + pmiq = PMI_2A_1mj; + + // printf("subband %d, pmi%d \n",i,pmiq); + pmivect |= (pmiq<<(2*i)); + } + + else if (rank==1) { + for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) { + pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; + //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]); + pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; + //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); + } + if (pmi_re >= pmi_im) // this is not orthogonal + // this is orthogonal + //if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im))) + pmiq = PMI_2A_R1_11; + else + pmiq = PMI_2A_R1_1j; + + // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); + // printf("subband %d, pmi%d \n",i,pmiq); + //According to Section 7.2.4 of 36.213 + + pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit + } + else { + LOG_E(PHY,"PMI feedback for rank>1 not supported!\n"); + pmivect = 0; + } + + } +#ifdef DEBUG_HARQ + printf( "quantize_subband_pmi pmivect %d \n", pmivect); +#endif + return(pmivect); +} + +uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands) +{ + + uint8_t i; + uint16_t pmiq=0; + uint16_t pmivect = 0; + uint8_t rank = meas->rank[eNB_id]; + int pmi_re,pmi_im; + + for (i=0; i<nb_subbands; i++) { + + if (rank == 0) { + pmi_re = meas->subband_pmi_re[eNB_id][i][a_id]; + pmi_im = meas->subband_pmi_im[eNB_id][i][a_id]; + + if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) + pmiq = PMI_2A_11; + else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) + pmiq = PMI_2A_1j; + else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) + pmiq = PMI_2A_1m1; + else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) + pmiq = PMI_2A_1mj; + + pmivect |= (pmiq<<(2*i)); + } else { + // This needs to be done properly!!! + pmivect = 0; + } + } + + return(pmivect); +} + +uint16_t quantize_wideband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) +{ + + uint16_t pmiq=0; + uint8_t rank = meas->rank[eNB_id]; + //int pmi; + int pmi_re,pmi_im; + + if (rank == 1) { + //pmi = + pmi_re = meas->wideband_pmi_re[eNB_id][meas->selected_rx_antennas[eNB_id][0]]; + pmi_im = meas->wideband_pmi_im[eNB_id][meas->selected_rx_antennas[eNB_id][0]]; + + if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) + pmiq = PMI_2A_11; + else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) + pmiq = PMI_2A_1j; + else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) + pmiq = PMI_2A_1m1; + else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) + pmiq = PMI_2A_1mj; + + } else { + // This needs to be done properly! + pmiq = PMI_2A_11; + } + + + return(pmiq); +} +/* + uint8_t sinr2cqi(int sinr) { + if (sinr<-3) + return(0); + if (sinr>14) + return(10); + else + return(3+(sinr>>1)); + } +*/ + +uint8_t sinr2cqi(double sinr,uint8_t trans_mode) +{ + // int flag_LA=0; + + uint8_t retValue = 0; + + if(flag_LA==0) { + // Ideal Channel Estimation + if (sinr<=-4.89) + retValue = (0); + else if (sinr < -3.53) + retValue = (3); + else if (sinr <= -1.93) + retValue = (4); + else if (sinr <= -0.43) + retValue = (5); + else if (sinr <= 1.11) + retValue = (6); + else if (sinr <= 3.26) + retValue = (7); + else if (sinr <= 5.0) + retValue = (8); + else if (sinr <= 7.0) + retValue = (9); + else if (sinr <= 9.0) + retValue = (10); + else if (sinr <= 11.0) + retValue = (11); + else if (sinr <= 13.0) + retValue = (12); + else if (sinr <= 15.5) + retValue = (13); + else if (sinr <= 17.5) + retValue = (14); + else + retValue = (15); + } else { + int h=0; + int trans_mode_tmp; + + if (trans_mode ==5) + trans_mode_tmp=2; + else if(trans_mode ==6) + trans_mode_tmp=3; + else + trans_mode_tmp = trans_mode-1; + + for(h=0; h<16; h++) { + if(sinr<=sinr_to_cqi[trans_mode_tmp][h]) + retValue = (h); + } + } + + LOG_D(PHY, "sinr=%f trans_mode=%d cqi=%d\n", sinr, trans_mode, retValue); + return retValue; +} +//uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) { +// +// uint8_t i; +//// uint16_t cqivect = 0; +// uint32_t cqivect = 0; +// +//// char diff_cqi; +// int diff_cqi=0; +// +// for (i=0;i<NUMBER_OF_SUBBANDS;i++) { +// +// diff_cqi = -sinr2cqi(meas->wideband_cqi_dB[eNB_id][0]) + sinr2cqi(meas->subband_cqi_dB[eNB_id][0][i]); +// +// // Note, this is Table 7.2.1-2 from 36.213 +// if (diff_cqi<=-1) +// diff_cqi = 3; +// else if (diff_cqi>2) +// diff_cqi = 2; +// cqivect |= (diff_cqi<<(2*i)); +// +// } +// +// return(cqivect); +//} + + +uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t trans_mode,int nb_subbands) +{ + + uint8_t i; + + uint32_t cqivect = 0,offset=0; + + + int diff_cqi=0; + + for (i=0; i<nb_subbands; i++) { + + diff_cqi = -sinr2cqi(meas->wideband_cqi_avg[eNB_id],trans_mode) + sinr2cqi(meas->subband_cqi_tot_dB[eNB_id][i],trans_mode); + + // Note, this is Table 7.2.1-2 from 36.213 + if (diff_cqi<=-1) + offset = 3; + else if (diff_cqi>=2) + offset = 2; + else + offset=(uint32_t)diff_cqi; + + cqivect |= (offset<<(2*i)); + + } + + return(cqivect); +} + +void fill_CQI(LTE_UE_ULSCH_t *ulsch,PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t harq_pid,int N_RB_DL,uint16_t rnti, uint8_t trans_mode, double sinr_eff) +{ + + // printf("[PHY][UE] Filling CQI for eNB %d, meas->wideband_cqi_tot[%d] %d\n", + // eNB_id,eNB_id,meas->wideband_cqi_tot[eNB_id]); + double sinr_tmp; + uint8_t *o = ulsch->o; + UCI_format_t uci_format = ulsch->uci_format; + + if(flag_LA==1) + sinr_tmp = sinr_eff; + else + sinr_tmp = (double) meas->wideband_cqi_avg[eNB_id]; + + + + //LOG_I(PHY,"[UE][UCI] Filling CQI format %d for eNB %d N_RB_DL %d\n",uci_format,eNB_id,N_RB_DL); + + switch (N_RB_DL) { + + case 6: + switch (uci_format) { + case wideband_cqi_rank1_2A: + ((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); + break; + + case wideband_cqi_rank2_2A: + ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); + break; + + case HLC_subband_cqi_nopmi: + ((HLC_subband_cqi_nopmi_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_nopmi_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); + break; + + case HLC_subband_cqi_rank1_2A: + ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); + ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); + break; + + case HLC_subband_cqi_rank2_2A: + // This has to be improved!!! + ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); + ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,6); + ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); + break; + + case HLC_subband_cqi_mcs_CBA: + // this is the cba mcs uci for cba transmission + ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; + ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti = rnti; + LOG_D(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); + break; + + case ue_selected: + LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); + AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); + break; + + default: + LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); + AssertFatal(1==0,"unsupported CQI mode !!!"); + break; + + } + + break; + + case 25: + switch (uci_format) { + case wideband_cqi_rank1_2A: + ((wideband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((wideband_cqi_rank1_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); + break; + + case wideband_cqi_rank2_2A: + ((wideband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); + break; + + case HLC_subband_cqi_nopmi: + ((HLC_subband_cqi_nopmi_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_nopmi_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); + break; + + case HLC_subband_cqi_rank1_2A: + ((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); + ((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); + break; + + case HLC_subband_cqi_rank2_2A: + // This has to be improved!!! + ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); + ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,7); + ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); + break; + + case HLC_subband_cqi_mcs_CBA: + // this is the cba mcs uci for cba transmission + ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; + ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = rnti; + LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); + break; + + case ue_selected: + LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); + AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); + break; + + default: + LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); + AssertFatal(1==0,"unsupported CQI mode !!!"); + break; + + } + + break; + + case 50: + switch (uci_format) { + case wideband_cqi_rank1_2A: + ((wideband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((wideband_cqi_rank1_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); + break; + + case wideband_cqi_rank2_2A: + ((wideband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); + break; + + case HLC_subband_cqi_nopmi: + ((HLC_subband_cqi_nopmi_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_nopmi_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); + break; + + case HLC_subband_cqi_rank1_2A: + ((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); + ((HLC_subband_cqi_rank1_2A_10MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); + break; + + case HLC_subband_cqi_rank2_2A: + // This has to be improved!!! + ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); + ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,9); + ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); + break; + + case HLC_subband_cqi_mcs_CBA: + // this is the cba mcs uci for cba transmission + ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; + ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti = rnti; + LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); + break; + + case ue_selected: + LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); + AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); + break; + + default: + LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); + AssertFatal(1==0,"unsupported CQI mode !!!"); + break; + + } + + break; + + case 100: + switch (uci_format) { + case wideband_cqi_rank1_2A: + ((wideband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((wideband_cqi_rank1_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); + break; + + case wideband_cqi_rank2_2A: + ((wideband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi + ((wideband_cqi_rank2_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); + break; + + case HLC_subband_cqi_nopmi: + ((HLC_subband_cqi_nopmi_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_nopmi_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); + break; + + case HLC_subband_cqi_rank1_2A: + ((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); + ((HLC_subband_cqi_rank1_2A_20MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); + break; + + case HLC_subband_cqi_rank2_2A: + // This has to be improved!!! + ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); + ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); + ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,13); + ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); + break; + + case HLC_subband_cqi_mcs_CBA: + // this is the cba mcs uci for cba transmission + ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; + ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti = rnti; + LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); + break; + + case ue_selected: + LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); + AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!"); + break; + + default: + LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); + AssertFatal(1==0,"unsupported CQI mode !!!"); + break; + + } + + break; + + } + + +} + +void reset_cba_uci(void *o) +{ + // this is the cba mcs uci for cba transmission + ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs = 0; //fixme + ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = 0x0; +} + + + + + +int generate_ue_ulsch_params_from_dci(void *dci_pdu, + uint16_t rnti, + uint8_t subframe, + DCI_format_t dci_format, + PHY_VARS_UE *ue, + UE_rxtx_proc_t *proc, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + uint16_t cba_rnti, + uint8_t eNB_id, + uint8_t use_srs) +{ + + uint8_t harq_pid; + uint8_t transmission_mode = ue->transmission_mode[eNB_id]; + ANFBmode_t AckNackFBMode; + LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; + LTE_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[subframe]][0]; + PHY_MEASUREMENTS *meas = &ue->measurements; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + // uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; + + if(frame_parms->frame_type == TDD) + { + AckNackFBMode = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode; + } + else + { + AckNackFBMode = 1; // 1: multiplexing for FDD + } + + uint32_t cqi_req; + uint32_t dai=3; + uint32_t cshift; + uint32_t TPC; + uint32_t ndi; + uint32_t mcs; + uint32_t rballoc,RIV_max; + uint16_t* RIV2first_rb_LUT; + uint16_t* RIV2nb_rb_LUT; + + // uint32_t hopping; + // uint32_t type; + + if (dci_format == format0) { + + if (!ulsch) + return -1; + + if (rnti == ra_rnti) + harq_pid = 0; + else + harq_pid = subframe2harq_pid(frame_parms, + pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,subframe), + pdcch_alloc2ul_subframe(frame_parms,subframe)); + LOG_D(PHY,"Frame %d, Subframe %d: Programming ULSCH for (%d.%d) => harq_pid %d\n", + proc->frame_rx,subframe, + pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,subframe), + pdcch_alloc2ul_subframe(frame_parms,subframe), harq_pid); + + if (harq_pid == 255) { + LOG_E(PHY, "frame %d, subframe %d, rnti %x, format %d: illegal harq_pid!\n", + proc->frame_rx, subframe, rnti, dci_format); + return(-1); + } + + switch (frame_parms->N_RB_DL) { + case 6: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + ndi = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; + mcs = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi; + mcs = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max6; + RIV2first_rb_LUT = RIV2first_rb_LUT6; + RIV2nb_rb_LUT = RIV2nb_rb_LUT6; + + break; + + case 25: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + ndi = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi; + mcs = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi; + mcs = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_5MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max25; + RIV2first_rb_LUT = RIV2first_rb_LUT25; + RIV2nb_rb_LUT = RIV2nb_rb_LUT25; + // printf("***********rballoc %d, first_rb %d, nb_rb %d (dci %p)\n",rballoc,ulsch->harq_processes[harq_pid]->first_rb,ulsch->harq_processes[harq_pid]->nb_rb,dci_pdu); + break; + + case 50: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC; + ndi = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi; + mcs = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi; + mcs = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_10MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max50; + RIV2first_rb_LUT = RIV2first_rb_LUT50; + RIV2nb_rb_LUT = RIV2nb_rb_LUT50; + + break; + + case 100: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC; + ndi = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi; + mcs = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi; + mcs = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_20MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max100; + RIV2first_rb_LUT = RIV2first_rb_LUT100; + RIV2nb_rb_LUT = RIV2nb_rb_LUT100; + + // printf("rb_alloc (20 MHz dci) %d\n",rballoc); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + + + if (rballoc > RIV_max) { + LOG_E(PHY,"frame %d, subframe %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[%d] > RIV_max[%d]\n", + proc->frame_rx, subframe, rnti, dci_format,rballoc,RIV_max); + LOG_E(PHY,"Wrong DCI0 detection, do not transmit PUSCH for HARQID: %d\n",harq_pid); + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; + return(-1); + } + + + // indicate that this process is to be serviced in subframe n+4 + if ((rnti >= cba_rnti) && (rnti < p_rnti)) + ulsch->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; //+=1 this indicates the number of dci / cba group: not supported in the data struct + else + { + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; + //LOG_I(PHY,"[HARQ-UL harqId: %d] DCI0 ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); + + } + + ulsch->harq_processes[harq_pid]->TPC = TPC; + ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT[rballoc]; + ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT[rballoc]; + + if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n", + ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch, + delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC], + ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC); + ulsch->f_pusch += delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC]; + } else { + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ABS) %d, adjusting to %d (TPC %d)\n", + ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch, + delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC], + ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC); + ulsch->f_pusch = delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC]; + } + + if (ulsch->harq_processes[harq_pid]->first_tx==1) { + // ulsch->harq_processes[harq_pid]->Ndi = 1; + ulsch->harq_processes[harq_pid]->first_tx=0; + ulsch->harq_processes[harq_pid]->DCINdi= ndi; + ulsch->harq_processes[harq_pid]->round = 0; + } else { + if (ulsch->harq_processes[harq_pid]->DCINdi!=ndi) { // new SDU opportunity + // ulsch->harq_processes[harq_pid]->Ndi = 1; + ulsch->harq_processes[harq_pid]->DCINdi= ndi; + ulsch->harq_processes[harq_pid]->round = 0; + } else { + // ulsch->harq_processes[harq_pid]->Ndi = 0; + //ulsch->harq_processes[harq_pid]->round++; // This is done in phich RX + + //#ifdef DEBUG_PHICH + //LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d Adaptative Retrans, NDI not toggled => Nack. maxHARQ_Tx %d \n", + // ue->Mod_id,harq_pid, + // proc->frame_rx, + // subframe, + // ulsch->Mlimit); + //#endif +/* + if (ulsch->harq_processes[harq_pid]->round > 0) // NACK detected on phich + { + // ulsch->harq_processes[harq_pid]->round++; already done on phich_rx + // ulsch->harq_processes[harq_pid] = ulsch->harq_processes[8]; + // LOG_I(PHY," Adaptative retransmission - copy temporary harq Process to current harq process. [harqId %d round %d] \n",harq_pid, ulsch->harq_processes[8]->round); + + if (ulsch->harq_processes[harq_pid]->round >= ulsch->Mlimit) //UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx) + { + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; + ulsch->harq_processes[harq_pid]->round = 0; + ulsch->harq_processes[harq_pid]->status = IDLE; + //LOG_I(PHY," PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid); + //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); + } + else + { + // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; + uint8_t rv_table[4] = {0, 2, 3, 1}; + ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; + ulsch->O_RI = 0; + ulsch->O = 0; + ulsch->uci_format = HLC_subband_cqi_nopmi; + //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round); + } + } +*/ + } + } + + ulsch->harq_processes[harq_pid]->n_DMRS = cshift; + + //printf("nb_rb %d, first_rb %d (RIV %d)\n",ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,rballoc); + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + // ulsch->cba_rnti[0]=rnti; + } else { + ulsch->rnti = rnti; + } + + // printf("[PHY][UE] DCI format 0: harq_pid %d nb_rb %d, rballoc %d\n",harq_pid,ulsch->harq_processes[harq_pid]->nb_rb, + // ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc); + //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) + if(cshift == 0) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; + else if(cshift == 1) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 6; + else if(cshift == 2) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 3; + else if(cshift == 3) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 4; + else if(cshift == 4) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 2; + else if(cshift == 5) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 8; + else if(cshift == 6) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; + else if(cshift == 7) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; + + + //reserved for cooperative communication + /* + if(ulsch->n_DMRS2 == 6) + ulsch->cooperation_flag = 2; + else + ulsch->cooperation_flag = 0; + */ + + if ((ulsch->harq_processes[harq_pid]->nb_rb>0) && (ulsch->harq_processes[harq_pid]->nb_rb < 25)) + ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb-1]; + + // if (ulsch->harq_processes[harq_pid]->Ndi == 1) + // ulsch->harq_processes[harq_pid]->status = ACTIVE; + + + if (cqi_req == 1) { + + if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) ) + { + ulsch->O_RI = 1; + } + else + { + ulsch->O_RI = 0; + } + //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table + + switch(transmission_mode) { + // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling + case 1: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + case 2: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + case 3: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + case 4: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank1_2A; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank2_2A; + ulsch->o_RI[0] = 1; + } + + break; + + case 5: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank1_2A; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank2_2A; + ulsch->o_RI[0] = 1; + } + + break; + + case 6: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank1_2A; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank2_2A; + ulsch->o_RI[0] = 1; + } + + break; + + case 7: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + default: + LOG_E(PHY,"Incorrect Transmission Mode \n"); + break; + } + } else { + ulsch->O_RI = 0; + ulsch->O = 0; + ulsch->uci_format = HLC_subband_cqi_nopmi; + } + + print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL); + + ulsch->bundling = 1-AckNackFBMode; + + if (frame_parms->frame_type == FDD) { + //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); + int dl_subframe = subframe; + + if (ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission + ulsch->harq_processes[harq_pid]->O_ACK = 1; + } else { + ulsch->harq_processes[harq_pid]->O_ACK = 0; + } + /*LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe, + ue->dlsch[0][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, + ue->dlsch[1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, + harq_pid, + ulsch->harq_processes[harq_pid]->O_ACK);*/ + + } else { + if (ulsch->bundling) + ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1; + else + ulsch->harq_processes[harq_pid]->O_ACK = (dai >= 2)? 2 : (dai+1)&3; //(dai+1)&3; + + // ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1; + } + + dlsch[0]->harq_ack[subframe].vDAI_UL = dai+1; + + + LOG_D(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d" + " ulsch->bundling %d, O_ACK %d \n", + harq_pid, + (frame_parms->frame_type == TDD? "TDD" : "FDD"), + cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc, + ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb, + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, + ulsch->bundling, + ulsch->harq_processes[harq_pid]->O_ACK); + + LOG_D(PHY,"Setting beta_offset_cqi_times8 to %d, index %d\n", + beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index], + ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index); + + ulsch->beta_offset_cqi_times8 = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18; + ulsch->beta_offset_ri_times8 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10; + ulsch->beta_offset_harqack_times8 = beta_ack[ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index];//16; + + ulsch->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); + ulsch->srs_active = use_srs; + + if ((rnti >= cba_rnti) && (rnti < p_rnti)) + ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; + else + ulsch->harq_processes[harq_pid]->status = ACTIVE; + + ulsch->harq_processes[harq_pid]->rvidx = 0; + + // ulsch->harq_processes[harq_pid]->calibration_flag =0; + if (mcs < 29) { + ulsch->harq_processes[harq_pid]->mcs = mcs; + // ulsch->harq_processes[harq_pid]->round = 0; + } else { + ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; + if (ulsch->harq_processes[harq_pid]->round == 0) { + LOG_W(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); + } else { + LOG_D(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); + } + //LOG_E(PHY,"Fatal: mcs(%d) > 28!!! and round == 0\n", mcs); + } + ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; + + /* + else if (ulsch->harq_processes[harq_pid]->mcs == 29) { + ulsch->harq_processes[harq_pid]->mcs = 4; + ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; + // ulsch->harq_processes[harq_pid]->calibration_flag =1; + // printf("Auto-Calibration (UE): mcs %d, TBS %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->TBS,ulsch->harq_processes[harq_pid]->nb_rb); + }*/ + ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; + ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->Nsymb_pusch; + + // a Ndi=1 automatically acknowledges previous PUSCH transmission + if (ue->ulsch_Msg3_active[eNB_id] == 1) + ue->ulsch_Msg3_active[eNB_id] = 0; + + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d, cqi_req %d => O %d\n", + ue->Mod_id,harq_pid, + proc->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb, + ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id],cqi_req,ulsch->O); + + // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; + +#ifdef UE_DEBUG_TRACE + + LOG_D(PHY,"Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe); + LOG_D(PHY,"Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): rballoc %d\n",rballoc); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): harq_pid %d\n",harq_pid); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_tx %d\n",ulsch->harq_processes[harq_pid]->first_tx); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): DCINdi %d\n",ulsch->harq_processes[harq_pid]->DCINdi); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): round %d\n",ulsch->harq_processes[harq_pid]->round); + //LOG_I(PHY,"Format 0 DCI :ulsch (ue): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); + //LOG_I(PHY,"Format 0 DCI :ulsch (ue): O %d\n",ulsch->O); + //LOG_I(PHY,"Format 0 DCI :ulsch (ue): cqiReq %d\n",cqi_req); + //if (frame_parms->frame_type == TDD) + // LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK/DAI %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai); + //else + // LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK %d\n",ulsch->harq_processes[harq_pid]->O_ACK); + + LOG_D(PHY,"Format 0 DCI :ulsch (ue): Nsymb_pusch %d\n",ulsch->Nsymb_pusch); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); + LOG_D(PHY,"Format 0 DCI :ulsch (ue): phich status %d\n",ulsch->harq_processes[harq_pid]->status); +#else + UNUSED_VARIABLE(dai); +#endif + return(0); + } else { + LOG_E(PHY,"frame %d, subframe %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n", + proc->frame_rx, subframe,dci_format); + return(-1); + } + +} + +/* +int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, + eNB_rxtx_proc_t *proc, + void *dci_pdu, + uint16_t rnti, + DCI_format_t dci_format, + uint8_t UE_id, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + uint16_t cba_rnti, + uint8_t use_srs) +{ + + uint8_t harq_pid; + uint32_t rb_alloc; + uint8_t transmission_mode=eNB->transmission_mode[UE_id]; + ANFBmode_t AckNackFBMode = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode; + LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + int subframe = proc->subframe_tx; + + uint32_t cqi_req = 0; + uint32_t dai = 0; + uint32_t cshift = 0; + uint32_t TPC = 0; + uint32_t mcs = 0; + uint32_t rballoc = UINT32_MAX; + uint32_t RIV_max = 0; + // uint32_t hopping; + // uint32_t type; + +#ifdef DEBUG_DCI + printf("filling eNB ulsch params for rnti %x, dci format %d, dci %x, subframe %d\n", + rnti,dci_format,*(uint32_t*)dci_pdu,subframe); +#endif + + if (dci_format == format0) { + + harq_pid = subframe2harq_pid(frame_parms, + pdcch_alloc2ul_frame(frame_parms, + proc->frame_tx, + subframe), + pdcch_alloc2ul_subframe(frame_parms,subframe)); + switch (frame_parms->N_RB_DL) { + case 6: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + mcs = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC; + mcs = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping; + // type = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max6; + ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT6[rballoc]; + ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT6[rballoc]; + + break; + + case 25: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + mcs = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping; + // type = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC; + mcs = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping; + // type = ((DCI0_5MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max25; + ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT25[rballoc]; + ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT25[rballoc]; + + break; + + case 50: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC; + mcs = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping; + // type = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC; + mcs = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping; + // type = ((DCI0_10MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max50; + ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT50[rballoc]; + ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT50[rballoc]; + + break; + + case 100: + if (frame_parms->frame_type == TDD) { + cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req; + dai = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai; + cshift = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift; + TPC = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC; + mcs = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping; + // type = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type; + } else { + cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req; + cshift = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift; + TPC = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC; + mcs = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc; + // hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping; + // type = ((DCI0_20MHz_FDD_t *)dci_pdu)->type; + } + + RIV_max = RIV_max100; + ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT100[rballoc]; + ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT100[rballoc]; + + //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } + + + rb_alloc = rballoc; + AssertFatal(rb_alloc>RIV_max, + "Format 0: rb_alloc (%d) > RIV_max (%d)\n",rb_alloc,RIV_max); +#ifdef DEBUG_DCI + printf("generate_eNB_ulsch_params_from_dci: subframe %d, rnti %x,harq_pid %d,cqi_req %d\n",subframe,rnti,harq_pid,cqi_req); +#endif + + ulsch->harq_processes[harq_pid]->dci_alloc = 1; + ulsch->harq_processes[harq_pid]->rar_alloc = 0; + ulsch->harq_processes[harq_pid]->TPC = TPC; + ulsch->harq_processes[harq_pid]->n_DMRS = cshift; + + + if (cqi_req == 1) { + // 36.213 7.2.1 (release 10) says: + // "RI is only reported for transmission modes 3 and 4, + // as well as transmission modes 8 and 9 with PMI/RI reporting" + // This is for aperiodic reporting. + // TODO: deal with TM 8&9 correctly when they are implemented. + // TODO: deal with periodic reporting if we implement it. + // + if (transmission_mode == 3 || transmission_mode == 4) + ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table + else + ulsch->harq_processes[harq_pid]->O_RI = 0; + + switch(transmission_mode) { + // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling + case 1: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; + } else { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; + } + + break; + + case 2: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; + } else { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; + } + + break; + + case 3: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; + } else { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; + } + + break; + + case 4: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; + } else { + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + + } + + ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; + } + + break; + + case 5: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; + } else { + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; + } + + break; + + case 6: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; + } else { + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; + ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; + } + + break; + + case 7: + ulsch->harq_processes[harq_pid]->Or2 = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; + break; + + default: + LOG_E(PHY,"Incorrect Transmission Mode \n"); + break; + } + } else { + ulsch->harq_processes[harq_pid]->O_RI = 0; + ulsch->harq_processes[harq_pid]->Or2 = 0; + ulsch->harq_processes[harq_pid]->Or1 = 0; + ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; + } + + ulsch->bundling = 1-AckNackFBMode; + + if (frame_parms->frame_type == FDD) { + int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); + + if (eNB->dlsch[UE_id][0]->subframe_tx[dl_subframe]>0) { // we have downlink transmission + ulsch->harq_processes[harq_pid]->O_ACK = 1; + } else { + ulsch->harq_processes[harq_pid]->O_ACK = 0; + } + } else { + if (ulsch->bundling) + ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1; + else + ulsch->harq_processes[harq_pid]->O_ACK = (dai+1)&3; + + ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1; + } + + ulsch->beta_offset_cqi_times8 = beta_cqi[eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index];//18; + ulsch->beta_offset_ri_times8 = beta_ri[eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index];//10; + ulsch->beta_offset_harqack_times8 = beta_ack[eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index];//16; + + ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); + ulsch->harq_processes[harq_pid]->srs_active = use_srs; + + //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) + if(cshift == 0) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; + else if(cshift == 1) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 6; + else if(cshift == 2) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 3; + else if(cshift == 3) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 4; + else if(cshift == 4) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 2; + else if(cshift == 5) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 8; + else if(cshift == 6) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; + else if(cshift == 7) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; + + + LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d)\n", + eNB->Mod_id,harq_pid,proc->frame_tx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift); + + + + if (ulsch->harq_processes[harq_pid]->round == 0) { + if ((rnti >= cba_rnti) && (rnti < p_rnti)) + ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; + else + ulsch->harq_processes[harq_pid]->status = ACTIVE; + + ulsch->harq_processes[harq_pid]->rvidx = 0; + ulsch->harq_processes[harq_pid]->mcs = mcs; + // ulsch->harq_processes[harq_pid]->calibration_flag = 0; + //if (ulsch->harq_processes[harq_pid]->mcs) + // + //if (ulsch->harq_processes[harq_pid]->mcs == 29) { + //ulsch->harq_processes[harq_pid]->mcs = 4; + // ulsch->harq_processes[harq_pid]->calibration_flag = 1; + // printf("Auto-Calibration (eNB): mcs %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->nb_rb); + //} + + ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; + + ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; + ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch; + ulsch->harq_processes[harq_pid]->round = 0; + } else { + if (mcs>28) + ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; + else { + ulsch->harq_processes[harq_pid]->rvidx = 0; + ulsch->harq_processes[harq_pid]->mcs = mcs; + } + + // ulsch->harq_processes[harq_pid]->round++; + } + + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + ulsch->cba_rnti[0] = rnti; + } else { + ulsch->rnti = rnti; + } + + //ulsch->n_DMRS2 = cshift; + +#ifdef DEBUG_DCI + printf("ulsch (eNB): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); + printf("ulsch (eNB): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb); + printf("ulsch (eNB): harq_pid %d\n",harq_pid); + printf("ulsch (eNB): round %d\n",ulsch->harq_processes[harq_pid]->round); + printf("ulsch (eNB): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); + printf("ulsch (eNB): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); + printf("ulsch (eNB): Or1 %d\n",ulsch->harq_processes[harq_pid]->Or1); + printf("ulsch (eNB): Nsymb_pusch %d\n",ulsch->harq_processes[harq_pid]->Nsymb_pusch); + printf("ulsch (eNB): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); +#else + UNUSED_VARIABLE(dai); +#endif + return(0); + } else { + LOG_E(PHY,"generate_eNB_ulsch_params_from_dci, Illegal dci_format %d\n",dci_format); + return(-1); + } + +} +*/ + +double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe) +{ + uint8_t transmission_mode = ue->transmission_mode[eNB_id]; + PHY_MEASUREMENTS *meas = &ue->measurements; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; + double *s_dB; + s_dB = ue->sinr_CQI_dB; + // LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; + //for the calculation of SINR_eff for CQI calculation + int count,a_rx,a_tx; + double abs_channel=0; + double channelx=0; + double channely=0; + double channelx_i=0; + double channely_i=0; + uint16_t q = quantize_subband_pmi(meas,eNB_id,7); + uint8_t qq; + + switch(transmission_mode) { + case 1: + for (count=0; count<frame_parms->N_RB_DL*12; count++) { + for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { + for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { + s_dB[count] = 10*log10(pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2], + 2)) - meas->n0_power_avg_dB; + } + } + } + + break; + + case 2: + for (count=0; count<frame_parms->N_RB_DL*12; count++) { + abs_channel=0; + + for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { + for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { + abs_channel += (pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],2)); + } + } + + s_dB[count] = 10*log10(abs_channel/2) - meas->n0_power_avg_dB; + } + + break; + + case 5: + for (count=0; count<frame_parms->N_RB_DL*12; count++) { + channelx=0; + channely=0; + channelx_i=0; + channely_i=0; + qq = (q>>(((count/12)>>2)<<1))&3; + + //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq); + for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { + for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { + switch(qq) { + case 0: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + case 1: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + case 2: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + case 3: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + default: + printf("Problem in SINR Calculation for TM5 \n"); + break; + }//switch(qq) + }//a_rx + }//a_tx + + s_dB[count] = 10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - 10 * log10 ((pow(channelx_i,2) + pow(channely_i,2))/2) - meas->n0_power_avg_dB; + }//count + + break; + + case 6: + for (count=0; count<frame_parms->N_RB_DL*12; count++) { + channelx=0; + channely=0; + qq = (q>>(((count/12)>>2)<<1))&3; + + //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq); + for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { + for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { + switch(qq) { + case 0: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + case 1: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + case 2: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + case 3: + if (channelx==0 || channely==0) { + channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + } else { + channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; + channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; + } + + break; + + default: + printf("Problem in SINR Calculation for TM6 \n"); + break; + }//switch(qq) + }//a_rx + }//a_tx + + s_dB[count] = 10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - meas->n0_power_avg_dB; + }//count + + break; + + default: + printf("Problem in SINR Calculation for CQI \n"); + break; + } + + int ii; + double sinr_eff = 0; + double sinr_eff_qpsk=0; + double sinr_eff_qam16=0; + double sinr_eff_qam64=0; + double x = 0; + double I_qpsk=0; + double I_qam16=0; + double I_qam64=0; + double I_qpsk_avg=0; + double I_qam16_avg=0; + double I_qam64_avg=0; + double qpsk_max=12.2; + double qam16_max=19.2; + double qam64_max=25.2; + double sinr_min = -20; + int offset=0; + + + for (offset = 0; offset <= 24; offset++) { + for(ii=0; ii<12; ii++) { + //x is the sinr_dB in dB + x = s_dB[(offset*12)+ii]; + + if(x<sinr_min) { + I_qpsk +=0; + I_qam16 +=0; + I_qam64 +=0; + } else { + if(x>qpsk_max) + I_qpsk += 1; + else + I_qpsk += (q_qpsk[0]*pow(x,7) + q_qpsk[1]*pow(x,6) + q_qpsk[2]*pow(x,5) + q_qpsk[3]*pow(x,4) + q_qpsk[4]*pow(x,3) + q_qpsk[5]*pow(x,2) + q_qpsk[6]*x + q_qpsk[7]); + + if(x>qam16_max) + I_qam16 += 1; + else + I_qam16 += (q_qam16[0]*pow(x,7) + q_qam16[1]*pow(x,6) + q_qam16[2]*pow(x,5) + q_qam16[3]*pow(x,4) + q_qam16[4]*pow(x,3) + q_qam16[5]*pow(x,2) + q_qam16[6]*x + q_qam16[7]); + + if(x>qam64_max) + I_qam64 += 1; + else + I_qam64 += (q_qam64[0]*pow(x,7) + q_qam64[1]*pow(x,6) + q_qam64[2]*pow(x,5) + q_qam64[3]*pow(x,4) + q_qam64[4]*pow(x,3) + q_qam64[5]*pow(x,2) + q_qam64[6]*x + q_qam64[7]); + + } + } + } + + // averaging of accumulated MI + I_qpsk_avg = I_qpsk/(12*frame_parms->N_RB_DL); + I_qam16_avg = I_qam16/(12*frame_parms->N_RB_DL); + I_qam64_avg = I_qam64/(12*frame_parms->N_RB_DL); + + // I->SINR_effective Mapping + + sinr_eff_qpsk = (p_qpsk[0]*pow(I_qpsk_avg,7) + p_qpsk[1]*pow(I_qpsk_avg,6) + p_qpsk[2]*pow(I_qpsk_avg,5) + p_qpsk[3]*pow(I_qpsk_avg,4) + p_qpsk[4]*pow(I_qpsk_avg,3) + p_qpsk[5]*pow(I_qpsk_avg, + 2) + p_qpsk[6]*I_qpsk_avg + p_qpsk[7]); + + sinr_eff_qam16 = (p_qam16[0]*pow(I_qam16_avg,7) + p_qam16[1]*pow(I_qam16_avg,6) + p_qam16[2]*pow(I_qam16_avg,5) + p_qam16[3]*pow(I_qam16_avg,4) + p_qam16[4]*pow(I_qam16_avg, + 3) + p_qam16[5]*pow(I_qam16_avg,2) + p_qam16[6]*I_qam16_avg + p_qam16[7]); + + sinr_eff_qam64 = (p_qam64[0]*pow(I_qam64_avg,7) + p_qam64[1]*pow(I_qam64_avg,6) + p_qam64[2]*pow(I_qam64_avg,5) + p_qam64[3]*pow(I_qam64_avg,4) + p_qam64[4]*pow(I_qam64_avg, + 3) + p_qam64[5]*pow(I_qam64_avg,2) + p_qam64[6]*I_qam64_avg + p_qam64[7]); + sinr_eff = cmax3(sinr_eff_qpsk,sinr_eff_qam16,sinr_eff_qam64); + + //printf("SINR_Eff = %e\n",sinr_eff); + + return(sinr_eff); +} +// + + + +#ifdef DEBUG_DLSCH_TOOLS +main() +{ + + int i; + uint8_t rah; + uint32_t rballoc; + + generate_RIV_tables(); + + rah = 0; + rballoc = 0x1fff; + printf("rballoc 0 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); + rah = 1; + + rballoc = 0x1678; + printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); + + rballoc = 0xfffc; + printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); + rballoc = 0xfffd; + printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); + rballoc = 0xffff; + printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); + rballoc = 0xfffe; + printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); +} + +#endif + diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c new file mode 100755 index 0000000000000000000000000000000000000000..f7afb08286ddb8f58e359bec492d0bdbfca0258d --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c @@ -0,0 +1,3245 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/dci.c +* \brief Implements PDCCH physical channel TX/RX procedures (36.211) and DCI encoding/decoding (36.212/36.213). Current LTE compliance V8.6 2009-03. +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "PHY/defs_UE.h" +#include "PHY/phy_extern.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "SCHED_UE/sched_UE.h" +#include "SIMULATION/TOOLS/sim.h" // for taus +#include "PHY/sse_intrin.h" +#include "PHY/LTE_TRANSPORT/transport_extern.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "SCHED/sched_common.h" + +#include "assertions.h" +#include "T.h" +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" + +//#define DEBUG_DCI_ENCODING 1 +//#define DEBUG_DCI_DECODING 1 +//#define DEBUG_PHY + +//#undef ALL_AGGREGATION + + +uint16_t extract_crc(uint8_t *dci,uint8_t dci_len) +{ + + uint16_t crc16; + // uint8_t i; + + /* + uint8_t crc; + crc = ((uint16_t *)dci)[DCI_LENGTH>>4]; + printf("crc1: %x, shift %d (DCI_LENGTH %d)\n",crc,DCI_LENGTH&0xf,DCI_LENGTH); + crc = (crc>>(DCI_LENGTH&0xf)); + // clear crc bits + ((uint16_t *)dci)[DCI_LENGTH>>4] &= (0xffff>>(16-(DCI_LENGTH&0xf))); + printf("crc2: %x, dci0 %x\n",crc,((int16_t *)dci)[DCI_LENGTH>>4]); + crc |= (((uint16_t *)dci)[1+(DCI_LENGTH>>4)])<<(16-(DCI_LENGTH&0xf)); + // clear crc bits + (((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0; + printf("extract_crc: crc %x\n",crc); + */ +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY,"dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)], + dci_len&0x7); +#endif + + if ((dci_len&0x7) > 0) { + ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]<<(dci_len&0x7) | dci[2+(dci_len>>3)]>>(8-(dci_len&0x7)); + ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]<<(dci_len&0x7) | dci[1+(dci_len>>3)]>>(8-(dci_len&0x7)); + } else { + ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]; + ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]; + } + +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY,"dci_crc =>%x\n",crc16); +#endif + + // dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf)); + // dci[(dci_len>>3)+1] = 0; + // dci[(dci_len>>3)+2] = 0; + return((uint16_t)crc16); + +} + + + +void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parms,uint8_t num_pdcch_symbols,uint8_t mi) +{ + + uint32_t i, lprime; + uint16_t kprime,kprime_mod12,mprime,symbol_offset,tti_offset,tti_offset0; + int16_t re_offset,re_offset0; + uint32_t Msymb=(DCI_BITS_MAX/2); + + // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5 + + int Msymb2; + + switch (frame_parms->N_RB_DL) { + case 100: + Msymb2 = Msymb; + break; + + case 75: + Msymb2 = 3*Msymb/4; + break; + + case 50: + Msymb2 = Msymb>>1; + break; + + case 25: + Msymb2 = Msymb>>2; + break; + + case 15: + Msymb2 = Msymb*15/100; + break; + + case 6: + Msymb2 = Msymb*6/100; + break; + + default: + Msymb2 = Msymb>>2; + break; + } + + mprime=0; + + + re_offset = 0; + re_offset0 = 0; // counter for symbol with pilots (extracted outside!) + + for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) { + for (lprime=0; lprime<num_pdcch_symbols; lprime++) { + + symbol_offset = (uint32_t)frame_parms->N_RB_DL*12*lprime; + + tti_offset = symbol_offset + re_offset; + tti_offset0 = symbol_offset + re_offset0; + + // if REG is allocated to PHICH, skip it + if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) { +// printf("dci_demapping : skipping REG %d (RE %d)\n",(lprime==0)?kprime/6 : kprime>>2,kprime); + if ((lprime == 0)&&((kprime%6)==0)) + re_offset0+=4; + } else { // not allocated to PHICH/PCFICH + // printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2); + if (lprime == 0) { + // first symbol, or second symbol+4 TX antennas skip pilots + kprime_mod12 = kprime%12; + + if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) { + // kprime represents REG + + for (i=0; i<4; i++) { + wbar[mprime] = llr[tti_offset0+i]; +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime])); +#endif + mprime++; + re_offset0++; + } + } + } else if ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)) { + // LATER!!!! + } else { // no pilots in this symbol + kprime_mod12 = kprime%12; + + if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) { + // kprime represents REG + for (i=0; i<4; i++) { + wbar[mprime] = llr[tti_offset+i]; +#ifdef DEBUG_DCI_DECODING +// LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime])); +#endif + mprime++; + } + } // is representative + } // no pilots case + } // not allocated to PHICH/PCFICH + + // Stop when all REGs are copied in + if (mprime>=Msymb2) + break; + } //lprime loop + + re_offset++; + + } // kprime loop +} + + +void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t *wbar,uint8_t number_pdcch_symbols,uint8_t mi) +{ + + uint16_t *wptr,*zptr,*wptr2; + uint32_t Msymb=(DCI_BITS_MAX/2); + uint16_t wtemp_rx[Msymb]; + uint16_t Mquad=get_nquad(number_pdcch_symbols,frame_parms,mi); + uint32_t RCC = (Mquad>>5), ND; + uint32_t row,col,Kpi,index; + int32_t i,k; + + + // printf("Mquad %d, RCC %d\n",Mquad,RCC); + + AssertFatal(z!=NULL,"dci.c: pdcch_deinterleaving: FATAL z is Null\n"); + + // undo permutation + for (i=0; i<Mquad; i++) { + wptr = &wtemp_rx[((i+frame_parms->Nid_cell)%Mquad)<<2]; + wptr2 = &wbar[i<<2]; + + wptr[0] = wptr2[0]; + wptr[1] = wptr2[1]; + wptr[2] = wptr2[2]; + wptr[3] = wptr2[3]; + /* + printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad, + ((char*)wptr2)[0], + ((char*)wptr2)[1], + ((char*)wptr2)[2], + ((char*)wptr2)[3], + ((char*)wptr2)[4], + ((char*)wptr2)[5], + ((char*)wptr2)[6], + ((char*)wptr2)[7]); + */ + + } + + if ((Mquad&0x1f) > 0) + RCC++; + + Kpi = (RCC<<5); + ND = Kpi - Mquad; + + k=0; + + for (col=0; col<32; col++) { + index = bitrev_cc_dci[col]; + + for (row=0; row<RCC; row++) { + // printf("row %d, index %d, Nd %d\n",row,index,ND); + if (index>=ND) { + + + + wptr = &wtemp_rx[k<<2]; + zptr = &z[(index-ND)<<2]; + + zptr[0] = wptr[0]; + zptr[1] = wptr[1]; + zptr[2] = wptr[2]; + zptr[3] = wptr[3]; + + /* + printf("deinterleaving ; k %d, index-Nd %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND), + ((int8_t *)wptr)[0], + ((int8_t *)wptr)[1], + ((int8_t *)wptr)[2], + ((int8_t *)wptr)[3], + ((int8_t *)wptr)[4], + ((int8_t *)wptr)[5], + ((int8_t *)wptr)[6], + ((int8_t *)wptr)[7]); + */ + k++; + } + + index+=32; + + } + } + + for (i=0; i<Mquad; i++) { + zptr = &z[i<<2]; + /* + printf("deinterleaving ; quad %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i, + ((int8_t *)zptr)[0], + ((int8_t *)zptr)[1], + ((int8_t *)zptr)[2], + ((int8_t *)zptr)[3], + ((int8_t *)zptr)[4], + ((int8_t *)zptr)[5], + ((int8_t *)zptr)[6], + ((int8_t *)zptr)[7]); + */ + } + +} + + + +int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + char *pdcch_llr, + uint8_t symbol) +{ + + int16_t *rxF= (int16_t*) &rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + int32_t i; + char *pdcch_llr8; + + pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12]; + + if (!pdcch_llr8) { + printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); + return(-1); + } + + // printf("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr); + + for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) { + + if (*rxF>31) + *pdcch_llr8=31; + else if (*rxF<-32) + *pdcch_llr8=-32; + else + *pdcch_llr8 = (char)(*rxF); + + // printf("rxF->llr : %d %d => %d\n",i,*rxF,*pdcch_llr8); + rxF++; + pdcch_llr8++; + } + + return(0); + +} + +//__m128i avg128P; + +//compute average channel_level on each (TX,RX) antenna pair +void pdcch_channel_level(int32_t **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + int32_t *avg, + uint8_t nb_rb) +{ + + int16_t rb; + uint8_t aatx,aarx; +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch128; + __m128i avg128P; +#elif defined(__arm__) + int16x8_t *dl_ch128; + int32x4_t *avg128P; +#endif + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + //clear average level +#if defined(__x86_64__) || defined(__i386__) + avg128P = _mm_setzero_si128(); + dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][0]; +#elif defined(__arm__) + +#endif + for (rb=0; rb<nb_rb; rb++) { + +#if defined(__x86_64__) || defined(__i386__) + avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); + avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); + avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); +#elif defined(__arm__) + +#endif + dl_ch128+=3; + /* + if (rb==0) { + print_shorts("dl_ch128",&dl_ch128[0]); + print_shorts("dl_ch128",&dl_ch128[1]); + print_shorts("dl_ch128",&dl_ch128[2]); + } + */ + } + + DevAssert( nb_rb ); + avg[(aatx<<1)+aarx] = (((int32_t*)&avg128P)[0] + + ((int32_t*)&avg128P)[1] + + ((int32_t*)&avg128P)[2] + + ((int32_t*)&avg128P)[3])/(nb_rb*12); + + // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif + +} + + + +void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int32_t **rxdataF_comp_i, + int32_t **rho, + int32_t **rho_i, + uint8_t symbol) +{ + + uint8_t aatx; + +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; +#elif defined(__arm__) + int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; +#endif + int32_t i; + + if (frame_parms->nb_antennas_rx>1) { + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { + //if (frame_parms->mode1_flag && (aatx>0)) break; + +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; +#elif defined(__arm__) + rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; +#endif + // MRC on each re of rb on MF output + for (i=0; i<frame_parms->N_RB_DL*3; i++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); +#elif defined(__arm__) + rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); +#endif + } + } + +#if defined(__x86_64__) || defined(__i386__) + rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12]; + rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; +#elif defined(__arm__) + rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12]; + rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12]; +#endif + for (i=0; i<frame_parms->N_RB_DL*3; i++) { +#if defined(__x86_64__) || defined(__i386__) + rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); +#elif defined(__arm__) + rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]); +#endif + } + +#if defined(__x86_64__) || defined(__i386__) + rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; + rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12]; +#elif defined(__arm__) + rho128_i0 = (int16x8_t*) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; + rho128_i1 = (int16x8_t*) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i0 = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i1 = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12]; + +#endif + // MRC on each re of rb on MF and rho + for (i=0; i<frame_parms->N_RB_DL*3; i++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1)); + rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); +#elif defined(__arm__) + rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]); + rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]); + +#endif + } + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + + +void pdcch_extract_rbs_single(int32_t **rxdataF, + int32_t **dl_ch_estimates, + int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + uint8_t symbol, + uint32_t high_speed_flag, + LTE_DL_FRAME_PARMS *frame_parms) +{ + + + uint16_t rb,nb_rb=0; + uint8_t i,j,aarx; + int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; + + + int nushiftmod3 = frame_parms->nushift%3; + uint8_t symbol_mod; + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod); +#endif + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + + if (high_speed_flag == 1) + dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; + else + dl_ch0 = &dl_ch_estimates[aarx][5]; + + dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; + + rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; + + rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; + + if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs + for (rb=0; rb<frame_parms->N_RB_DL; rb++) { + + // For second half of RBs skip DC carrier + if (rb==(frame_parms->N_RB_DL>>1)) { + rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; + + //dl_ch0++; + } + + if (symbol_mod>0) { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); + + for (i=0; i<12; i++) { + + rxF_ext[i]=rxF[i]; + + } + + nb_rb++; + dl_ch0_ext+=12; + rxF_ext+=12; + + dl_ch0+=12; + rxF+=12; + } else { + j=0; + + for (i=0; i<12; i++) { + if ((i!=nushiftmod3) && + (i!=(nushiftmod3+3)) && + (i!=(nushiftmod3+6)) && + (i!=(nushiftmod3+9))) { + rxF_ext[j]=rxF[i]; + //printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + //printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); + } + } + + nb_rb++; + dl_ch0_ext+=8; + rxF_ext+=8; + + dl_ch0+=12; + rxF+=12; + } + } + } else { // Odd number of RBs + for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) { + + if (symbol_mod>0) { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); + + for (i=0; i<12; i++) + rxF_ext[i]=rxF[i]; + + nb_rb++; + dl_ch0_ext+=12; + rxF_ext+=12; + + dl_ch0+=12; + rxF+=12; + } else { + j=0; + + for (i=0; i<12; i++) { + if ((i!=nushiftmod3) && + (i!=(nushiftmod3+3)) && + (i!=(nushiftmod3+6)) && + (i!=(nushiftmod3+9))) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); + } + } + + nb_rb++; + dl_ch0_ext+=8; + rxF_ext+=8; + + dl_ch0+=12; + rxF+=12; + } + } + + // Do middle RB (around DC) + // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); + + if (symbol_mod==0) { + j=0; + + for (i=0; i<6; i++) { + if ((i!=nushiftmod3) && + (i!=(nushiftmod3+3))) { + dl_ch0_ext[j]=dl_ch0[i]; + rxF_ext[j++]=rxF[i]; + // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + } + } + + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + + for (; i<12; i++) { + if ((i!=(nushiftmod3+6)) && + (i!=(nushiftmod3+9))) { + dl_ch0_ext[j]=dl_ch0[i]; + rxF_ext[j++]=rxF[(1+i-6)]; + // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + } + } + + + nb_rb++; + dl_ch0_ext+=8; + rxF_ext+=8; + dl_ch0+=12; + rxF+=7; + rb++; + } else { + for (i=0; i<6; i++) { + dl_ch0_ext[i]=dl_ch0[i]; + rxF_ext[i]=rxF[i]; + } + + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + + for (; i<12; i++) { + dl_ch0_ext[i]=dl_ch0[i]; + rxF_ext[i]=rxF[(1+i-6)]; + } + + + nb_rb++; + dl_ch0_ext+=12; + rxF_ext+=12; + dl_ch0+=12; + rxF+=7; + rb++; + } + + for (; rb<frame_parms->N_RB_DL; rb++) { + if (symbol_mod > 0) { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); + + for (i=0; i<12; i++) + rxF_ext[i]=rxF[i]; + + nb_rb++; + dl_ch0_ext+=12; + rxF_ext+=12; + + dl_ch0+=12; + rxF+=12; + } else { + j=0; + + for (i=0; i<12; i++) { + if ((i!=(nushiftmod3)) && + (i!=(nushiftmod3+3)) && + (i!=(nushiftmod3+6)) && + (i!=(nushiftmod3+9))) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + } + } + + nb_rb++; + dl_ch0_ext+=8; + rxF_ext+=8; + + dl_ch0+=12; + rxF+=12; + } + } + } + } +} + +void pdcch_extract_rbs_dual(int32_t **rxdataF, + int32_t **dl_ch_estimates, + int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + uint8_t symbol, + uint32_t high_speed_flag, + LTE_DL_FRAME_PARMS *frame_parms) +{ + + + uint16_t rb,nb_rb=0; + uint8_t i,aarx,j; + int32_t *dl_ch0,*dl_ch0_ext,*dl_ch1,*dl_ch1_ext,*rxF,*rxF_ext; + uint8_t symbol_mod; + int nushiftmod3 = frame_parms->nushift%3; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY, "extract_rbs_dual: symbol_mod %d\n",symbol_mod); +#endif + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + + if (high_speed_flag==1) { + dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; + dl_ch1 = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; + } else { + dl_ch0 = &dl_ch_estimates[aarx][5]; + dl_ch1 = &dl_ch_estimates[2+aarx][5]; + } + + dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; + dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)]; + + // printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12)); + rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; + + rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; + + if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs + for (rb=0; rb<frame_parms->N_RB_DL; rb++) { + + // For second half of RBs skip DC carrier + if (rb==(frame_parms->N_RB_DL>>1)) { + rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; + // dl_ch0++; + //dl_ch1++; + } + + if (symbol_mod>0) { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); + + /* + printf("rb %d\n",rb); + for (i=0;i<12;i++) + printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]); + printf("\n"); + */ + for (i=0; i<12; i++) { + rxF_ext[i]=rxF[i]; + // printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2, + // ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]); + } + + nb_rb++; + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + } else { + j=0; + + for (i=0; i<12; i++) { + if ((i!=nushiftmod3) && + (i!=nushiftmod3+3) && + (i!=nushiftmod3+6) && + (i!=nushiftmod3+9)) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j] =dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + } + } + + nb_rb++; + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + } + + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; + } + + else { // Odd number of RBs + for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) { + + // printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]); + + if (symbol_mod>0) { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); + + for (i=0; i<12; i++) + rxF_ext[i]=rxF[i]; + + nb_rb++; + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; + + } else { + j=0; + + for (i=0; i<12; i++) { + if ((i!=nushiftmod3) && + (i!=nushiftmod3+3) && + (i!=nushiftmod3+6) && + (i!=nushiftmod3+9)) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); + } + } + + nb_rb++; + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + + + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; + } + } + + // Do middle RB (around DC) + + if (symbol_mod > 0) { + for (i=0; i<6; i++) { + dl_ch0_ext[i]=dl_ch0[i]; + dl_ch1_ext[i]=dl_ch1[i]; + rxF_ext[i]=rxF[i]; + } + + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + + for (; i<12; i++) { + dl_ch0_ext[i]=dl_ch0[i]; + dl_ch1_ext[i]=dl_ch1[i]; + rxF_ext[i]=rxF[(1+i)]; + } + + nb_rb++; + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + + dl_ch0+=12; + dl_ch1+=12; + rxF+=7; + rb++; + } else { + j=0; + + for (i=0; i<6; i++) { + if ((i!=nushiftmod3) && + (i!=nushiftmod3+3)) { + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j]=dl_ch1[i]; + rxF_ext[j++]=rxF[i]; + // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + } + } + + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + + for (; i<12; i++) { + if ((i!=nushiftmod3+6) && + (i!=nushiftmod3+9)) { + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j]=dl_ch1[i]; + rxF_ext[j++]=rxF[(1+i-6)]; + // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + } + } + + + nb_rb++; + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + dl_ch0+=12; + dl_ch1+=12; + rxF+=7; + rb++; + } + + for (; rb<frame_parms->N_RB_DL; rb++) { + + if (symbol_mod>0) { + // printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]); + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); + + for (i=0; i<12; i++) + rxF_ext[i]=rxF[i]; + + nb_rb++; + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; + } else { + j=0; + + for (i=0; i<12; i++) { + if ((i!=nushiftmod3) && + (i!=nushiftmod3+3) && + (i!=nushiftmod3+6) && + (i!=nushiftmod3+9)) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + } + } + + nb_rb++; + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; + } + } + } + } +} + + +void pdcch_channel_compensation(int32_t **rxdataF_ext, + int32_t **dl_ch_estimates_ext, + int32_t **rxdataF_comp, + int32_t **rho, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t symbol, + uint8_t output_shift) +{ + + uint16_t rb; + +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; + __m128i *dl_ch128_2, *rho128; + __m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3; +#elif defined(__arm__) + +#endif + uint8_t aatx,aarx,pilots=0; + + + + +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol); +#endif + + if (symbol==0) + pilots=1; + + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { + //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + +#if defined(__x86_64__) || defined(__i386__) + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; + +#elif defined(__arm__) + +#endif + + for (rb=0; rb<frame_parms->N_RB_DL; rb++) { + +#if defined(__x86_64__) || defined(__i386__) + // multiply by conjugated channel + mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpPD0); + + // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpPD1); + mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[0]); + // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); + // print_ints("re(shift)",&mmtmpPD0); + mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); + // print_ints("im(shift)",&mmtmpPD1); + mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); + mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); + // print_ints("c0",&mmtmpPD2); + // print_ints("c1",&mmtmpPD3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); + + // multiply by conjugated channel + mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); + mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[1]); + // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); + mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); + mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); + mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); + + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); + + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); + // multiply by conjugated channel + if (pilots == 0) { + mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); + // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); + mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[2]); + // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); + mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); + mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); + mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); + + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); + } + + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch128+2); + // print_shorts("pack:",rxdataF_comp128+2); + + if (pilots==0) { + dl_ch128+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } else { + dl_ch128+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + } +#elif defined(__arm__) + +#endif + } + } + } + + + if (rho) { + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + +#if defined(__x86_64__) || defined(__i386__) + rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + +#elif defined(__arm__) + +#endif + for (rb=0; rb<frame_parms->N_RB_DL; rb++) { +#if defined(__x86_64__) || defined(__i386__) + + // multiply by conjugated channel + mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpPD1); + mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[0]); + // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); + mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); + // print_ints("c0",&mmtmpPD2); + // print_ints("c1",&mmtmpPD3); + rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); + + //print_shorts("rx:",dl_ch128_2); + //print_shorts("ch:",dl_ch128); + //print_shorts("pack:",rho128); + + // multiply by conjugated channel + mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); + mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); + mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); + mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); + mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); + + + rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3); + //print_shorts("rx:",dl_ch128_2+1); + //print_shorts("ch:",dl_ch128+1); + //print_shorts("pack:",rho128+1); + // multiply by conjugated channel + mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]); + // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); + mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[2]); + // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); + mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); + mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); + mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); + + rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); + //print_shorts("rx:",dl_ch128_2+2); + //print_shorts("ch:",dl_ch128+2); + //print_shorts("pack:",rho128+2); + + dl_ch128+=3; + dl_ch128_2+=3; + rho128+=3; + +#elif defined(__arm_) + + +#endif + } + } + + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + +void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t symbol) +{ + + uint8_t aatx; + +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1; +#elif defined(__arm__) + int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1; +#endif + int32_t i; + + if (frame_parms->nb_antennas_rx>1) { + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; +#elif defined(__arm__) + rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; +#endif + // MRC on each re of rb + for (i=0; i<frame_parms->N_RB_DL*3; i++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); +#elif defined(__arm__) + rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); +#endif + } + } + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif + +} + +void pdcch_siso(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t l) +{ + + + uint8_t rb,re,jj,ii; + + jj=0; + ii=0; + + for (rb=0; rb<frame_parms->N_RB_DL; rb++) { + + for (re=0; re<12; re++) { + + rxdataF_comp[0][jj++] = rxdataF_comp[0][ii]; + ii++; + } + } +} + + +void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t symbol) +{ + + + int16_t *rxF0,*rxF1; + uint8_t rb,re; + int32_t jj=(symbol*frame_parms->N_RB_DL*12); + + rxF0 = (int16_t*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y + rxF1 = (int16_t*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y + + for (rb=0; rb<frame_parms->N_RB_DL; rb++) { + + for (re=0; re<12; re+=2) { + + // Alamouti RX combining + + rxF0[0] = rxF0[0] + rxF1[2]; + rxF0[1] = rxF0[1] - rxF1[3]; + + rxF0[2] = rxF0[2] - rxF1[0]; + rxF0[3] = rxF0[3] + rxF1[1]; + + rxF0+=4; + rxF1+=4; + } + } + + +} + +int32_t avgP[4]; + +int32_t rx_pdcch(PHY_VARS_UE *ue, + uint32_t frame, + uint8_t subframe, + uint8_t eNB_id, + MIMO_mode_t mimo_mode, + uint32_t high_speed_flag) +{ + + LTE_UE_COMMON *common_vars = &ue->common_vars; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]]; + + uint8_t log2_maxh,aatx,aarx; + int32_t avgs; + uint8_t n_pdcch_symbols; + uint8_t mi = get_mi(frame_parms,subframe); + + // printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d, handling symbol 0 \n",subframe,eNB_id,pdcch_vars); + // procress ofdm symbol 0 + if (frame_parms->nb_antenna_ports_eNB>1) { + pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, + common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], + pdcch_vars[eNB_id]->rxdataF_ext, + pdcch_vars[eNB_id]->dl_ch_estimates_ext, + 0, + high_speed_flag, + frame_parms); + } else { + pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, + common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], + pdcch_vars[eNB_id]->rxdataF_ext, + pdcch_vars[eNB_id]->dl_ch_estimates_ext, + 0, + high_speed_flag, + frame_parms); + } + + + // compute channel level based on ofdm symbol 0 + pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avgP, + frame_parms->N_RB_DL); + + avgs = 0; + + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) + avgs = cmax(avgs,avgP[(aarx<<1)+aatx]); + + log2_maxh = (log2_approx(avgs)/2) + 5; //+frame_parms->nb_antennas_rx; +#ifdef UE_DEBUG_TRACE + LOG_I(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs); +#endif + + T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id), T_INT(frame%1024), T_INT(subframe), + T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); + + // compute LLRs for ofdm symbol 0 only + pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext, + pdcch_vars[eNB_id]->dl_ch_estimates_ext, + pdcch_vars[eNB_id]->rxdataF_comp, + (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL, + frame_parms, + 0, + log2_maxh); // log2_maxh+I0_shift + + +#ifdef DEBUG_PHY + + if (subframe==5) { + printf("Writing output s0\n"); + write_output("rxF_comp_d0.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][0*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + } +#endif + + if (frame_parms->nb_antennas_rx > 1) { + pdcch_detection_mrc(frame_parms, + pdcch_vars[eNB_id]->rxdataF_comp, + 0); + } + + if (mimo_mode == SISO) + pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0); + else + pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0); + + pdcch_llr(frame_parms, + pdcch_vars[eNB_id]->rxdataF_comp, + (char *)pdcch_vars[eNB_id]->llr, + 0); + + + // decode pcfich here and find out pdcch ofdm symbol number + n_pdcch_symbols = rx_pcfich(frame_parms, + subframe, + pdcch_vars[eNB_id], + mimo_mode); + + // printf("In rx_pdcch, subframe %d, num_pdcch_symbols %d \n",subframe,n_pdcch_symbols); + + if (n_pdcch_symbols>3) + n_pdcch_symbols=1; + +#if T_TRACER + T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), + T_INT(n_pdcch_symbols), + T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); +#endif + + +#ifdef DEBUG_DCI_DECODING + + if (subframe==5) LOG_I(PHY,"demapping: subframe %d, num_pdcch_symbols %d\n",subframe,n_pdcch_symbols); +#endif + + // process pdcch ofdm symbol 1 and 2 if necessary + for (int s=1; s<n_pdcch_symbols; s++){ + // printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d, handling symbol %d \n",subframe,eNB_id,pdcch_vars,s); + if (frame_parms->nb_antenna_ports_eNB>1) { + pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, + common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], + pdcch_vars[eNB_id]->rxdataF_ext, + pdcch_vars[eNB_id]->dl_ch_estimates_ext, + s, + high_speed_flag, + frame_parms); + } else { + pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, + common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], + pdcch_vars[eNB_id]->rxdataF_ext, + pdcch_vars[eNB_id]->dl_ch_estimates_ext, + s, + high_speed_flag, + frame_parms); + } + + + pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext, + pdcch_vars[eNB_id]->dl_ch_estimates_ext, + pdcch_vars[eNB_id]->rxdataF_comp, + (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL, + frame_parms, + s, + log2_maxh); // log2_maxh+I0_shift + + +#ifdef DEBUG_PHY + + if (subframe==5) { + write_output("rxF_comp_ds.m","rxF_c_ds",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + } +#endif + + + + if (frame_parms->nb_antennas_rx > 1) { + pdcch_detection_mrc(frame_parms, + pdcch_vars[eNB_id]->rxdataF_comp, + s); + + } + + if (mimo_mode == SISO) + pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s); + else + pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s); + + + // printf("subframe %d computing llrs for symbol %d : %p\n",subframe,s,pdcch_vars[eNB_id]->llr); + pdcch_llr(frame_parms, + pdcch_vars[eNB_id]->rxdataF_comp, + (char *)pdcch_vars[eNB_id]->llr, + s); + /*#ifdef DEBUG_PHY + write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); + #endif*/ + } + + pdcch_demapping(pdcch_vars[eNB_id]->llr, + pdcch_vars[eNB_id]->wbar, + frame_parms, + n_pdcch_symbols, + get_mi(frame_parms,subframe)); + + pdcch_deinterleaving(frame_parms, + (uint16_t*)pdcch_vars[eNB_id]->e_rx, + pdcch_vars[eNB_id]->wbar, + n_pdcch_symbols, + mi); + + pdcch_unscrambling(frame_parms, + subframe, + pdcch_vars[eNB_id]->e_rx, + get_nCCE(n_pdcch_symbols,frame_parms,mi)*72); + + pdcch_vars[eNB_id]->num_pdcch_symbols = n_pdcch_symbols; + + // if ((frame&1) ==0 && subframe==5) exit(-1); + return(0); +} + + +void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + int8_t* llr, + uint32_t length) +{ + + int i; + uint8_t reset; + uint32_t x1, x2, s=0; + + reset = 1; + // x1 is set in first call to lte_gold_generic + + x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 + + for (i=0; i<length; i++) { + if ((i&0x1f)==0) { + s = lte_gold_generic(&x1, &x2, reset); + // printf("lte_gold[%d]=%x\n",i,s); + reset = 0; + } + + + // if (subframe == 5) printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1)); + if (((s>>(i%32))&1)==0) + llr[i] = -llr[i]; + // if (subframe == 5) printf("%d\n",llr[i]); + + } +} + +/* +uint8_t get_num_pdcch_symbols(uint8_t num_dci, + DCI_ALLOC_t *dci_alloc, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe) +{ + + uint16_t numCCE = 0; + uint8_t i; + uint8_t nCCEmin = 0; + uint16_t CCE_max_used_index = 0; + uint16_t firstCCE_max = dci_alloc[0].firstCCE; + uint8_t L = dci_alloc[0].L; + + // check pdcch duration imposed by PHICH duration (Section 6.9 of 36-211) + if (frame_parms->Ncp==1) { // extended prefix + if ((frame_parms->frame_type == TDD) && + ((frame_parms->tdd_config<3)||(frame_parms->tdd_config==6)) && + ((subframe==1) || (subframe==6))) // subframes 1 and 6 (S-subframes) for 5ms switching periodicity are 2 symbols + nCCEmin = 2; + else { // 10ms switching periodicity is always 3 symbols, any DL-only subframe is 3 symbols + nCCEmin = 3; + } + } + + // compute numCCE + for (i=0; i<num_dci; i++) { + // printf("dci %d => %d\n",i,dci_alloc[i].L); + numCCE += (1<<(dci_alloc[i].L)); + + if(firstCCE_max < dci_alloc[i].firstCCE) { + firstCCE_max = dci_alloc[i].firstCCE; + L = dci_alloc[i].L; + } + } + CCE_max_used_index = firstCCE_max + (1<<L) - 1; + + //if ((9*numCCE) <= (frame_parms->N_RB_DL*2)) + if (CCE_max_used_index < get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) + return(cmax(1,nCCEmin)); + //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5))) + else if (CCE_max_used_index < get_nCCE(2, frame_parms, get_mi(frame_parms, subframe))) + return(cmax(2,nCCEmin)); + //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8))) + else if (CCE_max_used_index < get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))) + return(cmax(3,nCCEmin)); + else if (frame_parms->N_RB_DL<=10) { + if (frame_parms->Ncp == 0) { // normal CP + printf("numCCE %d, N_RB_DL = %d : should be returning 4 PDCCH symbols (%d,%d,%d)\n",numCCE,frame_parms->N_RB_DL, + get_nCCE(1, frame_parms, get_mi(frame_parms, subframe)), + get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)), + get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))); + + if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 10 : 11))) + return(4); + } else { // extended CP + if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 9 : 10))) + return(4); + } + } + + + + // LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci); + //for (i=0;i<num_dci;i++) { + // printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L); + //} + //exit(-1); +exit(1); + return(0); +} +*/ + + + +void dci_decoding(uint8_t DCI_LENGTH, + uint8_t aggregation_level, + int8_t *e, + uint8_t *decoded_output) +{ + + uint8_t dummy_w_rx[3*(MAX_DCI_SIZE_BITS+16+64)]; + int8_t w_rx[3*(MAX_DCI_SIZE_BITS+16+32)],d_rx[96+(3*(MAX_DCI_SIZE_BITS+16))]; + + uint16_t RCC; + + uint16_t D=(DCI_LENGTH+16+64); + uint16_t coded_bits; +#ifdef DEBUG_DCI_DECODING + int32_t i; +#endif + + AssertFatal(aggregation_level<4, + "dci_decoding FATAL, illegal aggregation_level %d\n",aggregation_level); + + coded_bits = 72 * (1<<aggregation_level); + +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY," Doing DCI decoding for %d bits, DCI_LENGTH %d,coded_bits %d, e %p\n",3*(DCI_LENGTH+16),DCI_LENGTH,coded_bits,e); +#endif + + // now do decoding + memset((void*)dummy_w_rx,0,3*D); + RCC = generate_dummy_w_cc(DCI_LENGTH+16, + dummy_w_rx); + + + +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY," Doing DCI Rate Matching RCC %d, w %p\n",RCC,w_rx); +#endif + + lte_rate_matching_cc_rx(RCC,coded_bits,w_rx,dummy_w_rx,e); + + sub_block_deinterleaving_cc((uint32_t)(DCI_LENGTH+16), + &d_rx[96], + &w_rx[0]); + +#ifdef DEBUG_DCI_DECODING + if (DCI_LENGTH==27 && ((1<<aggregation_level) == 4)) + for (int i=0; i<16+DCI_LENGTH; i++) + LOG_I(PHY," DCI %d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i))); + +#endif + memset(decoded_output,0,2+((16+DCI_LENGTH)>>3)); + +#ifdef DEBUG_DCI_DECODING + printf("Before Viterbi\n"); + + for (i=0; i<16+DCI_LENGTH; i++) + printf("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i))); + +#endif + //debug_printf("Doing DCI Viterbi \n"); + phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH); + //debug_printf("Done DCI Viterbi \n"); +} + + +static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8]; + + + + +int get_nCCE_offset_l1(int *CCE_table, + const unsigned char L, + const int nCCE, + const int common_dci, + const unsigned short rnti, + const unsigned char subframe) +{ + + int search_space_free,m,nb_candidates = 0,l,i; + unsigned int Yk; + /* + printf("CCE Allocation: "); + for (i=0;i<nCCE;i++) + printf("%d.",CCE_table[i]); + printf("\n"); + */ + if (common_dci == 1) { + // check CCE(0 ... L-1) + nb_candidates = (L==4) ? 4 : 2; + nb_candidates = min(nb_candidates,nCCE/L); + + // printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L); + + for (m = nb_candidates-1 ; m >=0 ; m--) { + + search_space_free = 1; + for (l=0; l<L; l++) { + + // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); + if (CCE_table[(m*L) + l] == 1) { + search_space_free = 0; + break; + } + } + + if (search_space_free == 1) { + + // printf("returning %d\n",m*L); + + for (l=0; l<L; l++) + CCE_table[(m*L)+l]=1; + return(m*L); + } + } + + return(-1); + + } else { // Find first available in ue specific search space + // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) + // compute Yk + Yk = (unsigned int)rnti; + + for (i=0; i<=subframe; i++) + Yk = (Yk*39827)%65537; + + Yk = Yk % (nCCE/L); + + + switch (L) { + case 1: + case 2: + nb_candidates = 6; + break; + + case 4: + case 8: + nb_candidates = 2; + break; + + default: + DevParam(L, nCCE, rnti); + break; + } + + + LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates); + + for (m = 0 ; m < nb_candidates ; m++) { + search_space_free = 1; + + for (l=0; l<L; l++) { + int cce = (((Yk+m)%(nCCE/L))*L) + l; + if (cce >= nCCE || CCE_table[cce] == 1) { + search_space_free = 0; + break; + } + } + + if (search_space_free == 1) { + for (l=0; l<L; l++) + CCE_table[(((Yk+m)%(nCCE/L))*L)+l]=1; + + return(((Yk+m)%(nCCE/L))*L); + } + } + + return(-1); + } +} + + +void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, + int do_common, + dci_detect_mode_t mode, + uint8_t subframe, + DCI_ALLOC_t *dci_alloc, + int16_t eNB_id, + uint8_t current_thread_id, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t mi, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + uint8_t L, + uint8_t format_si, + uint8_t format_p, + uint8_t format_ra, + uint8_t format_c, + uint8_t sizeof_bits, + uint8_t sizeof_bytes, + uint8_t *dci_cnt, + uint8_t *format0_found, + uint8_t *format_c_found, + uint32_t *CCEmap0, + uint32_t *CCEmap1, + uint32_t *CCEmap2) +{ + + uint16_t crc,CCEind,nCCE; + uint32_t *CCEmap=NULL,CCEmap_mask=0; + int L2=(1<<L); + unsigned int Yk,nb_candidates = 0,i,m; + unsigned int CCEmap_cand; + + nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi); + + if (nCCE > get_nCCE(3,frame_parms,1)) { + LOG_D(PHY,"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", nCCE, get_nCCE(3,frame_parms,1)); + return; + } + + if (nCCE<L2) { + LOG_D(PHY,"skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2); + return; + } + + if (mode == NO_DCI) { + LOG_D(PHY, "skip DCI decoding: expect no DCIs at subframe %d\n", subframe); + return; + } + + if (do_common == 1) { + nb_candidates = (L2==4) ? 4 : 2; + Yk=0; + } else { + // Find first available in ue specific search space + // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) + // compute Yk + Yk = (unsigned int)pdcch_vars[eNB_id]->crnti; + + for (i=0; i<=subframe; i++) + Yk = (Yk*39827)%65537; + + Yk = Yk % (nCCE/L2); + + switch (L2) { + case 1: + case 2: + nb_candidates = 6; + break; + + case 4: + case 8: + nb_candidates = 2; + break; + + default: + DevParam(L2, do_common, eNB_id); + break; + } + } + + /* for (CCEind=0; + CCEind<nCCE2; + CCEind+=(1<<L)) {*/ + + if (nb_candidates*L2 > nCCE) + nb_candidates = nCCE/L2; + + for (m=0; m<nb_candidates; m++) { + + CCEind = (((Yk+m)%(nCCE/L2))*L2); + + if (CCEind<32) + CCEmap = CCEmap0; + else if (CCEind<64) + CCEmap = CCEmap1; + else if (CCEind<96) + CCEmap = CCEmap2; + else { + AssertFatal(1==0, + "Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind,Yk,m,nCCE,L2); + } + + switch (L2) { + case 1: + CCEmap_mask = (1<<(CCEind&0x1f)); + break; + + case 2: + CCEmap_mask = (3<<(CCEind&0x1f)); + break; + + case 4: + CCEmap_mask = (0xf<<(CCEind&0x1f)); + break; + + case 8: + CCEmap_mask = (0xff<<(CCEind&0x1f)); + break; + + default: + AssertFatal(1==0, + "Illegal L2 value %d\n", L2 ); + } + + CCEmap_cand = (*CCEmap)&CCEmap_mask; + + // CCE is not allocated yet + + if (CCEmap_cand == 0) { + + if (do_common == 1) + LOG_D(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", + pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); + else + LOG_D(PHY,"[DCI search nPdcch %d - ue spec %x] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", + pdcch_vars[eNB_id]->num_pdcch_symbols,pdcch_vars[eNB_id]->crnti,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); + + dci_decoding(sizeof_bits, + L, + &pdcch_vars[eNB_id]->e_rx[CCEind*72], + &dci_decoded_output[current_thread_id][0]); + /* + for (i=0;i<3+(sizeof_bits>>3);i++) + printf("dci_decoded_output[%d][%d] => %x\n",current_thread_id,i,dci_decoded_output[current_thread_id][i]); + */ + + crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits); +#ifdef DEBUG_DCI_DECODING + printf("crc =>%x\n",crc); +#endif + + if (((L>1) && ((crc == si_rnti)|| + (crc == p_rnti)|| + (crc == ra_rnti)))|| + (crc == pdcch_vars[eNB_id]->crnti)) { + dci_alloc[*dci_cnt].dci_length = sizeof_bits; + dci_alloc[*dci_cnt].rnti = crc; + dci_alloc[*dci_cnt].L = L; + dci_alloc[*dci_cnt].firstCCE = CCEind; + + //printf("DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes); + if (sizeof_bytes<=4) { + dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0]; + dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1]; + dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2]; + dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3]; +#ifdef DEBUG_DCI_DECODING + printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0], + dci_decoded_output[current_thread_id][1], + dci_decoded_output[current_thread_id][2], + dci_decoded_output[current_thread_id][3]); +#endif + } else { + dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0]; + dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1]; + dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2]; + dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3]; + dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4]; + dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5]; + dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6]; + dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7]; +#ifdef DEBUG_DCI_DECODING + printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", + dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3], + dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]); +#endif + } + + if (crc==si_rnti) { + dci_alloc[*dci_cnt].format = format_si; + *dci_cnt = *dci_cnt+1; + } else if (crc==p_rnti) { + dci_alloc[*dci_cnt].format = format_p; + *dci_cnt = *dci_cnt+1; + } else if (crc==ra_rnti) { + dci_alloc[*dci_cnt].format = format_ra; + // store first nCCE of group for PUCCH transmission of ACK/NAK + pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; + *dci_cnt = *dci_cnt+1; + } else if (crc==pdcch_vars[eNB_id]->crnti) { + + if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A + if (*format0_found == 0) { + dci_alloc[*dci_cnt].format = format0; + *format0_found = 1; + *dci_cnt = *dci_cnt+1; + pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; + } + } else if (format_c == format0) { // this is a format 1A DCI + dci_alloc[*dci_cnt].format = format1A; + *dci_cnt = *dci_cnt+1; + pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; + } else { + // store first nCCE of group for PUCCH transmission of ACK/NAK + if (*format_c_found == 0) { + dci_alloc[*dci_cnt].format = format_c; + *dci_cnt = *dci_cnt+1; + *format_c_found = 1; + pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; + } + } + } + + //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2); + // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); + + + + switch (1<<L) { + case 1: + *CCEmap|=(1<<(CCEind&0x1f)); + break; + + case 2: + *CCEmap|=(1<<(CCEind&0x1f)); + break; + + case 4: + *CCEmap|=(1<<(CCEind&0x1f)); + break; + + case 8: + *CCEmap|=(1<<(CCEind&0x1f)); + break; + } + +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x) candidate %d / %d \n", + *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap,m,nb_candidates ); + dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]); + +#endif + return; + } // rnti match + } // CCEmap_cand == 0 +/* + if ( agregationLevel != 0xFF && + (format_c == format0 && m==0 && si_rnti != SI_RNTI)) + { + //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0. + return; + } +*/ + } // candidate loop +} + +uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue, + DCI_ALLOC_t *dci_alloc, + uint8_t DCIFormat, + uint8_t agregationLevel, + int16_t eNB_id, + uint8_t subframe) +{ + + uint8_t dci_cnt=0,old_dci_cnt=0; + uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0; + LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]]; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + uint8_t mi = get_mi(&ue->frame_parms,subframe); + uint16_t ra_rnti=99; + uint8_t format0_found=0,format_c_found=0; + uint8_t tmode = ue->transmission_mode[eNB_id]; + uint8_t frame_type = frame_parms->frame_type; + uint8_t format0_size_bits=0,format0_size_bytes=0; + uint8_t format1_size_bits=0,format1_size_bytes=0; + dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe); + + switch (frame_parms->N_RB_DL) { + case 6: + if (frame_type == TDD) { + format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t); + + } else { + format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); + format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t); + } + + break; + + case 25: + default: + if (frame_type == TDD) { + format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_5MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_5MHz_TDD_t); + } else { + format0_size_bits = sizeof_DCI0_5MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_5MHz_FDD_t); + format1_size_bits = sizeof_DCI1_5MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_5MHz_FDD_t); + } + + break; + + case 50: + if (frame_type == TDD) { + format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_10MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_10MHz_TDD_t); + + } else { + format0_size_bits = sizeof_DCI0_10MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_10MHz_FDD_t); + format1_size_bits = sizeof_DCI1_10MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_10MHz_FDD_t); + } + + break; + + case 100: + if (frame_type == TDD) { + format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_20MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_20MHz_TDD_t); + } else { + format0_size_bits = sizeof_DCI0_20MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_20MHz_FDD_t); + format1_size_bits = sizeof_DCI1_20MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_20MHz_FDD_t); + } + + break; + } + + if (ue->prach_resources[eNB_id]) + ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; + + // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8 + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + agregationLevel, + format1A, + format1A, + format1A, + format0, + format0_size_bits, + format0_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (DCIFormat == format1) + { + if ((tmode < 3) || (tmode == 7)) { + //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); + + // Now check UE_SPEC format 1 search spaces at aggregation 1 + + //printf("[DCI search] Format 1/1A aggregation 1\n"); + + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 0, + format1A, + format1A, + format1A, + format1, + format1_size_bits, + format1_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff) || + (format_c_found==1)) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); + + } + else if (DCIFormat == format1A) + { + AssertFatal(0,"Other Transmission mode not yet coded\n"); + } + } + else + { + LOG_W(PHY,"DCI format %d wrong or not yet implemented \n",DCIFormat); + } + + return(dci_cnt); + +} + +uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, + DCI_ALLOC_t *dci_alloc, + int do_common, + int16_t eNB_id, + uint8_t subframe) +{ + + uint8_t dci_cnt=0,old_dci_cnt=0; + uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0; + LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]]; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + uint8_t mi = get_mi(&ue->frame_parms,subframe); + uint16_t ra_rnti=99; + uint8_t format0_found=0,format_c_found=0; + uint8_t tmode = ue->transmission_mode[eNB_id]; + uint8_t frame_type = frame_parms->frame_type; + uint8_t format1A_size_bits=0,format1A_size_bytes=0; + uint8_t format1C_size_bits=0,format1C_size_bytes=0; + uint8_t format0_size_bits=0,format0_size_bytes=0; + uint8_t format1_size_bits=0,format1_size_bytes=0; + uint8_t format2_size_bits=0,format2_size_bytes=0; + uint8_t format2A_size_bits=0,format2A_size_bytes=0; + dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe); + + switch (frame_parms->N_RB_DL) { + case 6: + if (frame_type == TDD) { + format1A_size_bits = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + format1A_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + format1C_size_bits = sizeof_DCI1C_1_5MHz_t; + format1C_size_bytes = sizeof(DCI1C_1_5MHz_t); + format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_1_5MHz_2A_TDD_t; + format2_size_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); + format2A_size_bits = sizeof_DCI2A_1_5MHz_2A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_1_5MHz_4A_TDD_t; + format2_size_bytes = sizeof(DCI2_1_5MHz_4A_TDD_t); + format2A_size_bits = sizeof_DCI2A_1_5MHz_4A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_TDD_t); + } + } else { + format1A_size_bits = sizeof_DCI1A_1_5MHz_FDD_t; + format1A_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + format1C_size_bits = sizeof_DCI1C_1_5MHz_t; + format1C_size_bytes = sizeof(DCI1C_1_5MHz_t); + format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); + format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_1_5MHz_2A_FDD_t; + format2_size_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); + format2A_size_bits = sizeof_DCI2A_1_5MHz_2A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_1_5MHz_4A_FDD_t; + format2_size_bytes = sizeof(DCI2_1_5MHz_4A_FDD_t); + format2A_size_bits = sizeof_DCI2A_1_5MHz_4A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_FDD_t); + } + } + + break; + + case 25: + default: + if (frame_type == TDD) { + format1A_size_bits = sizeof_DCI1A_5MHz_TDD_1_6_t; + format1A_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + format1C_size_bits = sizeof_DCI1C_5MHz_t; + format1C_size_bytes = sizeof(DCI1C_5MHz_t); + format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_5MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_5MHz_TDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_5MHz_2A_TDD_t; + format2_size_bytes = sizeof(DCI2_5MHz_2A_TDD_t); + format2A_size_bits = sizeof_DCI2A_5MHz_2A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_5MHz_4A_TDD_t; + format2_size_bytes = sizeof(DCI2_5MHz_4A_TDD_t); + format2A_size_bits = sizeof_DCI2A_5MHz_4A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_5MHz_4A_TDD_t); + } + } else { + format1A_size_bits = sizeof_DCI1A_5MHz_FDD_t; + format1A_size_bytes = sizeof(DCI1A_5MHz_FDD_t); + format1C_size_bits = sizeof_DCI1C_5MHz_t; + format1C_size_bytes = sizeof(DCI1C_5MHz_t); + format0_size_bits = sizeof_DCI0_5MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_5MHz_FDD_t); + format1_size_bits = sizeof_DCI1_5MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_5MHz_FDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_5MHz_2A_FDD_t; + format2_size_bytes = sizeof(DCI2_5MHz_2A_FDD_t); + format2A_size_bits = sizeof_DCI2A_5MHz_2A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_5MHz_4A_FDD_t; + format2_size_bytes = sizeof(DCI2_5MHz_4A_FDD_t); + format2A_size_bits = sizeof_DCI2A_5MHz_4A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_5MHz_4A_FDD_t); + } + } + + break; + + case 50: + if (frame_type == TDD) { + format1A_size_bits = sizeof_DCI1A_10MHz_TDD_1_6_t; + format1A_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + format1C_size_bits = sizeof_DCI1C_10MHz_t; + format1C_size_bytes = sizeof(DCI1C_10MHz_t); + format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_10MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_10MHz_TDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_10MHz_2A_TDD_t; + format2_size_bytes = sizeof(DCI2_10MHz_2A_TDD_t); + format2A_size_bits = sizeof_DCI2A_10MHz_2A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_10MHz_4A_TDD_t; + format2_size_bytes = sizeof(DCI2_10MHz_4A_TDD_t); + format2A_size_bits = sizeof_DCI2A_10MHz_4A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_10MHz_4A_TDD_t); + } + } else { + format1A_size_bits = sizeof_DCI1A_10MHz_FDD_t; + format1A_size_bytes = sizeof(DCI1A_10MHz_FDD_t); + format1C_size_bits = sizeof_DCI1C_10MHz_t; + format1C_size_bytes = sizeof(DCI1C_10MHz_t); + format0_size_bits = sizeof_DCI0_10MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_10MHz_FDD_t); + format1_size_bits = sizeof_DCI1_10MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_10MHz_FDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_10MHz_2A_FDD_t; + format2_size_bytes = sizeof(DCI2_10MHz_2A_FDD_t); + format2A_size_bits = sizeof_DCI2A_10MHz_2A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_10MHz_4A_FDD_t; + format2_size_bytes = sizeof(DCI2_10MHz_4A_FDD_t); + format2A_size_bits = sizeof_DCI2A_10MHz_4A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_10MHz_4A_FDD_t); + } + } + + break; + + case 100: + if (frame_type == TDD) { + format1A_size_bits = sizeof_DCI1A_20MHz_TDD_1_6_t; + format1A_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + format1C_size_bits = sizeof_DCI1C_20MHz_t; + format1C_size_bytes = sizeof(DCI1C_20MHz_t); + format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; + format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); + format1_size_bits = sizeof_DCI1_20MHz_TDD_t; + format1_size_bytes = sizeof(DCI1_20MHz_TDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_20MHz_2A_TDD_t; + format2_size_bytes = sizeof(DCI2_20MHz_2A_TDD_t); + format2A_size_bits = sizeof_DCI2A_20MHz_2A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_20MHz_4A_TDD_t; + format2_size_bytes = sizeof(DCI2_20MHz_4A_TDD_t); + format2A_size_bits = sizeof_DCI2A_20MHz_4A_TDD_t; + format2A_size_bytes = sizeof(DCI2A_20MHz_4A_TDD_t); + } + } else { + format1A_size_bits = sizeof_DCI1A_20MHz_FDD_t; + format1A_size_bytes = sizeof(DCI1A_20MHz_FDD_t); + format1C_size_bits = sizeof_DCI1C_20MHz_t; + format1C_size_bytes = sizeof(DCI1C_20MHz_t); + format0_size_bits = sizeof_DCI0_20MHz_FDD_t; + format0_size_bytes = sizeof(DCI0_20MHz_FDD_t); + format1_size_bits = sizeof_DCI1_20MHz_FDD_t; + format1_size_bytes = sizeof(DCI1_20MHz_FDD_t); + + if (frame_parms->nb_antenna_ports_eNB == 2) { + format2_size_bits = sizeof_DCI2_20MHz_2A_FDD_t; + format2_size_bytes = sizeof(DCI2_20MHz_2A_FDD_t); + format2A_size_bits = sizeof_DCI2A_20MHz_2A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); + } else if (frame_parms->nb_antenna_ports_eNB == 4) { + format2_size_bits = sizeof_DCI2_20MHz_4A_FDD_t; + format2_size_bytes = sizeof(DCI2_20MHz_4A_FDD_t); + format2A_size_bits = sizeof_DCI2A_20MHz_4A_FDD_t; + format2A_size_bytes = sizeof(DCI2A_20MHz_4A_FDD_t); + } + } + + break; + } + + if (do_common == 1) { +#ifdef DEBUG_DCI_DECODING + printf("[DCI search] subframe %d: doing common search/format0 aggregation 4\n",subframe); +#endif + + if (ue->prach_resources[eNB_id]) + ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; + + // First check common search spaces at aggregation 4 (SI_RNTI, P_RNTI and RA_RNTI format 0/1A), + // and UE_SPEC format0 (PUSCH) too while we're at it + dci_decoding_procedure0(pdcch_vars,1,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0) , + ra_rnti, + P_RNTI, + 2, + format1A, + format1A, + format1A, + format0, + format1A_size_bits, + format1A_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff) || + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + // Now check common search spaces at aggregation 4 (SI_RNTI,P_RNTI and RA_RNTI and C-RNTI format 1C), + // and UE_SPEC format0 (PUSCH) too while we're at it + dci_decoding_procedure0(pdcch_vars,1,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 2, + format1C, + format1C, + format1C, + format1C, + format1C_size_bits, + format1C_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff) || + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + // Now check common search spaces at aggregation 8 (SI_RNTI,P_RNTI and RA_RNTI format 1A), + // and UE_SPEC format0 (PUSCH) too while we're at it + // printf("[DCI search] doing common search/format0 aggregation 3\n"); +#ifdef DEBUG_DCI_DECODING + printf("[DCI search] doing common search/format0 aggregation 8\n"); +#endif + dci_decoding_procedure0(pdcch_vars,1,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + P_RNTI, + ra_rnti, + 3, + format1A, + format1A, + format1A, + format0, + format1A_size_bits, + format1A_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + // Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI and C-RNTI format 1C), + // and UE_SPEC format0 (PUSCH) too while we're at it + dci_decoding_procedure0(pdcch_vars,1,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 3, + format1C, + format1C, + format1C, + format1C, + format1C_size_bits, + format1C_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + //#endif + + } + + if (ue->UE_mode[eNB_id] <= PRACH) + return(dci_cnt); + + if (ue->prach_resources[eNB_id]) + ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; + + // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8 + // printf("[DCI search] Format 0/1A aggregation 8\n"); + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 0, + format1A, + format1A, + format1A, + format0, + format0_size_bits, + format0_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + //printf("[DCI search] Format 0 aggregation 1 dci_cnt %d\n",dci_cnt); + + if (dci_cnt == 0) + { + // Now check UE_SPEC format 0 search spaces at aggregation 4 + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 1, + format1A, + format1A, + format1A, + format0, + format0_size_bits, + format0_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + + //printf("[DCI search] Format 0 aggregation 2 dci_cnt %d\n",dci_cnt); + } + + if (dci_cnt == 0) + { + // Now check UE_SPEC format 0 search spaces at aggregation 2 + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 2, + format1A, + format1A, + format1A, + format0, + format0_size_bits, + format0_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + //printf("[DCI search] Format 0 aggregation 4 dci_cnt %d\n",dci_cnt); + } + + if (dci_cnt == 0) + { + // Now check UE_SPEC format 0 search spaces at aggregation 1 + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 3, + format1A, + format1A, + format1A, + format0, + format0_size_bits, + format0_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + //printf("[DCI search] Format 0 aggregation 8 dci_cnt %d\n",dci_cnt); + + } + // These are for CRNTI based on transmission mode + if ((tmode < 3) || (tmode == 7)) { + // Now check UE_SPEC format 1 search spaces at aggregation 1 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 0, + format1A, + format1A, + format1A, + format1, + format1_size_bits, + format1_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + //printf("[DCI search] Format 1 aggregation 1 dci_cnt %d\n",dci_cnt); + + if ((CCEmap0==0xffff) || + (format_c_found==1)) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 1 search spaces at aggregation 2 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 1, + format1A, + format1A, + format1A, + format1, + format1_size_bits, + format1_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + //printf("[DCI search] Format 1 aggregation 2 dci_cnt %d\n",dci_cnt); + + if ((CCEmap0==0xffff)|| + (format_c_found==1)) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 1 search spaces at aggregation 4 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 2, + format1A, + format1A, + format1A, + format1, + format1_size_bits, + format1_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + //printf("[DCI search] Format 1 aggregation 4 dci_cnt %d\n",dci_cnt); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + //#ifdef ALL_AGGREGATION + // Now check UE_SPEC format 1 search spaces at aggregation 8 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode,subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 3, + format1A, + format1A, + format1A, + format1, + format1_size_bits, + format1_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + //printf("[DCI search] Format 1 aggregation 8 dci_cnt %d\n",dci_cnt); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + //#endif //ALL_AGGREGATION + } else if (tmode == 3) { + + + // LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); + // Now check UE_SPEC format 2A_2A search spaces at aggregation 1 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 0, + format1A, + format1A, + format1A, + format2A, + format2A_size_bits, + format2A_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + LOG_D(PHY," format 2A_2A search CCEmap0 %x, format0_found %d, format_c_found %d \n", CCEmap0, format0_found, format_c_found); + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 2 search spaces at aggregation 2 + LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 2 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 1, + format1A, + format1A, + format1A, + format2A, + format2A_size_bits, + format2A_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 2_2A search spaces at aggregation 4 + // LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n"); + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 2, + format1A, + format1A, + format1A, + format2A, + format2A_size_bits, + format2A_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + //#ifdef ALL_AGGREGATION + // Now check UE_SPEC format 2_2A search spaces at aggregation 8 + LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 8 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 3, + format1A, + format1A, + format1A, + format2A, + format2A_size_bits, + format2A_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + //#endif + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + } else if (tmode == 4) { + + // Now check UE_SPEC format 2_2A search spaces at aggregation 1 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 0, + format1A, + format1A, + format1A, + format2, + format2_size_bits, + format2_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 2 search spaces at aggregation 2 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 1, + format1A, + format1A, + format1A, + format2, + format2_size_bits, + format2_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 2_2A search spaces at aggregation 4 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 2, + format1A, + format1A, + format1A, + format2, + format2_size_bits, + format2_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + //#ifdef ALL_AGGREGATION + // Now check UE_SPEC format 2_2A search spaces at aggregation 8 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 3, + format1A, + format1A, + format1A, + format2, + format2_size_bits, + format2_size_bytes, + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + //#endif + } else if ((tmode==5) || (tmode==6)) { // This is MU-MIMO + + // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 1 +#ifdef DEBUG_DCI_DECODING + LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n"); +#endif + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 0, + format1A, + format1A, + format1A, + format1E_2A_M10PRB, + sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, + sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 1, + format1A, + format1A, + format1A, + format1E_2A_M10PRB, + sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, + sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 2, + format1A, + format1A, + format1A, + format1E_2A_M10PRB, + sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, + sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + //#ifdef ALL_AGGREGATION + + // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8 + old_dci_cnt=dci_cnt; + dci_decoding_procedure0(pdcch_vars,0,mode, + subframe, + dci_alloc, + eNB_id, + ue->current_thread_id[subframe], + frame_parms, + mi, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), + ra_rnti, + P_RNTI, + 3, + format1A, + format1A, + format1A, + format1E_2A_M10PRB, + sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, + sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), + &dci_cnt, + &format0_found, + &format_c_found, + &CCEmap0, + &CCEmap1, + &CCEmap2); + + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + if (dci_cnt>old_dci_cnt) + return(dci_cnt); + + //#endif //ALL_AGGREGATION + + } + + return(dci_cnt); +} diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c similarity index 77% rename from openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c rename to openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c index 7acf6480eb40df1d7aef3e2c4be17bdcb2dc2fa4..30f7733be24ad0459eacc25df2d2e0a385a6bb1e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c @@ -31,14 +31,15 @@ */ //#include "defs.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/CODING/extern.h" -#include "SCHED/extern.h" -#include "SIMULATION/TOOLS/defs.h" +#include "PHY/defs_UE.h" +#include "PHY/CODING/coding_extern.h" +#include "SCHED/sched_common_extern.h" +#include "SIMULATION/TOOLS/sim.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" //#define DEBUG_DLSCH_DECODING +//#define UE_DEBUG_TRACE 1 -extern double cpuf; void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { @@ -205,21 +206,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, time_stats_t *); #endif - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); +decoder_if_t tc; @@ -254,13 +241,13 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, #if 0 tc_2cw = phy_threegpplte_turbo_decoder16avx2; #endif - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; } else { AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n", harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; } @@ -489,7 +476,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); ret = tc (&harq_process->d[r][96], + NULL, harq_process->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -758,3 +747,183 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, return(ret); } +int dlsch_encoding_SIC(PHY_VARS_UE *ue, + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats) +{ + + unsigned int G; + unsigned int crc=1; + unsigned short iind; + + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + unsigned char harq_pid = ue->dlsch[subframe&2][0][0]->rnti; + unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; + unsigned int A; + unsigned char mod_order; + unsigned int Kr=0,Kr_bytes,r,r_offset=0; + // unsigned short m=dlsch->harq_processes[harq_pid]->mcs; + uint8_t beamforming_mode=0; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); + + A = dlsch->harq_processes[harq_pid]->TBS; //6228 + // printf("Encoder: A: %d\n",A); + mod_order = dlsch->harq_processes[harq_pid]->Qm; + + if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7) + beamforming_mode = 7; + else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8) + beamforming_mode = 8; + else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10) + beamforming_mode = 9; + G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode); + + + // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet + if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet +#ifdef DEBUG_DLSCH_CODING + printf("SIC encoding thinks this is a new packet \n"); +#endif + /* + int i; + printf("dlsch (tx): \n"); + for (i=0;i<(A>>3);i++) + printf("%02x.",a[i]); + printf("\n"); + */ + // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a, + A)>>8; + a[A>>3] = ((uint8_t*)&crc)[2]; + a[1+(A>>3)] = ((uint8_t*)&crc)[1]; + a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + // printf("CRC %x (A %d)\n",crc,A); + + dlsch->harq_processes[harq_pid]->B = A+24; + // dlsch->harq_processes[harq_pid]->b = a; + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); + + if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, + dlsch->harq_processes[harq_pid]->c, + dlsch->harq_processes[harq_pid]->B, + &dlsch->harq_processes[harq_pid]->C, + &dlsch->harq_processes[harq_pid]->Cplus, + &dlsch->harq_processes[harq_pid]->Cminus, + &dlsch->harq_processes[harq_pid]->Kplus, + &dlsch->harq_processes[harq_pid]->Kminus, + &dlsch->harq_processes[harq_pid]->F)<0) + return(-1); + + for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { + + if (r<dlsch->harq_processes[harq_pid]->Cminus) + Kr = dlsch->harq_processes[harq_pid]->Kminus; + else + Kr = dlsch->harq_processes[harq_pid]->Kplus; + + Kr_bytes = Kr>>3; + + // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14) + if (Kr_bytes<=64) + iind = (Kr_bytes-5); + else if (Kr_bytes <=128) + iind = 59 + ((Kr_bytes-64)>>1); + else if (Kr_bytes <= 256) + iind = 91 + ((Kr_bytes-128)>>2); + else if (Kr_bytes <= 768) + iind = 123 + ((Kr_bytes-256)>>3); + else { + printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes); + return(-1); + } + + +#ifdef DEBUG_DLSCH_CODING + printf("Generating Code Segment %d (%d bits)\n",r,Kr); + // generate codewords + + printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A); + printf("N_RB = %d\n",nb_rb); + printf("Ncp %d\n",frame_parms->Ncp); + printf("mod_order %d\n",mod_order); +#endif + + +#ifdef DEBUG_DLSCH_CODING + printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); +#endif + start_meas(te_stats); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); + stop_meas(te_stats); +#ifdef DEBUG_DLSCH_CODING + + if (r==0) + write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4); + +#endif + start_meas(i_stats); + dlsch->harq_processes[harq_pid]->RTC[r] = + sub_block_interleaving_turbo(4+(Kr_bytes*8), + &dlsch->harq_processes[harq_pid]->d[r][96], + dlsch->harq_processes[harq_pid]->w[r]); + stop_meas(i_stats); + } + + } + + // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the + // outputs for each code segment, see Section 5.1.5 p.20 + + for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { +#ifdef DEBUG_DLSCH_CODING + printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", + r, + G, + Kr*3, + mod_order,nb_rb); +#endif + + start_meas(rm_stats); +#ifdef DEBUG_DLSCH_CODING + printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); +#endif + r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], + G, //G + dlsch->harq_processes[harq_pid]->w[r], + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->C, // C + dlsch->Nsoft, // Nsoft, + dlsch->Mdlharq, + dlsch->Kmimo, + dlsch->harq_processes[harq_pid]->rvidx, + dlsch->harq_processes[harq_pid]->Qm, + dlsch->harq_processes[harq_pid]->Nl, + r, + nb_rb); + // m); // r + stop_meas(rm_stats); +#ifdef DEBUG_DLSCH_CODING + + if (r==dlsch->harq_processes[harq_pid]->C-1) + write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4); + +#endif + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); + + return(0); +} diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c similarity index 99% rename from openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c rename to openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 1bd0076e1428bb656941cd1cc8bf965d4a1b694a..665d5cead04d59a18aaebce0701066b9f1861600 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -29,11 +29,11 @@ * \note * \warning */ -//#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "defs.h" -#include "extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "SCHED_UE/sched_UE.h" +#include "transport_ue.h" +#include "transport_proto_ue.h" #include "PHY/sse_intrin.h" #include "T.h" @@ -48,13 +48,10 @@ int16_t interf_unaw_shift = 13; //#define DEBUG_HARQ -//#undef LOG_D -//#define LOG_D LOG_I - //#define DEBUG_PHY 1 //#define DEBUG_DLSCH_DEMOD 1 - +//#define DISABLE_LOG_X // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; @@ -370,7 +367,7 @@ int rx_pdsch(PHY_VARS_UE *ue, //printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id); if (nb_rb==0) { - LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); + // LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); return(-1); } @@ -845,18 +842,20 @@ int rx_pdsch(PHY_VARS_UE *ue, pllr_symbol_cw1 = (int8_t*)pdsch_vars[eNB_id]->llr[1]; pllr_symbol_cw0 += llr_offset_symbol; pllr_symbol_cw1 += llr_offset_symbol; - - /*LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", - proc->frame_rx, proc->subframe_rx,symbol, + /* + LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n", + frame, subframe,symbol, nb_rb,dlsch0_harq->Qm, pdsch_vars[eNB_id]->llr_length[symbol], pdsch_vars[eNB_id]->llr_offset[symbol], (int16_t*)pdsch_vars[eNB_id]->llr[0], - pllr_symbol);*/ - + pllr_symbol_cw0); + */ switch (dlsch0_harq->Qm) { case 2 : if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { + + dlsch_qpsk_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, (int16_t*)pllr_symbol_cw0, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c similarity index 99% rename from openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c rename to openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c index 8ea922b85c7ea13725aab5d113cdceecc1adaaef..525c8db676b1e60f76e751fee197ff56352e18c1 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c @@ -30,17 +30,18 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/TOOLS/defs.h" -#include "PHY/extern.h" -#include "defs.h" -#include "extern.h" +#include "PHY/defs_UE.h" +#include "PHY/TOOLS/tools_defs.h" +#include "PHY/phy_extern_ue.h" +#include "transport_ue.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" +#include "transport_proto_ue.h" #include "PHY/sse_intrin.h" //#define DEBUG_LLR_SIC -int16_t zero[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; +int16_t zeros[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; int16_t ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; #if defined(__x86_64__) || defined(__i386__) __m128i rho_rpi __attribute__ ((aligned(16))); @@ -672,14 +673,14 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, } - //printf("dlsch_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); - /*LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / FirstSym %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n", + /* + LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / FirstSym %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n", symbol, first_symbol_flag, len, dlsch_llr, - llr32);*/ - + llr32); + */ //printf("ll32p=%p , dlsch_llr=%p, symbol=%d, flag=%d \n", llr32, dlsch_llr, symbol, first_symbol_flag); for (i=0; i<len; i++) { *llr32 = *rxF; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c similarity index 99% rename from openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c rename to openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c index 588adfbc55c65f736444797013a08ab37ade4a65..81cd18c954f647ceb9bd58c50a828fdf94a35b14 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c @@ -30,11 +30,10 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/TOOLS/defs.h" -#include "PHY/extern.h" -#include "defs.h" -#include "extern.h" +#include "PHY/defs_UE.h" +#include "PHY/TOOLS/tools_defs.h" +#include "PHY/phy_extern_ue.h" +#include "transport_ue.h" #include "PHY/sse_intrin.h" int16_t ones256[16] __attribute__ ((aligned(32))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c similarity index 96% rename from openair1/PHY/LTE_TRANSPORT/drs_modulation.c rename to openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c index a432cde4e4fb20ed7721e223475f57953623f7f5..96ff82ba162d2cd6278c54a77a4129a65f7c186a 100644 --- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c @@ -29,9 +29,11 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #include "PHY/sse_intrin.h" +#include "transport_proto_ue.h" + //#define DEBUG_DRS int generate_drs_pusch(PHY_VARS_UE *ue, @@ -94,8 +96,10 @@ int generate_drs_pusch(PHY_VARS_UE *ue, l<frame_parms->symbols_per_tti; l += (7 - frame_parms->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) { - drs_offset = 0; // printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d\n",Msc_RS, Msc_RS_idx); - + drs_offset = 0; +#ifdef DEBUG_DRS + printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d, u=%d,v=%d\n",Msc_RS, Msc_RS_idx,u,v); +#endif re_offset = frame_parms->first_carrier_offset; diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c similarity index 98% rename from openair1/PHY/LTE_TRANSPORT/initial_sync.c rename to openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c index 918696968b373ce1830f4abe081fa01505e4e7ae..b1d5b9b70e3b50dc3ca03ddbbdeddaff6d629b1e 100644 --- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c @@ -30,18 +30,20 @@ * \warning */ #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" -#include "defs.h" -#include "extern.h" - - +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "SCHED_UE/sched_UE.h" +#include "transport_proto_ue.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" +#include "openair2/LAYER2/MAC/mac_proto.h" #include "common_lib.h" +#include "PHY/INIT/phy_init.h" + extern openair0_config_t openair0_cfg[]; -#define DEBUG_INITIAL_SYNCH +//#define DEBUG_INITIAL_SYNCH int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..a6acec9ca3762499a8c7fbed3032f253c3f1a7cf --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c @@ -0,0 +1,632 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/pbch.c +* \brief Top-level routines for generating and decoding the PBCH/BCH physical/transport channel V8.6 2009-03 +* \author R. Knopp, F. Kaltenberger +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger.fr +* \note +* \warning +*/ +#include "PHY/defs_UE.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/coding_extern.h" +#include "PHY/CODING/lte_interleaver_inline.h" +#include "transport_ue.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/sse_intrin.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" + +//#define DEBUG_PBCH 1 +//#define DEBUG_PBCH_ENCODING +//#define INTERFERENCE_MITIGATION 1 + + +#define PBCH_A 24 + +uint16_t pbch_extract(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + uint32_t symbol, + uint32_t high_speed_flag, + LTE_DL_FRAME_PARMS *frame_parms) +{ + + + uint16_t rb,nb_rb=6; + uint8_t i,j,aarx,aatx; + int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; + + uint32_t nsymb = (frame_parms->Ncp==0) ? 7:6; + uint32_t symbol_mod = symbol % nsymb; + + int rx_offset = frame_parms->ofdm_symbol_size-3*12; + int ch_offset = frame_parms->N_RB_DL*6-3*12; + int nushiftmod3 = frame_parms->nushift%3; + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + /* + printf("extract_rbs (nushift %d): symbol_mod=%d, rx_offset=%d, ch_offset=%d\n",frame_parms->nushift,symbol_mod, + (rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))*2, + LTE_CE_OFFSET+ch_offset+(symbol_mod*(frame_parms->ofdm_symbol_size))); + */ + + rxF = &rxdataF[aarx][(rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; + rxF_ext = &rxdataF_ext[aarx][symbol_mod*(6*12)]; + + for (rb=0; rb<nb_rb; rb++) { + // skip DC carrier + if (rb==3) { + rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; + } + + if ((symbol_mod==0) || (symbol_mod==1)) { + j=0; + + for (i=0; i<12; i++) { + if ((i!=nushiftmod3) && + (i!=(nushiftmod3+3)) && + (i!=(nushiftmod3+6)) && + (i!=(nushiftmod3+9))) { + rxF_ext[j++]=rxF[i]; + } + } + + rxF+=12; + rxF_ext+=8; + } else { + for (i=0; i<12; i++) { + rxF_ext[i]=rxF[i]; + } + + rxF+=12; + rxF_ext+=12; + } + } + + for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) { + if (high_speed_flag == 1) + dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset+(symbol*(frame_parms->ofdm_symbol_size))]; + else + dl_ch0 = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset]; + + dl_ch0_ext = &dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*(6*12)]; + + for (rb=0; rb<nb_rb; rb++) { + // skip DC carrier + // if (rb==3) dl_ch0++; + if (symbol_mod>1) { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); + dl_ch0+=12; + dl_ch0_ext+=12; + } else { + j=0; + + for (i=0; i<12; i++) { + if ((i!=nushiftmod3) && + (i!=(nushiftmod3+3)) && + (i!=(nushiftmod3+6)) && + (i!=(nushiftmod3+9))) { + // printf("PBCH extract i %d j %d => (%d,%d)\n",i,j,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); + dl_ch0_ext[j++]=dl_ch0[i]; + } + } + + dl_ch0+=12; + dl_ch0_ext+=8; + } + } + } //tx antenna loop + + } + + return(0); +} + +//__m128i avg128; + +//compute average channel_level on each (TX,RX) antenna pair +int pbch_channel_level(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + uint32_t symbol) +{ + + int16_t rb, nb_rb=6; + uint8_t aatx,aarx; + +#if defined(__x86_64__) || defined(__i386__) + __m128i avg128; + __m128i *dl_ch128; +#elif defined(__arm__) + int32x4_t avg128; + int16x8_t *dl_ch128; +#endif + int avg1=0,avg2=0; + + uint32_t nsymb = (frame_parms->Ncp==0) ? 7:6; + uint32_t symbol_mod = symbol % nsymb; + + for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antenna_ports_eNB;aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + //clear average level + +#if defined(__x86_64__) || defined(__i386__) + avg128 = _mm_setzero_si128(); + dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12]; +#elif defined(__arm__) + avg128 = vdupq_n_s32(0); + dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12]; + +#endif + for (rb=0; rb<nb_rb; rb++) { +#if defined(__x86_64__) || defined(__i386__) + avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); + avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); + avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); +#elif defined(__arm__) +// to be filled in +#endif + dl_ch128+=3; + /* + if (rb==0) { + print_shorts("dl_ch128",&dl_ch128[0]); + print_shorts("dl_ch128",&dl_ch128[1]); + print_shorts("dl_ch128",&dl_ch128[2]); + } + */ + } + + avg1 = (((int*)&avg128)[0] + + ((int*)&avg128)[1] + + ((int*)&avg128)[2] + + ((int*)&avg128)[3])/(nb_rb*12); + + if (avg1>avg2) + avg2 = avg1; + + //msg("Channel level : %d, %d\n",avg1, avg2); + } +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif + return(avg2); + +} + +#if defined(__x86_64__) || defined(__i386__) +__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3; +#elif defined(__arm__) +int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3; +#endif +void pbch_channel_compensation(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **rxdataF_comp, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t symbol, + uint8_t output_shift) +{ + + uint16_t rb,nb_rb=6; + uint8_t aatx,aarx,symbol_mod; +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; +#elif defined(__arm__) + +#endif + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antenna_ports_eNB;aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + +#if defined(__x86_64__) || defined(__i386__) + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol_mod*6*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol_mod*6*12]; + +#elif defined(__arm__) +// to be filled in +#endif + + for (rb=0; rb<nb_rb; rb++) { + //printf("rb %d\n",rb); +#if defined(__x86_64__) || defined(__i386__) + // multiply by conjugated channel + mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpP0); + // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) + mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); + mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpP1); + mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[0]); + // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); + // print_ints("re(shift)",&mmtmpP0); + mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); + // print_ints("im(shift)",&mmtmpP1); + mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); + mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); + // print_ints("c0",&mmtmpP2); + // print_ints("c1",&mmtmpP3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpP2,mmtmpP3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); + + // multiply by conjugated channel + mmtmpP0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) + mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); + mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); + mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[1]); + // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); + mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); + mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); + mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpP2,mmtmpP3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); + + if (symbol_mod>1) { + // multiply by conjugated channel + mmtmpP0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); + // mmtmpP0 contains real part of 4 consecutive outputs (32-bit) + mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1)); + mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]); + mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[2]); + // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift); + mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift); + mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1); + mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1); + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpP2,mmtmpP3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch128+2); + // print_shorts("pack:",rxdataF_comp128+2); + + dl_ch128+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } else { + dl_ch128+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + } +#elif defined(__arm__) +// to be filled in +#endif + } + } +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + +void pbch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + uint8_t symbol) +{ + + uint8_t aatx, symbol_mod; + int i, nb_rb=6; +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1; +#elif defined(__arm__) + int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1; +#endif + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if (frame_parms->nb_antennas_rx>1) { + for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12]; +#elif defined(__arm__) + rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12]; + rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12]; + +#endif + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0; i<nb_rb*3; i++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); +#elif defined(__arm__) + rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); + +#endif + } + } + } +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + +void pbch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, + int8_t* llr, + uint32_t length, + uint8_t frame_mod4) +{ + int i; + uint8_t reset; + uint32_t x1, x2, s=0; + + reset = 1; + // x1 is set in first call to lte_gold_generic + x2 = frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.6.1 + // msg("pbch_unscrambling: Nid_cell = %d\n",x2); + + for (i=0; i<length; i++) { + if (i%32==0) { + s = lte_gold_generic(&x1, &x2, reset); + // printf("lte_gold[%d]=%x\n",i,s); + reset = 0; + } + + // take the quarter of the PBCH that corresponds to this frame + if ((i>=(frame_mod4*(length>>2))) && (i<((1+frame_mod4)*(length>>2)))) { + + if (((s>>(i%32))&1)==0) + llr[i] = -llr[i]; + } + } +} + +void pbch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + uint8_t symbol) +{ + + + int16_t *rxF0,*rxF1; + // __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b; + uint8_t rb,re,symbol_mod; + int jj; + + // printf("Doing alamouti\n"); + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + jj = (symbol_mod*6*12); + + rxF0 = (int16_t*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y + rxF1 = (int16_t*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y + + for (rb=0; rb<6; rb++) { + + for (re=0; re<12; re+=2) { + + // Alamouti RX combining + + rxF0[0] = rxF0[0] + rxF1[2]; + rxF0[1] = rxF0[1] - rxF1[3]; + + rxF0[2] = rxF0[2] - rxF1[0]; + rxF0[3] = rxF0[3] + rxF1[1]; + + rxF0+=4; + rxF1+=4; + } + + } + +} + +void pbch_quantize(int8_t *pbch_llr8, + int16_t *pbch_llr, + uint16_t len) +{ + + uint16_t i; + + for (i=0; i<len; i++) { + if (pbch_llr[i]>7) + pbch_llr8[i]=7; + else if (pbch_llr[i]<-8) + pbch_llr8[i]=-8; + else + pbch_llr8[i] = (char)(pbch_llr[i]); + + } +} + +static unsigned char dummy_w_rx[3*3*(16+PBCH_A)]; +static int8_t pbch_w_rx[3*3*(16+PBCH_A)],pbch_d_rx[96+(3*(16+PBCH_A))]; + + +uint16_t rx_pbch(LTE_UE_COMMON *lte_ue_common_vars, + LTE_UE_PBCH *lte_ue_pbch_vars, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t eNB_id, + MIMO_mode_t mimo_mode, + uint32_t high_speed_flag, + uint8_t frame_mod4) +{ + + uint8_t log2_maxh;//,aatx,aarx; + int max_h=0; + + int symbol,i; + uint32_t nsymb = (frame_parms->Ncp==0) ? 14:12; + uint16_t pbch_E; + uint8_t pbch_a[8]; + uint8_t RCC; + + int8_t *pbch_e_rx; + uint8_t *decoded_output = lte_ue_pbch_vars->decoded_output; + uint16_t crc; + + + // pbch_D = 16+PBCH_A; + + pbch_E = (frame_parms->Ncp==0) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK) + pbch_e_rx = <e_ue_pbch_vars->llr[frame_mod4*(pbch_E>>2)]; +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] starting symbol loop (Ncp %d, frame_mod4 %d,mimo_mode %d\n",frame_parms->Ncp,frame_mod4,mimo_mode); +#endif + + // clear LLR buffer + memset(lte_ue_pbch_vars->llr,0,pbch_E); + + for (symbol=(nsymb>>1); symbol<(nsymb>>1)+4; symbol++) { + +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] starting extract\n"); +#endif + pbch_extract(lte_ue_common_vars->common_vars_rx_data_per_thread[0].rxdataF, + lte_ue_common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates[eNB_id], + lte_ue_pbch_vars->rxdataF_ext, + lte_ue_pbch_vars->dl_ch_estimates_ext, + symbol, + high_speed_flag, + frame_parms); +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PHY] PBCH Symbol %d\n",symbol); + LOG_D(PHY,"[PHY] PBCH starting channel_level\n"); +#endif + + max_h = pbch_channel_level(lte_ue_pbch_vars->dl_ch_estimates_ext, + frame_parms, + symbol); + log2_maxh = 3+(log2_approx(max_h)/2); + +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",log2_maxh,max_h); +#endif + + pbch_channel_compensation(lte_ue_pbch_vars->rxdataF_ext, + lte_ue_pbch_vars->dl_ch_estimates_ext, + lte_ue_pbch_vars->rxdataF_comp, + frame_parms, + symbol, + log2_maxh); // log2_maxh+I0_shift + + if (frame_parms->nb_antennas_rx > 1) + pbch_detection_mrc(frame_parms, + lte_ue_pbch_vars->rxdataF_comp, + symbol); + + + if (mimo_mode == ALAMOUTI) { + pbch_alamouti(frame_parms,lte_ue_pbch_vars->rxdataF_comp,symbol); + } else if (mimo_mode != SISO) { + LOG_D(PHY,"[PBCH][RX] Unsupported MIMO mode\n"); + return(-1); + } + + if (symbol>(nsymb>>1)+1) { + pbch_quantize(pbch_e_rx, + (short*)&(lte_ue_pbch_vars->rxdataF_comp[0][(symbol%(nsymb>>1))*72]), + 144); + + pbch_e_rx+=144; + } else { + pbch_quantize(pbch_e_rx, + (short*)&(lte_ue_pbch_vars->rxdataF_comp[0][(symbol%(nsymb>>1))*72]), + 96); + + pbch_e_rx+=96; + } + + + } + + pbch_e_rx = lte_ue_pbch_vars->llr; + + + + //un-scrambling +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] doing unscrambling\n"); +#endif + + + pbch_unscrambling(frame_parms, + pbch_e_rx, + pbch_E, + frame_mod4); + + + + //un-rate matching +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] doing un-rate-matching\n"); +#endif + + + memset(dummy_w_rx,0,3*3*(16+PBCH_A)); + RCC = generate_dummy_w_cc(16+PBCH_A, + dummy_w_rx); + + + lte_rate_matching_cc_rx(RCC,pbch_E,pbch_w_rx,dummy_w_rx,pbch_e_rx); + + sub_block_deinterleaving_cc((unsigned int)(PBCH_A+16), + &pbch_d_rx[96], + &pbch_w_rx[0]); + + memset(pbch_a,0,((16+PBCH_A)>>3)); + + + + + phy_viterbi_lte_sse2(pbch_d_rx+96,pbch_a,16+PBCH_A); + + // Fix byte endian of PBCH (bit 23 goes in first) + for (i=0; i<(PBCH_A>>3); i++) + decoded_output[(PBCH_A>>3)-i-1] = pbch_a[i]; + +#ifdef DEBUG_PBCH + + for (i=0; i<(PBCH_A>>3); i++) + LOG_I(PHY,"[PBCH] pbch_a[%d] = %x\n",i,decoded_output[i]); + +#endif //DEBUG_PBCH + +#ifdef DEBUG_PBCH + LOG_I(PHY,"PBCH CRC %x : %x\n", + crc16(pbch_a,PBCH_A), + ((uint16_t)pbch_a[PBCH_A>>3]<<8)+pbch_a[(PBCH_A>>3)+1]); +#endif + + crc = (crc16(pbch_a,PBCH_A)>>16) ^ + (((uint16_t)pbch_a[PBCH_A>>3]<<8)+pbch_a[(PBCH_A>>3)+1]); + + if (crc == 0x0000) + return(1); + else if (crc == 0xffff) + return(2); + else if (crc == 0x5555) + return(4); + else + return(-1); + + +} diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pcfich_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pcfich_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..82bb0a2659ed9ff4e4ea8a09fc4d068f2c516092 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/pcfich_ue.c @@ -0,0 +1,162 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/pcfich.c +* \brief Top-level routines for generating and decoding the PCFICH/CFI physical/transport channel V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#include "PHY/defs_UE.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" + +//#define DEBUG_PCFICH + +extern uint8_t pcfich_b[4][32]; + + + + +void pcfich_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + int16_t *d) +{ + + uint32_t i; + uint8_t reset; + uint32_t x1, x2, s=0; + + reset = 1; + // x1 is set in lte_gold_generic + x2 = ((((2*frame_parms->Nid_cell)+1)*(1+subframe))<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.7.1 + + for (i=0; i<32; i++) { + if ((i&0x1f)==0) { + s = lte_gold_generic(&x1, &x2, reset); + //printf("lte_gold[%d]=%x\n",i,s); + reset = 0; + } + + if (((s>>(i&0x1f))&1) == 1) + d[i]=-d[i]; + + } +} + +uint8_t rx_pcfich(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + LTE_UE_PDCCH *lte_ue_pdcch_vars, + MIMO_mode_t mimo_mode) +{ + + uint8_t pcfich_quad; + uint8_t i,j; + uint16_t reg_offset; + + int32_t **rxdataF_comp = lte_ue_pdcch_vars->rxdataF_comp; + int16_t pcfich_d[32],*pcfich_d_ptr; + int32_t metric,old_metric=-16384; + uint8_t num_pdcch_symbols=3; + uint16_t *pcfich_reg = frame_parms->pcfich_reg; + + // demapping + // loop over 4 quadruplets and lookup REGs + // m=0; + pcfich_d_ptr = pcfich_d; + + for (pcfich_quad=0; pcfich_quad<4; pcfich_quad++) { + reg_offset = (pcfich_reg[pcfich_quad]*4); + + for (i=0; i<4; i++) { + + pcfich_d_ptr[0] = ((int16_t*)&rxdataF_comp[0][reg_offset+i])[0]; // RE component + pcfich_d_ptr[1] = ((int16_t*)&rxdataF_comp[0][reg_offset+i])[1]; // IM component +#ifdef DEBUG_PCFICH + printf("rx_pcfich: quad %d, i %d, offset %d => (%d,%d) => pcfich_d_ptr[0] %d \n",pcfich_quad,i,reg_offset+i, + ((int16_t*)&rxdataF_comp[0][reg_offset+i])[0], + ((int16_t*)&rxdataF_comp[0][reg_offset+i])[1], + pcfich_d_ptr[0]); +#endif + pcfich_d_ptr+=2; + } + + /* + } + else { // ALAMOUTI + for (i=0;i<4;i+=2) { + pcfich_d_ptr[0] = 0; + pcfich_d_ptr[1] = 0; + pcfich_d_ptr[2] = 0; + pcfich_d_ptr[3] = 0; + for (j=0;j<frame_parms->nb_antennas_rx;j++) { + + pcfich_d_ptr[0] += (((int16_t*)&rxdataF_comp[j][reg_offset+i])[0]+ + ((int16_t*)&rxdataF_comp[j+2][reg_offset+i+1])[0]); // RE component + pcfich_d_ptr[1] += (((int16_t*)&rxdataF_comp[j][reg_offset+i])[1] - + ((int16_t*)&rxdataF_comp[j+2][reg_offset+i+1])[1]);// IM component + + pcfich_d_ptr[2] += (((int16_t*)&rxdataF_comp[j][reg_offset+i+1])[0]- + ((int16_t*)&rxdataF_comp[j+2][reg_offset+i])[0]); // RE component + pcfich_d_ptr[3] += (((int16_t*)&rxdataF_comp[j][reg_offset+i+1])[1] + + ((int16_t*)&rxdataF_comp[j+2][reg_offset+i])[1]);// IM component + + + } + + pcfich_d_ptr+=4; + + } + */ + } + + // pcfhich unscrambling + + pcfich_unscrambling(frame_parms,subframe,pcfich_d); + + // pcfich detection + + for (i=0; i<3; i++) { + metric = 0; + + for (j=0; j<32; j++) { + // printf("pcfich_b[%d][%d] %d => pcfich_d[%d] %d\n",i,j,pcfich_b[i][j],j,pcfich_d[j]); + metric += (int32_t)(((pcfich_b[i][j]==0) ? (pcfich_d[j]) : (-pcfich_d[j]))); + } + +#ifdef DEBUG_PCFICH + printf("metric %d : %d\n",i,metric); +#endif + + if (metric > old_metric) { + num_pdcch_symbols = 1+i; + old_metric = metric; + } + } + +#ifdef DEBUG_PCFICH + printf("[PHY] PCFICH detected for %d PDCCH symbols\n",num_pdcch_symbols); +#endif + return(num_pdcch_symbols); +} diff --git a/openair1/PHY/LTE_TRANSPORT/pch.c b/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c similarity index 97% rename from openair1/PHY/LTE_TRANSPORT/pch.c rename to openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c index 600c5215bdd5c4bbde741ff86b4dad7196620633..aed3ddabc15b6279393c7405961edde780c51cd2 100644 --- a/openair1/PHY/LTE_TRANSPORT/pch.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #include "assertions.h" const unsigned int Ttab[4] = {32,64,128,256}; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/phich_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/phich_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..669e0937c6c57bc559d4e2f87c546fd550419ac5 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/phich_ue.c @@ -0,0 +1,489 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/phich_ue.c +* \brief Top-level routines for decoding the PHICH/HI physical/transport channel V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ + +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "SCHED_UE/sched_UE.h" +#include "transport_ue.h" +#include "transport_proto_ue.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" + +#include "LAYER2/MAC/mac.h" + +#include "T.h" + +//#define DEBUG_PHICH 1 + +//extern unsigned short pcfich_reg[4]; +//extern unsigned char pcfich_first_reg_idx; + +//unsigned short phich_reg[MAX_NUM_PHICH_GROUPS][3]; + + +uint8_t rv_table[4] = {0, 2, 3, 1}; + + + + + + +// This routine demodulates the PHICH and updates PUSCH/ULSCH parameters + +void rx_phich(PHY_VARS_UE *ue, + UE_rxtx_proc_t *proc, + uint8_t subframe, + uint8_t eNB_id) +{ + + + LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; + LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]; + + // uint8_t HI; + uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,proc->frame_rx,subframe); + LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; + int16_t phich_d[24],*phich_d_ptr,HI16; + // unsigned int i,aa; + int8_t d[24],*dp; + uint16_t reg_offset; + + // scrambling + uint32_t x1, x2, s=0; + uint8_t reset = 1; + int16_t cs[12]; + uint32_t i,i2,i3,phich_quad; + int32_t **rxdataF_comp = pdcch_vars[eNB_id]->rxdataF_comp; + uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH; + uint8_t NSF_PHICH = 4; + uint8_t pusch_subframe; + + int8_t delta_PUSCH_acc[4] = {-1,0,1,3}; + + // check if we're expecting a PHICH in this subframe + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe); + + if (!ulsch) + return; + + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX Status: %d \n",ue->Mod_id,harq_pid,proc->frame_rx,subframe, ulsch->harq_processes[harq_pid]->status); + + if (ulsch->harq_processes[harq_pid]->status == ACTIVE) { + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX ACTIVE\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe); + Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; + + if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) + Ngroup_PHICH++; + + if (frame_parms->Ncp == 1) + NSF_PHICH = 2; + + + ngroup_PHICH = (ulsch->harq_processes[harq_pid]->first_rb + + ulsch->harq_processes[harq_pid]->n_DMRS)%Ngroup_PHICH; + + if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) { + pusch_subframe = phich_subframe2_pusch_subframe(frame_parms,subframe); + + if ((pusch_subframe == 4) || (pusch_subframe == 9)) + ngroup_PHICH += Ngroup_PHICH; + } + + nseq_PHICH = ((ulsch->harq_processes[harq_pid]->first_rb/Ngroup_PHICH) + + ulsch->harq_processes[harq_pid]->n_DMRS)%(2*NSF_PHICH); + } else { + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH RX %s\n", + ue->Mod_id, + harq_pid, + proc->frame_rx, + subframe, + (ulsch->harq_processes[harq_pid]->status==SCH_IDLE? "SCH_IDLE" : + (ulsch->harq_processes[harq_pid]->status==ACTIVE? "ACTIVE" : + (ulsch->harq_processes[harq_pid]->status==CBA_ACTIVE? "CBA_ACTIVE": + (ulsch->harq_processes[harq_pid]->status==DISABLED? "DISABLED" : "UNKNOWN"))))); + + return; + } + + memset(d,0,24*sizeof(int8_t)); + phich_d_ptr = phich_d; + + // x1 is set in lte_gold_generic + x2 = (((subframe+1)*((frame_parms->Nid_cell<<1)+1))<<9) + frame_parms->Nid_cell; + + s = lte_gold_generic(&x1, &x2, reset); + + // compute scrambling sequence + for (i=0; i<12; i++) { + cs[i] = 1-(((s>>(i&0x1f))&1)<<1); + } + + if (frame_parms->Ncp == 0) { // Normal Cyclic Prefix + + + // 12 output symbols (Msymb) + + for (i=0,i2=0,i3=0; i<3; i++,i2+=4,i3+=8) { + switch (nseq_PHICH) { + case 0: // +1 +1 +1 +1 + d[i3] = cs[i2]; + d[1+i3] = cs[i2]; + d[2+i3] = cs[1+i2]; + d[3+i3] = cs[1+i2]; + d[4+i3] = cs[2+i2]; + d[5+i3] = cs[2+i2]; + d[6+i3] = cs[3+i2]; + d[7+i3] = cs[3+i2]; + break; + + case 1: // +1 -1 +1 -1 + d[i3] = cs[i2]; + d[1+i3] = cs[i2]; + d[2+i3] = -cs[1+i2]; + d[3+i3] = -cs[1+i2]; + d[4+i3] = cs[2+i2]; + d[5+i3] = cs[2+i2]; + d[6+i3] = -cs[3+i2]; + d[7+i3] = -cs[3+i2]; + break; + + case 2: // +1 +1 -1 -1 + d[i3] = cs[i2]; + d[1+i3] = cs[i2]; + d[2+i3] = cs[1+i2]; + d[3+i3] = cs[1+i2]; + d[4+i3] = -cs[2+i2]; + d[5+i3] = -cs[2+i2]; + d[6+i3] = -cs[3+i2]; + d[7+i3] = -cs[3+i2]; + break; + + case 3: // +1 -1 -1 +1 + d[i3] = cs[i2]; + d[1+i3] = cs[i2]; + d[2+i3] = -cs[1+i2]; + d[3+i3] = -cs[1+i2]; + d[4+i3] = -cs[2+i2]; + d[5+i3] = -cs[2+i2]; + d[6+i3] = cs[3+i2]; + d[7+i3] = cs[3+i2]; + break; + + case 4: // +j +j +j +j + d[i3] = -cs[i2]; + d[1+i3] = cs[i2]; + d[2+i3] = -cs[1+i2]; + d[3+i3] = cs[1+i2]; + d[4+i3] = -cs[2+i2]; + d[5+i3] = cs[2+i2]; + d[6+i3] = -cs[3+i2]; + d[7+i3] = cs[3+i2]; + break; + + case 5: // +j -j +j -j + d[1+i3] = cs[i2]; + d[3+i3] = -cs[1+i2]; + d[5+i3] = cs[2+i2]; + d[7+i3] = -cs[3+i2]; + d[i3] = -cs[i2]; + d[2+i3] = cs[1+i2]; + d[4+i3] = -cs[2+i2]; + d[6+i3] = cs[3+i2]; + break; + + case 6: // +j +j -j -j + d[1+i3] = cs[i2]; + d[3+i3] = cs[1+i2]; + d[5+i3] = -cs[2+i2]; + d[7+i3] = -cs[3+i2]; + d[i3] = -cs[i2]; + d[2+i3] = -cs[1+i2]; + d[4+i3] = cs[2+i2]; + d[6+i3] = cs[3+i2]; + break; + + case 7: // +j -j -j +j + d[1+i3] = cs[i2]; + d[3+i3] = -cs[1+i2]; + d[5+i3] = -cs[2+i2]; + d[7+i3] = cs[3+i2]; + d[i3] = -cs[i2]; + d[2+i3] = cs[1+i2]; + d[4+i3] = cs[2+i2]; + d[6+i3] = -cs[3+i2]; + break; + + default: + AssertFatal(1==0,"phich_coding.c: Illegal PHICH Number\n"); + } // nseq_PHICH + } + +#ifdef DEBUG_PHICH + LOG_D(PHY,"PHICH =>"); + + for (i=0; i<24; i++) { + LOG_D(PHY,"%2d,",d[i]); + } + + LOG_D(PHY,"\n"); +#endif + // demodulation here + + + } else { // extended prefix + + // 6 output symbols + if ((ngroup_PHICH & 1) == 1) + dp = &d[4]; + else + dp = d; + + switch (nseq_PHICH) { + case 0: // +1 +1 + dp[0] = cs[0]; + dp[2] = cs[1]; + dp[8] = cs[2]; + dp[10] = cs[3]; + dp[16] = cs[4]; + dp[18] = cs[5]; + dp[1] = cs[0]; + dp[3] = cs[1]; + dp[9] = cs[2]; + dp[11] = cs[3]; + dp[17] = cs[4]; + dp[19] = cs[5]; + break; + + case 1: // +1 -1 + dp[0] = cs[0]; + dp[2] = -cs[1]; + dp[8] = cs[2]; + dp[10] = -cs[3]; + dp[16] = cs[4]; + dp[18] = -cs[5]; + dp[1] = cs[0]; + dp[3] = -cs[1]; + dp[9] = cs[2]; + dp[11] = -cs[3]; + dp[17] = cs[4]; + dp[19] = -cs[5]; + break; + + case 2: // +j +j + dp[1] = cs[0]; + dp[3] = cs[1]; + dp[9] = cs[2]; + dp[11] = cs[3]; + dp[17] = cs[4]; + dp[19] = cs[5]; + dp[0] = -cs[0]; + dp[2] = -cs[1]; + dp[8] = -cs[2]; + dp[10] = -cs[3]; + dp[16] = -cs[4]; + dp[18] = -cs[5]; + + break; + + case 3: // +j -j + dp[1] = cs[0]; + dp[3] = -cs[1]; + dp[9] = cs[2]; + dp[11] = -cs[3]; + dp[17] = cs[4]; + dp[19] = -cs[5]; + dp[0] = -cs[0]; + dp[2] = cs[1]; + dp[8] = -cs[2]; + dp[10] = cs[3]; + dp[16] = -cs[4]; + dp[18] = cs[5]; + break; + + default: + AssertFatal(1==0,"phich_coding.c: Illegal PHICH Number\n"); + } + } + + HI16 = 0; + + //#ifdef DEBUG_PHICH + + //#endif + /* + for (i=0;i<200;i++) + printf("re %d: %d %d\n",i,((int16_t*)&rxdataF_comp[0][i])[0],((int16_t*)&rxdataF_comp[0][i])[1]); + */ + for (phich_quad=0; phich_quad<3; phich_quad++) { + if (frame_parms->Ncp == 1) + reg_offset = (frame_parms->phich_reg[ngroup_PHICH][phich_quad]*4)+ (phich_quad*frame_parms->N_RB_DL*12); + else + reg_offset = (frame_parms->phich_reg[ngroup_PHICH][phich_quad]*4); + + // msg("\n[PUSCH 0]PHICH (RX) quad %d (%d)=>",phich_quad,reg_offset); + dp = &d[phich_quad*8];; + + for (i=0; i<8; i++) { + phich_d_ptr[i] = ((int16_t*)&rxdataF_comp[0][reg_offset])[i]; + +#ifdef DEBUG_PHICH + LOG_D(PHY,"%d,",((int16_t*)&rxdataF_comp[0][reg_offset])[i]); +#endif + + HI16 += (phich_d_ptr[i] * dp[i]); + } + } + +#ifdef DEBUG_PHICH + LOG_D(PHY,"\n"); + LOG_D(PHY,"HI16 %d\n",HI16); +#endif + + if (HI16>0) { //NACK + if (ue->ulsch_Msg3_active[eNB_id] == 1) { + LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received NAK (%d) nseq %d, ngroup %d\n", + ue->Mod_id,harq_pid, + proc->frame_rx, + subframe, + HI16, + nseq_PHICH, + ngroup_PHICH); + + ulsch->f_pusch += delta_PUSCH_acc[ulsch->harq_processes[harq_pid]->TPC]; + + LOG_D(PHY,"[PUSCH %d] AbsSubframe %d.%d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n", + harq_pid,proc->frame_rx,subframe,ulsch->f_pusch, + delta_PUSCH_acc[ulsch->harq_processes[harq_pid]->TPC], + ulsch->harq_processes[harq_pid]->TPC); + + + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; + // ulsch->harq_processes[harq_pid]->Ndi = 0; + ulsch->harq_processes[harq_pid]->round++; + ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; + + if (ulsch->harq_processes[harq_pid]->round>=ue->frame_parms.maxHARQ_Msg3Tx) { + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag =0; + ulsch->harq_processes[harq_pid]->status = SCH_IDLE; + // inform MAC that Msg3 transmission has failed + ue->ulsch_Msg3_active[eNB_id] = 0; + } + } else { +#ifdef UE_DEBUG_TRACE + 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, + HI16, + nseq_PHICH, + ngroup_PHICH, + ulsch->harq_processes[harq_pid]->round, + ulsch->Mlimit); +#endif + + // ulsch->harq_processes[harq_pid]->Ndi = 0; + ulsch->harq_processes[harq_pid]->round++; + + if ( ulsch->harq_processes[harq_pid]->round >= (ulsch->Mlimit - 1) ) + { + // this is last push re transmission + ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; + ulsch->O_RI = 0; + ulsch->O = 0; + ulsch->uci_format = HLC_subband_cqi_nopmi; + + // disable phich decoding since it is the last retransmission + ulsch->harq_processes[harq_pid]->status = SCH_IDLE; + + //ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; + //ulsch->harq_processes[harq_pid]->round = 0; + + //LOG_I(PHY,"PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid); + //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->Mlimit, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); + } + else + { + // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; + ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; + ulsch->O_RI = 0; + ulsch->O = 0; + ulsch->uci_format = HLC_subband_cqi_nopmi; + //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round); + } + } +#if T_TRACER + T(T_UE_PHY_ULSCH_UE_NACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ulsch->rnti), + T_INT(harq_pid)); +#endif + + } else { //ACK + if (ue->ulsch_Msg3_active[eNB_id] == 1) { + LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", + ue->Mod_id,harq_pid, + proc->frame_rx, + subframe, + HI16, + nseq_PHICH,ngroup_PHICH); + } else { +#ifdef UE_DEBUG_TRACE + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", + ue->Mod_id,harq_pid, + proc->frame_rx%1024, + subframe, HI16, + nseq_PHICH,ngroup_PHICH); +#endif + } + + // LOG_I(PHY,"[HARQ-UL harqId: %d] subframe_scheduling_flag = %d \n",harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag); + + // Incase of adaptive retransmission, PHICH is always decoded as ACK (at least with OAI-eNB) + // Workaround: + // rely only on DCI0 decoding and check if NDI has toggled + // save current harq_processes content in temporary struct + // harqId-8 corresponds to the temporary struct. In total we have 8 harq process(0 ..7) + 1 temporary harq process() + //ulsch->harq_processes[8] = ulsch->harq_processes[harq_pid]; + + + ulsch->harq_processes[harq_pid]->status = SCH_IDLE; + ulsch->harq_processes[harq_pid]->round = 0; + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; + // inform MAC? + ue->ulsch_Msg3_active[eNB_id] = 0; + +#if T_TRACER + T(T_UE_PHY_ULSCH_UE_ACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ulsch->rnti), + T_INT(harq_pid)); +#endif + + } + +} + diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..d944491b6399ead88d0c3d163f22c2e300787376 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c @@ -0,0 +1,844 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/sse_intrin.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" + +// Mask for identifying subframe for MBMS +#define MBSFN_TDD_SF3 0x80// for TDD +#define MBSFN_TDD_SF4 0x40 +#define MBSFN_TDD_SF7 0x20 +#define MBSFN_TDD_SF8 0x10 +#define MBSFN_TDD_SF9 0x08 + +#define MBSFN_FDD_SF1 0x80// for FDD +#define MBSFN_FDD_SF2 0x40 +#define MBSFN_FDD_SF3 0x20 +#define MBSFN_FDD_SF6 0x10 +#define MBSFN_FDD_SF7 0x08 +#define MBSFN_FDD_SF8 0x04 + + + +void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe) +{ + + unsigned int nsymb_pmch=12; + char fname[32],vname[32]; + int N_RB_DL=ue->frame_parms.N_RB_DL; + + sprintf(fname,"mch_rxF_ext0.m"); + sprintf(vname,"pmch_rxF_ext0"); + write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb_pmch,1,1); + sprintf(fname,"mch_ch_ext00.m"); + sprintf(vname,"pmch_ch_ext00"); + write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb_pmch,1,1); + /* + write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb_pmch,1,1); + write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb_pmch,1,1); + write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb_pmch,1,1); + write_output("dlsch%d_rho.m","dl_rho",pdsch_vars[eNB_id]->rho[0],12*N_RB_DL*nsymb_pmch,1,1); + */ + sprintf(fname,"mch_rxF_comp0.m"); + sprintf(vname,"pmch_rxF_comp0"); + write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb_pmch,1,1); + sprintf(fname,"mch_rxF_llr.m"); + sprintf(vname,"pmch_llr"); + write_output(fname,vname, ue->pdsch_vars_MCH[eNB_id]->llr[0],coded_bits_per_codeword,1,0); + sprintf(fname,"mch_mag1.m"); + sprintf(vname,"pmch_mag1"); + write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb_pmch,1,1); + sprintf(fname,"mch_mag2.m"); + sprintf(vname,"pmch_mag2"); + write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb_pmch,1,1); + + write_output("mch00_ch0.m","pmch00_ch0", + &(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), + ue->frame_parms.ofdm_symbol_size*12,1,1); + + write_output("rxsig_mch.m","rxs_mch", + &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti], + ue->frame_parms.samples_per_tti,1,1); + + /* + if (PHY_vars_eNB_g) + write_output("txsig_mch.m","txs_mch", + &PHY_vars_eNB_g[0][0]->common_vars.txdata[0][0][subframe*ue->frame_parms.samples_per_tti], + ue->frame_parms.samples_per_tti,1,1);*/ +} + + +void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id) +{ + + LTE_UE_DLSCH_t *dlsch = ue->dlsch_MCH[eNB_id]; + LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; + + // dlsch->rnti = M_RNTI; + dlsch->harq_processes[0]->mcs = mcs; + dlsch->harq_processes[0]->rvidx = rvidx; + // dlsch->harq_processes[0]->Ndi = ndi; + dlsch->harq_processes[0]->Nl = 1; + dlsch->harq_processes[0]->TBS = TBStable[get_I_TBS(dlsch->harq_processes[0]->mcs)][frame_parms->N_RB_DL-1]; + dlsch->current_harq_pid = 0; + dlsch->harq_processes[0]->nb_rb = frame_parms->N_RB_DL; + + switch(frame_parms->N_RB_DL) { + case 6: + dlsch->harq_processes[0]->rb_alloc_even[0] = 0x3f; + dlsch->harq_processes[0]->rb_alloc_odd[0] = 0x3f; + break; + + case 25: + dlsch->harq_processes[0]->rb_alloc_even[0] = 0x1ffffff; + dlsch->harq_processes[0]->rb_alloc_odd[0] = 0x1ffffff; + break; + + case 50: + dlsch->harq_processes[0]->rb_alloc_even[0] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_odd[0] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_even[1] = 0x3ffff; + dlsch->harq_processes[0]->rb_alloc_odd[1] = 0x3ffff; + break; + + case 100: + dlsch->harq_processes[0]->rb_alloc_even[0] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_odd[0] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_even[1] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_odd[1] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_even[2] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_odd[2] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc_even[3] = 0xf; + dlsch->harq_processes[0]->rb_alloc_odd[3] = 0xf; + break; + } +} + + + +void mch_extract_rbs(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + unsigned char subframe, + LTE_DL_FRAME_PARMS *frame_parms) +{ + + int pilots=0,i,j,offset,aarx; + + // printf("Extracting PMCH: symbol %d\n",symbol); + if ((symbol==2)|| + (symbol==10)) { + pilots = 1; + offset = 1; + } else if (symbol==6) { + pilots = 1; + offset = 0; + } + + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + + if (pilots==1) { + for (i=offset,j=0; i<frame_parms->N_RB_DL*6; i+=2,j++) { + /* printf("MCH with pilots: i %d, j %d => %d,%d\n",i,j, + *(int16_t*)&rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)], + *(int16_t*)(1+&rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)])); + */ + rxdataF_ext[aarx][j+symbol*(frame_parms->N_RB_DL*12)] = rxdataF[aarx][i+frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)]; + rxdataF_ext[aarx][(frame_parms->N_RB_DL*3)+j+symbol*(frame_parms->N_RB_DL*12)] = rxdataF[aarx][i+1+ (symbol*frame_parms->ofdm_symbol_size)]; + dl_ch_estimates_ext[aarx][j+symbol*(frame_parms->N_RB_DL*12)] = dl_ch_estimates[aarx][i+(symbol*frame_parms->ofdm_symbol_size)]; + dl_ch_estimates_ext[aarx][(frame_parms->N_RB_DL*3)+j+symbol*(frame_parms->N_RB_DL*12)] = dl_ch_estimates[aarx][i+(frame_parms->N_RB_DL*6)+(symbol*frame_parms->ofdm_symbol_size)]; + } + } else { + + memcpy((void*)&rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)], + (void*)&rxdataF[aarx][frame_parms->first_carrier_offset + (symbol*frame_parms->ofdm_symbol_size)], + frame_parms->N_RB_DL*24); + memcpy((void*)&rxdataF_ext[aarx][(frame_parms->N_RB_DL*6) + symbol*(frame_parms->N_RB_DL*12)], + (void*)&rxdataF[aarx][1 + (symbol*frame_parms->ofdm_symbol_size)], + frame_parms->N_RB_DL*24); + memcpy((void*)&dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)], + (void*)&dl_ch_estimates[aarx][(symbol*frame_parms->ofdm_symbol_size)], + frame_parms->N_RB_DL*48); + + } + + } + + + +} + +void mch_channel_level(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + int *avg, + uint8_t symbol, + unsigned short nb_rb) +{ + + int i,aarx,nre; +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch128,avg128; +#elif defined(__arm__) + int32x4_t avg128; +#endif + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { +#if defined(__x86_64__) || defined(__i386__) + //clear average level + avg128 = _mm_setzero_si128(); + // 5 is always a symbol with no pilots for both normal and extended prefix + + dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; +#elif defined(__arm__) + + +#endif + if ((symbol == 2) || (symbol == 6) || (symbol == 10)) + nre = (frame_parms->N_RB_DL*6); + else + nre = (frame_parms->N_RB_DL*12); + + for (i=0; i<(nre>>2); i++) { +#if defined(__x86_64__) || defined(__i386__) + avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); +#elif defined(__arm__) + +#endif + } + + avg[aarx] = (((int*)&avg128)[0] + + ((int*)&avg128)[1] + + ((int*)&avg128)[2] + + ((int*)&avg128)[3])/nre; + + // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + +void mch_channel_compensation(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **dl_ch_mag, + int **dl_ch_magb, + int **rxdataF_comp, + LTE_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + unsigned char mod_order, + unsigned char output_shift) +{ + + int aarx,nre,i; +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; +#elif defined(__arm__) + +#endif + if ((symbol == 2) || (symbol == 6) || (symbol == 10)) + nre = frame_parms->N_RB_DL*6; + else + nre = frame_parms->N_RB_DL*12; + +#if defined(__x86_64__) || defined(__i386__) + if (mod_order == 4) { + QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = _mm_setzero_si128(); + } else if (mod_order == 6) { + QAM_amp128 = _mm_set1_epi16(QAM64_n1); // + QAM_amp128b = _mm_set1_epi16(QAM64_n2); + } +#elif defined(__arm__) + +#endif + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + +#if defined(__x86_64__) || defined(__i386__) + + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128 = (__m128i *)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12]; +#elif defined(__arm__) + +#endif + + for (i=0; i<(nre>>2); i+=2) { + if (mod_order>2) { + // get channel amplitude if not QPSK +#if defined(__x86_64__) || defined(__i386__) + + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + + mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + // store channel magnitude here in a new field of dlsch + + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); + dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); + dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + + + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + + + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); + dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + +#elif defined(__arm__) + +#endif + } + +#if defined(__x86_64__) || defined(__i386__) + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); + + dl_ch128+=2; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + +#elif defined(__arm__) + +#endif + } + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif + +} + +void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + int **dl_ch_mag, + int **dl_ch_magb, + unsigned char symbol) +{ + + + int i; +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; +#elif defined(__arm__) + int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; +#endif + if (frame_parms->nb_antennas_rx>1) { + +#if defined(__x86_64__) || defined(__i386__) + + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12]; + +#elif defined(__arm__) + rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0 = (int16x8_t *)&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1 = (int16x8_t *)&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0b = (int16x8_t *)&dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1b = (int16x8_t *)&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12]; + +#endif + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0; i<frame_parms->N_RB_DL*3; i++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); + dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); + dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); +#elif defined(__arm__) + rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); + dl_ch_mag128_0[i] = vhaddq_s16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]); + dl_ch_mag128_0b[i] = vhaddq_s16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]); +#endif + } + } +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + +int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + short *dlsch_llr, + unsigned char symbol, + short **llr32p) +{ + + uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + uint32_t *llr32; + int i,len; + + if (symbol==2) { + llr32 = (uint32_t*)dlsch_llr; + } else { + llr32 = (uint32_t*)(*llr32p); + } + + AssertFatal(llr32!=NULL,"dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32); + + + if ((symbol==2) || (symbol==6) || (symbol==10)) { + len = frame_parms->N_RB_DL*6; + } else { + len = frame_parms->N_RB_DL*12; + } + + // printf("dlsch_qpsk_llr: symbol %d,len %d,pbch_pss_sss_adjust %d\n",symbol,len,pbch_pss_sss_adjust); + for (i=0; i<len; i++) { + *llr32 = *rxF; + rxF++; + llr32++; + } + + *llr32p = (short *)llr32; + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif + + return(0); +} + +//---------------------------------------------------------------------------------------------- +// 16-QAM +//---------------------------------------------------------------------------------------------- + +void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + short *dlsch_llr, + int **dl_ch_mag, + unsigned char symbol, + int16_t **llr32p) +{ + +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + __m128i *ch_mag; + __m128i llr128[2],xmm0; + uint32_t *llr32; +#elif defined(__arm__) + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + int16x8_t *ch_mag; + int16x8_t llr128[2],xmm0; + int16_t *llr16; +#endif + int i,len; + unsigned char len_mod4=0; + +#if defined(__x86_64__) || defined(__i386__) + if (symbol==2) { + llr32 = (uint32_t*)dlsch_llr; + } else { + llr32 = (uint32_t*)*llr32p; + } +#elif defined(__arm__) + if (symbol==2) { + llr16 = (int16_t*)dlsch_llr; + } else { + llr16 = (int16_t*)*llr32p; + } +#endif +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; +#endif + if ((symbol==2) || (symbol==6) || (symbol==10)) { + len = frame_parms->N_RB_DL*6; + } else { + len = frame_parms->N_RB_DL*12; + } + + + + // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE) + if (symbol==2) + *llr32p = dlsch_llr + (len<<2); + else + *llr32p += (len<<2); + + len_mod4 = len&3; + len>>=2; // length in quad words (4 REs) + len+=(len_mod4==0 ? 0 : 1); + + for (i=0; i<len; i++) { + +#if defined(__x86_64__) || defined(__i386__) + xmm0 = _mm_abs_epi16(rxF[i]); + xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); + + // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2 + llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); + llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); + llr32[0] = ((uint32_t *)&llr128[0])[0]; + llr32[1] = ((uint32_t *)&llr128[0])[1]; + llr32[2] = ((uint32_t *)&llr128[0])[2]; + llr32[3] = ((uint32_t *)&llr128[0])[3]; + llr32[4] = ((uint32_t *)&llr128[1])[0]; + llr32[5] = ((uint32_t *)&llr128[1])[1]; + llr32[6] = ((uint32_t *)&llr128[1])[2]; + llr32[7] = ((uint32_t *)&llr128[1])[3]; + llr32+=8; + +#elif defined(__arm__) + xmm0 = vabsq_s16(rxF[i]); + xmm0 = vsubq_s16(ch_mag[i],xmm0); + + // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2 + + llr16[0] = vgetq_lane_s16(rxF[i],0); + llr16[1] = vgetq_lane_s16(xmm0,0); + llr16[2] = vgetq_lane_s16(rxF[i],1); + llr16[3] = vgetq_lane_s16(xmm0,1); + llr16[4] = vgetq_lane_s16(rxF[i],2); + llr16[5] = vgetq_lane_s16(xmm0,2); + llr16[6] = vgetq_lane_s16(rxF[i],2); + llr16[7] = vgetq_lane_s16(xmm0,3); + llr16[8] = vgetq_lane_s16(rxF[i],4); + llr16[9] = vgetq_lane_s16(xmm0,4); + llr16[10] = vgetq_lane_s16(rxF[i],5); + llr16[11] = vgetq_lane_s16(xmm0,5); + llr16[12] = vgetq_lane_s16(rxF[i],6); + llr16[13] = vgetq_lane_s16(xmm0,6); + llr16[14] = vgetq_lane_s16(rxF[i],7); + llr16[15] = vgetq_lane_s16(xmm0,7); + llr16+=16; +#endif + + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + +//---------------------------------------------------------------------------------------------- +// 64-QAM +//---------------------------------------------------------------------------------------------- + +void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + short *dlsch_llr, + int **dl_ch_mag, + int **dl_ch_magb, + unsigned char symbol, + short **llr_save) +{ + +#if defined(__x86_64__) || defined(__i386__) + __m128i xmm1,xmm2,*ch_mag,*ch_magb; + __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; +#elif defined(__arm__) + int16x8_t xmm1,xmm2,*ch_mag,*ch_magb; + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; +#endif + + int i,len,len2; + // int j=0; + unsigned char len_mod4; + short *llr; + int16_t *llr2; + + if (symbol==2) + llr = dlsch_llr; + else + llr = *llr_save; + +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; + ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; + ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; +#endif + if ((symbol==2) || (symbol==6) || (symbol==10)) { + len = frame_parms->N_RB_DL*6; + } else { + len = frame_parms->N_RB_DL*12; + } + + + llr2 = llr; + llr += (len*6); + + len_mod4 =len&3; + len2=len>>2; // length in quad words (4 REs) + len2+=(len_mod4?0:1); + + + for (i=0; i<len2; i++) { +#if defined(__x86_64__) || defined(__i386__) + xmm1 = _mm_abs_epi16(rxF[i]); + xmm1 = _mm_subs_epi16(ch_mag[i],xmm1); + xmm2 = _mm_abs_epi16(xmm1); + xmm2 = _mm_subs_epi16(ch_magb[i],xmm2); +#elif defined(__arm__) + xmm1 = vabsq_s16(rxF[i]); + xmm1 = vsubq_s16(ch_mag[i],xmm1); + xmm2 = vabsq_s16(xmm1); + xmm2 = vsubq_s16(ch_magb[i],xmm2); +#endif + + /* + printf("pmch i: %d => mag (%d,%d) (%d,%d)\n",i,((short *)&ch_mag[i])[0],((short *)&ch_magb[i])[0], + ((short *)&rxF[i])[0],((short *)&rxF[i])[1]); + */ + // loop over all LLRs in quad word (24 coded bits) + /* + for (j=0;j<8;j+=2) { + llr2[0] = ((short *)&rxF[i])[j]; + llr2[1] = ((short *)&rxF[i])[j+1]; + llr2[2] = _mm_extract_epi16(xmm1,j); + llr2[3] = _mm_extract_epi16(xmm1,j+1);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,j);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,j+1);//((short *)&xmm2)[j+1]; + + llr2+=6; + } + */ + llr2[0] = ((short *)&rxF[i])[0]; + llr2[1] = ((short *)&rxF[i])[1]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,0); + llr2[3] = _mm_extract_epi16(xmm1,1);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,0);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,1);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,0); + llr2[3] = vgetq_lane_s16(xmm1,1);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,0);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,1);//((short *)&xmm2)[j+1]; +#endif + + llr2+=6; + llr2[0] = ((short *)&rxF[i])[2]; + llr2[1] = ((short *)&rxF[i])[3]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,2); + llr2[3] = _mm_extract_epi16(xmm1,3);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,2);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,3);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,2); + llr2[3] = vgetq_lane_s16(xmm1,3);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,2);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,3);//((short *)&xmm2)[j+1]; +#endif + llr2+=6; + llr2[0] = ((short *)&rxF[i])[4]; + llr2[1] = ((short *)&rxF[i])[5]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,4); + llr2[3] = _mm_extract_epi16(xmm1,5);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,4);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,5);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,4); + llr2[3] = vgetq_lane_s16(xmm1,5);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,4);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,5);//((short *)&xmm2)[j+1]; +#endif + llr2+=6; + llr2[0] = ((short *)&rxF[i])[6]; + llr2[1] = ((short *)&rxF[i])[7]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,6); + llr2[3] = _mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,6); + llr2[3] = vgetq_lane_s16(xmm1,7);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,6);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,7);//((short *)&xmm2)[j+1]; +#endif + llr2+=6; + } + + *llr_save = llr; +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + +int avg_pmch[4]; +int rx_pmch(PHY_VARS_UE *ue, + unsigned char eNB_id, + uint8_t subframe, + unsigned char symbol) +{ + + LTE_UE_COMMON *common_vars = &ue->common_vars; + LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[eNB_id]; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id]; + int avgs,aarx; + + //printf("*********************mch: symbol %d\n",symbol); + + mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, + common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], + pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + symbol, + subframe, + frame_parms); + + if (symbol == 2) { + mch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avg_pmch, + symbol, + frame_parms->N_RB_DL); + } + + avgs = 0; + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) + avgs = cmax(avgs,avg_pmch[aarx]); + + if (get_Qm(dlsch[0]->harq_processes[0]->mcs)==2) + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) ;// + 2 + else + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2); // + 5;// + 2 + + mch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + pdsch_vars[eNB_id]->rxdataF_comp0, + frame_parms, + symbol, + get_Qm(dlsch[0]->harq_processes[0]->mcs), + pdsch_vars[eNB_id]->log2_maxh); + + + if (frame_parms->nb_antennas_rx > 1) + mch_detection_mrc(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + symbol); + + switch (get_Qm(dlsch[0]->harq_processes[0]->mcs)) { + case 2 : + mch_qpsk_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + symbol, + pdsch_vars[eNB_id]->llr128); + break; + + case 4: + mch_16qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + pdsch_vars[eNB_id]->dl_ch_mag0, + symbol, + pdsch_vars[eNB_id]->llr128); + break; + + case 6: + mch_64qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + symbol, + pdsch_vars[eNB_id]->llr128); + break; + } + + return(0); +} + diff --git a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..02d0c9aa4f51a78bfcb8bacb4f319d0294086559 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c @@ -0,0 +1,534 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/prach_ue.c + * \brief Top-level routines for decoding the PRACH physical channel V8.6 2009-03 + * \author R. Knopp + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#include "PHY/sse_intrin.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +//#include "prach.h" +#include "PHY/LTE_TRANSPORT/if4_tools.h" + +#include "SCHED_UE/sched_UE.h" +#include "SCHED/sched_common_extern.h" +#include "UTIL/LOG/vcd_signal_dumper.h" + +#include "../LTE_TRANSPORT/prach_extern.h" + +int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ) +{ + + lte_frame_type_t frame_type = ue->frame_parms.frame_type; + //uint8_t tdd_config = ue->frame_parms.tdd_config; + uint16_t rootSequenceIndex = ue->frame_parms.prach_config_common.rootSequenceIndex; + uint8_t prach_ConfigIndex = ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; + uint8_t Ncs_config = ue->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; + uint8_t restricted_set = ue->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag; + //uint8_t n_ra_prboffset = ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; + uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex; + uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index; + int16_t *prachF = ue->prach_vars[eNB_id]->prachF; + static int16_t prach_tmp[45600*2] __attribute__((aligned(32))); + int16_t *prach = prach_tmp; + int16_t *prach2; + int16_t amp = ue->prach_vars[eNB_id]->amp; + int16_t Ncp; + uint8_t n_ra_prb; + uint16_t NCS; + uint16_t *prach_root_sequence_map; + uint16_t preamble_offset,preamble_shift; + uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar; + uint16_t d_start,numshift; + + uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type); + //uint8_t Nsp=2; + //uint8_t f_ra,t1_ra; + uint16_t N_ZC = (prach_fmt<4)?839:139; + uint8_t not_found; + int k; + int16_t *Xu; + uint16_t u; + int32_t Xu_re,Xu_im; + uint16_t offset,offset2; + int prach_start; + int i, prach_len; + uint16_t first_nonzero_root_idx=0; + +#if defined(EXMIMO) || defined(OAI_USRP) + prach_start = (ue->rx_offset+subframe*ue->frame_parms.samples_per_tti-ue->hw_timing_advance-ue->N_TA_offset); +#ifdef PRACH_DEBUG + LOG_I(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 + + if (prach_start<0) + prach_start+=(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + + if (prach_start>=(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) + prach_start-=(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + +#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 + + + // First compute physical root sequence + if (restricted_set == 0) { + AssertFatal(Ncs_config <= 15, + "[PHY] FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", Ncs_config ); + NCS = NCS_unrestricted[Ncs_config]; + } else { + AssertFatal(Ncs_config <= 14, + "[PHY] FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", Ncs_config ); + NCS = NCS_restricted[Ncs_config]; + } + + n_ra_prb = get_prach_prb_offset(&(ue->frame_parms), + ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset, + tdd_mapindex, Nf); + prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4; + + /* + // this code is not part of get_prach_prb_offset + if (frame_type == TDD) { // TDD + + if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) { + LOG_E( PHY, "[PHY][UE %"PRIu8"] Illegal prach_ConfigIndex %"PRIu8" for ", ue->Mod_id, prach_ConfigIndex ); + } + + // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211) + f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra; + + if (prach_fmt < 4) { + if ((f_ra&1) == 0) { + n_ra_prb = n_ra_prboffset + 6*(f_ra>>1); + } else { + n_ra_prb = ue->frame_parms.N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1); + } + } else { + if ((tdd_config >2) && (tdd_config<6)) + Nsp = 2; + + t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; + + if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) { + n_ra_prb = 6*f_ra; + } else { + n_ra_prb = ue->frame_parms.N_RB_UL - 6*(f_ra+1); + } + } + } + */ + + // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index + preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); + + if (restricted_set == 0) { + // This is the \nu corresponding to the preamble index + preamble_shift = (NCS==0)? 0 : (preamble_index % (N_ZC/NCS)); + preamble_shift *= NCS; + } else { // This is the high-speed case + +#ifdef PRACH_DEBUG + LOG_I(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config); +#endif + + not_found = 1; + preamble_index0 = preamble_index; + // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this + // preamble index and find the corresponding cyclic shift + preamble_offset = 0; // relative rootSequenceIndex; + + while (not_found == 1) { + // current root depending on rootSequenceIndex and preamble_offset + int index = (rootSequenceIndex + preamble_offset) % N_ZC; + + if (prach_fmt<4) { + // prach_root_sequence_map points to prach_root_sequence_map0_3 + DevAssert( index < sizeof(prach_root_sequence_map0_3) / sizeof(prach_root_sequence_map0_3[0]) ); + } else { + // prach_root_sequence_map points to prach_root_sequence_map4 + DevAssert( index < sizeof(prach_root_sequence_map4) / sizeof(prach_root_sequence_map4[0]) ); + } + + u = prach_root_sequence_map[index]; + + uint16_t n_group_ra = 0; + + if ( (du[u]<(N_ZC/3)) && (du[u]>=NCS) ) { + n_shift_ra = du[u]/NCS; + d_start = (du[u]<<1) + (n_shift_ra * NCS); + n_group_ra = N_ZC/d_start; + n_shift_ra_bar = max(0,(N_ZC-(du[u]<<1)-(n_group_ra*d_start))/N_ZC); + } else if ( (du[u]>=(N_ZC/3)) && (du[u]<=((N_ZC - NCS)>>1)) ) { + n_shift_ra = (N_ZC - (du[u]<<1))/NCS; + d_start = N_ZC - (du[u]<<1) + (n_shift_ra * NCS); + n_group_ra = du[u]/d_start; + n_shift_ra_bar = min(n_shift_ra,max(0,(du[u]- (n_group_ra*d_start))/NCS)); + } else { + n_shift_ra = 0; + n_shift_ra_bar = 0; + } + + // This is the number of cyclic shifts for the current root u + numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar; + + if (numshift>0 && preamble_index0==preamble_index) + first_nonzero_root_idx = preamble_offset; + + if (preamble_index0 < numshift) { + not_found = 0; + preamble_shift = (d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS); + + } else { // skip to next rootSequenceIndex and recompute parameters + preamble_offset++; + preamble_index0 -= numshift; + } + } + } + + // now generate PRACH signal +#ifdef PRACH_DEBUG + + if (NCS>0) + LOG_I(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, NCS %d (NCS_config %d, N_ZC/NCS %d) n_ra_prb %d: Preamble_offset %d, Preamble_shift %d\n", + rootSequenceIndex,preamble_index,NCS,Ncs_config,N_ZC/NCS,n_ra_prb, + preamble_offset,preamble_shift); + +#endif + + // nsymb = (frame_parms->Ncp==0) ? 14:12; + // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*subframe*nsymb; + + k = (12*n_ra_prb) - 6*ue->frame_parms.N_RB_UL; + + if (k<0) + k+=ue->frame_parms.ofdm_symbol_size; + + k*=12; + k+=13; + + Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx]; + + /* + k+=(12*ue->frame_parms.first_carrier_offset); + if (k>(12*ue->frame_parms.ofdm_symbol_size)) + k-=(12*ue->frame_parms.ofdm_symbol_size); + */ + k*=2; + + switch (ue->frame_parms.N_RB_UL) { + case 6: + memset((void*)prachF,0,4*1536); + break; + + case 15: + memset((void*)prachF,0,4*3072); + break; + + case 25: + memset((void*)prachF,0,4*6144); + break; + + case 50: + memset((void*)prachF,0,4*12288); + break; + + case 75: + memset((void*)prachF,0,4*18432); + break; + + case 100: + if (ue->frame_parms.threequarter_fs == 0) + memset((void*)prachF,0,4*24576); + else + memset((void*)prachF,0,4*18432); + break; + } + + for (offset=0,offset2=0; offset<N_ZC; offset++,offset2+=preamble_shift) { + + if (offset2 >= N_ZC) + offset2 -= N_ZC; + + Xu_re = (((int32_t)Xu[offset<<1]*amp)>>15); + Xu_im = (((int32_t)Xu[1+(offset<<1)]*amp)>>15); + prachF[k++]= ((Xu_re*ru[offset2<<1]) - (Xu_im*ru[1+(offset2<<1)]))>>15; + prachF[k++]= ((Xu_im*ru[offset2<<1]) + (Xu_re*ru[1+(offset2<<1)]))>>15; + + if (k==(12*2*ue->frame_parms.ofdm_symbol_size)) + k=0; + } + + switch (prach_fmt) { + case 0: + Ncp = 3168; + break; + + case 1: + case 3: + Ncp = 21024; + break; + + case 2: + Ncp = 6240; + break; + + case 4: + Ncp = 448; + break; + + default: + Ncp = 3168; + break; + } + + switch (ue->frame_parms.N_RB_UL) { + case 6: + Ncp>>=4; + prach+=4; // makes prach2 aligned to 128-bit + break; + + case 15: + Ncp>>=3; + break; + + case 25: + Ncp>>=2; + break; + + case 50: + Ncp>>=1; + break; + + case 75: + Ncp=(Ncp*3)>>2; + break; + } + + if (ue->frame_parms.threequarter_fs == 1) + Ncp=(Ncp*3)>>2; + + prach2 = prach+(Ncp<<1); + + // do IDFT + switch (ue->frame_parms.N_RB_UL) { + case 6: + if (prach_fmt == 4) { + idft256(prachF,prach2,1); + memmove( prach, prach+512, Ncp<<2 ); + prach_len = 256+Ncp; + } else { + idft1536(prachF,prach2,1); + memmove( prach, prach+3072, Ncp<<2 ); + prach_len = 1536+Ncp; + + if (prach_fmt>1) { + memmove( prach2+3072, prach2, 6144 ); + prach_len = 2*1536+Ncp; + } + } + + break; + + case 15: + if (prach_fmt == 4) { + idft512(prachF,prach2,1); + //TODO: account for repeated format in dft output + memmove( prach, prach+1024, Ncp<<2 ); + prach_len = 512+Ncp; + } else { + idft3072(prachF,prach2); + memmove( prach, prach+6144, Ncp<<2 ); + prach_len = 3072+Ncp; + + if (prach_fmt>1) { + memmove( prach2+6144, prach2, 12288 ); + prach_len = 2*3072+Ncp; + } + } + + break; + + case 25: + default: + if (prach_fmt == 4) { + idft1024(prachF,prach2,1); + memmove( prach, prach+2048, Ncp<<2 ); + prach_len = 1024+Ncp; + } else { + idft6144(prachF,prach2); + /*for (i=0;i<6144*2;i++) + prach2[i]<<=1;*/ + memmove( prach, prach+12288, Ncp<<2 ); + prach_len = 6144+Ncp; + + if (prach_fmt>1) { + memmove( prach2+12288, prach2, 24576 ); + prach_len = 2*6144+Ncp; + } + } + + break; + + case 50: + if (prach_fmt == 4) { + idft2048(prachF,prach2,1); + memmove( prach, prach+4096, Ncp<<2 ); + prach_len = 2048+Ncp; + } else { + idft12288(prachF,prach2); + memmove( prach, prach+24576, Ncp<<2 ); + prach_len = 12288+Ncp; + + if (prach_fmt>1) { + memmove( prach2+24576, prach2, 49152 ); + prach_len = 2*12288+Ncp; + } + } + + break; + + case 75: + if (prach_fmt == 4) { + idft3072(prachF,prach2); + //TODO: account for repeated format in dft output + memmove( prach, prach+6144, Ncp<<2 ); + prach_len = 3072+Ncp; + } else { + idft18432(prachF,prach2); + memmove( prach, prach+36864, Ncp<<2 ); + prach_len = 18432+Ncp; + + if (prach_fmt>1) { + memmove( prach2+36834, prach2, 73728 ); + prach_len = 2*18432+Ncp; + } + } + + break; + + case 100: + if (ue->frame_parms.threequarter_fs == 0) { + if (prach_fmt == 4) { + idft4096(prachF,prach2,1); + memmove( prach, prach+8192, Ncp<<2 ); + prach_len = 4096+Ncp; + } else { + idft24576(prachF,prach2); + memmove( prach, prach+49152, Ncp<<2 ); + prach_len = 24576+Ncp; + + if (prach_fmt>1) { + memmove( prach2+49152, prach2, 98304 ); + prach_len = 2* 24576+Ncp; + } + } + } + else { + if (prach_fmt == 4) { + idft3072(prachF,prach2); + //TODO: account for repeated format in dft output + memmove( prach, prach+6144, Ncp<<2 ); + prach_len = 3072+Ncp; + } else { + idft18432(prachF,prach2); + memmove( prach, prach+36864, Ncp<<2 ); + prach_len = 18432+Ncp; + printf("Generated prach for 100 PRB, 3/4 sampling\n"); + if (prach_fmt>1) { + memmove( prach2+36834, prach2, 73728 ); + prach_len = 2*18432+Ncp; + } + } + } + + break; + } + + //LOG_I(PHY,"prach_len=%d\n",prach_len); + + AssertFatal(prach_fmt<4, + "prach_fmt4 not fully implemented" ); +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + int j; + int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*ue->frame_parms.samples_per_tti; + LOG_I( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); + + for (i=prach_start,j=0; i<min(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) { + ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; + ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; + } + + for (i=0; i<overflow; i++,j++) { + ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; + ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; + } +#if defined(EXMIMO) + // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on + for (k=prach_start - (ue->frame_parms.samples_per_tti>>1) ; k<prach_start ; k++) { + if (k<0) + ue->common_vars.txdata[0][k+ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; + else if (k>(ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) + ue->common_vars.txdata[0][k-ue->frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; + else + ue->common_vars.txdata[0][k] &= 0xFFFEFFFE; + } +#endif +#else + + for (i=0; i<prach_len; i++) { + ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i] = prach[2*i]; + ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1]; + } + +#endif + + + +#if defined(PRACH_WRITE_OUTPUT_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 ); +} + diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pucch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pucch_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..c3bbd0fb1caafe229a22a5660e7991385f663515 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/pucch_ue.c @@ -0,0 +1,843 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/pucch.c +* \brief Top-level routines for generating and decoding the PUCCH physical channel V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/LTE_REFSIG/lte_refsig.h" + +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" + +#include "T.h" + +#include "../LTE_TRANSPORT/pucch_extern.h" + + + +void generate_pucch1x(int32_t **txdataF, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t ncs_cell[20][7], + PUCCH_FMT_t fmt, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint16_t n1_pucch, + uint8_t shortened_format, + uint8_t *payload, + int16_t amp, + uint8_t subframe) +{ + + uint32_t u,v,n; + uint32_t z[12*14],*zptr; + int16_t d0; + uint8_t ns,N_UL_symb,nsymb,n_oc,n_oc0,n_oc1; + uint8_t c = (frame_parms->Ncp==0) ? 3 : 2; + uint16_t nprime,nprime0,nprime1; + uint16_t i,j,re_offset,thres,h; + uint8_t Nprime_div_deltaPUCCH_Shift,Nprime,d; + uint8_t m,l,refs; + uint8_t n_cs,S,alpha_ind,rem; + int16_t tmp_re,tmp_im,ref_re,ref_im,W_re=0,W_im=0; + int32_t *txptr; + uint32_t symbol_offset; + + uint8_t deltaPUCCH_Shift = frame_parms->pucch_config_common.deltaPUCCH_Shift; + uint8_t NRB2 = frame_parms->pucch_config_common.nRB_CQI; + uint8_t Ncs1 = frame_parms->pucch_config_common.nCS_AN; + uint8_t Ncs1_div_deltaPUCCH_Shift = Ncs1/deltaPUCCH_Shift; + + LOG_D(PHY,"generate_pucch Start [deltaPUCCH_Shift %d, NRB2 %d, Ncs1_div_deltaPUCCH_Shift %d, n1_pucch %d]\n", deltaPUCCH_Shift, NRB2, Ncs1_div_deltaPUCCH_Shift,n1_pucch); + + + uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30; + uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30; + uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + + if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) { + printf("[PHY] generate_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift); + return; + } + + if (Ncs1_div_deltaPUCCH_Shift > 7) { + printf("[PHY] generate_pucch: Illegal Ncs1_div_deltaPUCCH_Shift %d (should be 0...7)\n",Ncs1_div_deltaPUCCH_Shift); + return; + } + + zptr = z; + thres = (c*Ncs1_div_deltaPUCCH_Shift); + Nprime_div_deltaPUCCH_Shift = (n1_pucch < thres) ? Ncs1_div_deltaPUCCH_Shift : (12/deltaPUCCH_Shift); + Nprime = Nprime_div_deltaPUCCH_Shift * deltaPUCCH_Shift; + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH: cNcs1/deltaPUCCH_Shift %d, Nprime %d, n1_pucch %d\n",thres,Nprime,n1_pucch); +#endif + + LOG_D(PHY,"[PHY] PUCCH: n1_pucch %d, thres %d Ncs1_div_deltaPUCCH_Shift %d (12/deltaPUCCH_Shift) %d Nprime_div_deltaPUCCH_Shift %d \n", + n1_pucch, thres, Ncs1_div_deltaPUCCH_Shift, (int)(12/deltaPUCCH_Shift), Nprime_div_deltaPUCCH_Shift); + LOG_D(PHY,"[PHY] PUCCH: deltaPUCCH_Shift %d, Nprime %d\n",deltaPUCCH_Shift,Nprime); + + + N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6; + + if (n1_pucch < thres) + nprime0=n1_pucch; + else + nprime0 = (n1_pucch - thres)%(12*c/deltaPUCCH_Shift); + + if (n1_pucch >= thres) + nprime1= ((c*(nprime0+1))%((12*c/deltaPUCCH_Shift)+1))-1; + else { + d = (frame_parms->Ncp==0) ? 2 : 0; + h= (nprime0+d)%(c*Nprime_div_deltaPUCCH_Shift); +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH: h %d, d %d\n",h,d); +#endif + nprime1 = (h/c) + (h%c)*Nprime_div_deltaPUCCH_Shift; + } + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH: nprime0 %d nprime1 %d, %s, payload (%d,%d)\n",nprime0,nprime1,pucch_format_string[fmt],payload[0],payload[1]); +#endif + + n_oc0 = nprime0/Nprime_div_deltaPUCCH_Shift; + + if (frame_parms->Ncp==1) + n_oc0<<=1; + + n_oc1 = nprime1/Nprime_div_deltaPUCCH_Shift; + + if (frame_parms->Ncp==1) // extended CP + n_oc1<<=1; + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH: noc0 %d noc1 %d\n",n_oc0,n_oc1); +#endif + + nprime=nprime0; + n_oc =n_oc0; + + // loop over 2 slots + for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) { + + if ((nprime&1) == 0) + S=0; // 1 + else + S=1; // j + + //loop over symbols in slot + for (l=0; l<N_UL_symb; l++) { + // Compute n_cs (36.211 p. 18) + n_cs = ncs_cell[ns][l]; + + if (frame_parms->Ncp==0) { // normal CP + n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc%deltaPUCCH_Shift))%Nprime)%12; + } else { + n_cs = ((uint16_t)n_cs + (nprime*deltaPUCCH_Shift + (n_oc>>1))%Nprime)%12; + } + + + refs=0; + + // Comput W_noc(m) (36.211 p. 19) + if ((ns==(1+(subframe<<1))) && (shortened_format==1)) { // second slot and shortened format + + if (l<2) { // data + W_re=W3_re[n_oc][l]; + W_im=W3_im[n_oc][l]; + } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP + W_re=W3_re[n_oc][l-2]; + W_im=W3_im[n_oc][l-2]; + refs=1; + } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP + W_re=W4[n_oc][l-2]; + W_im=0; + refs=1; + } else if ((l>=N_UL_symb-2)) { // data + W_re=W3_re[n_oc][l-N_UL_symb+4]; + W_im=W3_im[n_oc][l-N_UL_symb+4]; + } + } else { + if (l<2) { // data + W_re=W4[n_oc][l]; + W_im=0; + } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP + W_re=W3_re[n_oc][l-2]; + W_im=W3_im[n_oc][l-2]; + refs=1; + } else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP + W_re=W4[n_oc][l-2]; + W_im=0; + refs=1; + } else if ((l>=N_UL_symb-2)) { // data + W_re=W4[n_oc][l-N_UL_symb+4]; + W_im=0; + } + } + + // multiply W by S(ns) (36.211 p.17). only for data, reference symbols do not have this factor + if ((S==1)&&(refs==0)) { + tmp_re = W_re; + W_re = -W_im; + W_im = tmp_re; + } + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH: ncs[%d][%d]=%d, W_re %d, W_im %d, S %d, refs %d\n",ns,l,n_cs,W_re,W_im,S,refs); +#endif + alpha_ind=0; + // compute output sequence + + for (n=0; n<12; n++) { + + // this is r_uv^alpha(n) + tmp_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); + tmp_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); + + // this is S(ns)*w_noc(m)*r_uv^alpha(n) + ref_re = (tmp_re*W_re - tmp_im*W_im)>>15; + ref_im = (tmp_re*W_im + tmp_im*W_re)>>15; + + if ((l<2)||(l>=(N_UL_symb-2))) { //these are PUCCH data symbols + switch (fmt) { + case pucch_format1: //OOK 1-bit + + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15; + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15; + + break; + + case pucch_format1a: //BPSK 1-bit + d0 = (payload[0]&1)==0 ? amp : -amp; + ((int16_t *)&zptr[n])[0] = ((int32_t)d0*ref_re)>>15; + ((int16_t *)&zptr[n])[1] = ((int32_t)d0*ref_im)>>15; + // printf("d0 %d\n",d0); + break; + + case pucch_format1b: //QPSK 2-bits (Table 5.4.1-1 from 36.211, pg. 18) + if (((payload[0]&1)==0) && ((payload[1]&1)==0)) {// 1 + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15; + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15; + } else if (((payload[0]&1)==0) && ((payload[1]&1)==1)) { // -j + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_im)>>15; + ((int16_t *)&zptr[n])[1] = (-(int32_t)amp*ref_re)>>15; + } else if (((payload[0]&1)==1) && ((payload[1]&1)==0)) { // j + ((int16_t *)&zptr[n])[0] = (-(int32_t)amp*ref_im)>>15; + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_re)>>15; + } else { // -1 + ((int16_t *)&zptr[n])[0] = (-(int32_t)amp*ref_re)>>15; + ((int16_t *)&zptr[n])[1] = (-(int32_t)amp*ref_im)>>15; + } + + break; + case pucch_format1b_csA2: + case pucch_format1b_csA3: + case pucch_format1b_csA4: + AssertFatal(1==0,"PUCCH format 1b_csX not supported yet\n"); + break; + case pucch_format2: + case pucch_format2a: + case pucch_format2b: + AssertFatal(1==0,"should not go here\n"); + break; + + case pucch_format3: + fprintf(stderr, "PUCCH format 3 not handled\n"); + abort(); + } // switch fmt + } else { // These are PUCCH reference symbols + + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re)>>15; + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im)>>15; + // printf("ref\n"); + } + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH subframe %d z(%d,%d) => %d,%d, alpha(%d) => %d,%d\n",subframe,l,n,((int16_t *)&zptr[n])[0],((int16_t *)&zptr[n])[1], + alpha_ind,alpha_re[alpha_ind],alpha_im[alpha_ind]); +#endif + alpha_ind = (alpha_ind + n_cs)%12; + } // n + + zptr+=12; + } // l + + nprime=nprime1; + n_oc =n_oc1; + } // ns + + rem = ((((12*Ncs1_div_deltaPUCCH_Shift)>>3)&7)>0) ? 1 : 0; + + m = (n1_pucch < thres) ? NRB2 : (((n1_pucch-thres)/(12*c/deltaPUCCH_Shift))+NRB2+((deltaPUCCH_Shift*Ncs1_div_deltaPUCCH_Shift)>>3)+rem); + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH: m %d\n",m); +#endif + nsymb = N_UL_symb<<1; + + //for (j=0,l=0;l<(nsymb-1);l++) { + for (j=0,l=0; l<(nsymb); l++) { + if ((l<(nsymb>>1)) && ((m&1) == 0)) + re_offset = (m*6) + frame_parms->first_carrier_offset; + else if ((l<(nsymb>>1)) && ((m&1) == 1)) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else if ((m&1) == 0) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else + re_offset = ((m-1)*6) + frame_parms->first_carrier_offset; + + if (re_offset > frame_parms->ofdm_symbol_size) + re_offset -= (frame_parms->ofdm_symbol_size); + + symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb)); + txptr = &txdataF[0][symbol_offset]; + + for (i=0; i<12; i++,j++) { + txptr[re_offset++] = z[j]; + + if (re_offset==frame_parms->ofdm_symbol_size) + re_offset = 0; + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]); +#endif + } + } + +} + + + + +inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) __attribute__((always_inline)); +inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) { + + uint32_t x1, x2, s=0; + int i; + uint8_t c; + + x2 = (rnti) + ((uint32_t)(1+subframe)<<16)*(1+(fp->Nid_cell<<1)); //this is c_init in 36.211 Sec 6.3.1 + s = lte_gold_generic(&x1, &x2, 1); + for (i=0;i<19;i++) { + c = (uint8_t)((s>>i)&1); + btilde[i] = (((B>>i)&1) ^ c); + } +} + +inline void pucch2x_modulation(uint8_t *btilde,int16_t *d,int16_t amp) __attribute__((always_inline)); +inline void pucch2x_modulation(uint8_t *btilde,int16_t *d,int16_t amp) { + + int i; + + for (i=0;i<20;i++) + d[i] = btilde[i] == 1 ? -amp : amp; + +} + + + +uint32_t pucch_code[13] = {0xFFFFF,0x5A933,0x10E5A,0x6339C,0x73CE0, + 0xFFC00,0xD8E64,0x4F6B0,0x218EC,0x1B746, + 0x0FFFF,0x33FFF,0x3FFFC}; + + +void generate_pucch2x(int32_t **txdataF, + LTE_DL_FRAME_PARMS *fp, + uint8_t ncs_cell[20][7], + PUCCH_FMT_t fmt, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint16_t n2_pucch, + uint8_t *payload, + int A, + int B2, + int16_t amp, + uint8_t subframe, + uint16_t rnti) { + + int i,j; + uint32_t B=0; + uint8_t btilde[20]; + int16_t d[22]; + uint8_t deltaPUCCH_Shift = fp->pucch_config_common.deltaPUCCH_Shift; + uint8_t NRB2 = fp->pucch_config_common.nRB_CQI; + uint8_t Ncs1 = fp->pucch_config_common.nCS_AN; + + uint32_t u0 = fp->pucch_config_common.grouphop[subframe<<1]; + uint32_t u1 = fp->pucch_config_common.grouphop[1+(subframe<<1)]; + uint32_t v0 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + uint32_t v1 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + + uint32_t z[12*14],*zptr; + uint32_t u,v,n; + uint8_t ns,N_UL_symb,nsymb_slot0,nsymb_pertti; + uint32_t nprime,l,n_cs; + int alpha_ind,data_ind; + int16_t ref_re,ref_im; + int m,re_offset,symbol_offset; + int32_t *txptr; + + if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) { + printf("[PHY] generate_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift); + return; + } + + if (Ncs1 > 7) { + printf("[PHY] generate_pucch: Illegal Ncs1 %d (should be 0...7)\n",Ncs1); + return; + } + + // pucch2x_encoding + for (i=0;i<A;i++) + if ((*payload & (1<<i)) > 0) + B=B^pucch_code[i]; + + // scrambling + pucch2x_scrambling(fp,subframe,rnti,B,btilde); + // modulation + pucch2x_modulation(btilde,d,amp); + + // add extra symbol for 2a/2b + d[20]=0; + d[21]=0; + if (fmt==pucch_format2a) + d[20] = (B2 == 0) ? amp : -amp; + else if (fmt==pucch_format2b) { + switch (B2) { + case 0: + d[20] = amp; + break; + case 1: + d[21] = -amp; + break; + case 2: + d[21] = amp; + break; + case 3: + d[20] = -amp; + break; + default: + AssertFatal(1==0,"Illegal modulation symbol %d for PUCCH %s\n",B2,pucch_format_string[fmt]); + break; + } + } + + +#ifdef DEBUG_PUCCH_TX + printf("[PHY] PUCCH2x: n2_pucch %d\n",n2_pucch); +#endif + + N_UL_symb = (fp->Ncp==0) ? 7 : 6; + data_ind = 0; + zptr = z; + nprime = 0; + for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) { + + if ((ns&1) == 0) + nprime = (n2_pucch < 12*NRB2) ? + n2_pucch % 12 : + (n2_pucch+Ncs1 + 1)%12; + else { + nprime = (n2_pucch < 12*NRB2) ? + ((12*(nprime+1)) % 13)-1 : + (10-n2_pucch)%12; + } + //loop over symbols in slot + for (l=0; l<N_UL_symb; l++) { + // Compute n_cs (36.211 p. 18) + n_cs = (ncs_cell[ns][l]+nprime)%12; + + alpha_ind = 0; + 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); + + if ((l!=1)&&(l!=5)) { //these are PUCCH data symbols + ((int16_t *)&zptr[n])[0] = ((int32_t)d[data_ind]*ref_re - (int32_t)d[data_ind+1]*ref_im)>>15; + ((int16_t *)&zptr[n])[1] = ((int32_t)d[data_ind]*ref_im + (int32_t)d[data_ind+1]*ref_re)>>15; + //LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n); + } + else { + 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; + + if ((l!=1)&&(l!=5)) //these are PUCCH data symbols so increment data index + data_ind+=2; + } // l + } //ns + + m = n2_pucch/12; + +#ifdef DEBUG_PUCCH_TX + LOG_D(PHY,"[PHY] PUCCH: n2_pucch %d m %d\n",n2_pucch,m); +#endif + + nsymb_slot0 = ((fp->Ncp==0) ? 7 : 6); + nsymb_pertti = nsymb_slot0 << 1; + + //nsymb = nsymb_slot0<<1; + + //for (j=0,l=0;l<(nsymb-1);l++) { + for (j=0,l=0; l<(nsymb_pertti); l++) { + + if ((l<nsymb_slot0) && ((m&1) == 0)) + re_offset = (m*6) + fp->first_carrier_offset; + else if ((l<nsymb_slot0) && ((m&1) == 1)) + re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12; + else if ((m&1) == 0) + re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12; + else + re_offset = ((m-1)*6) + fp->first_carrier_offset; + + if (re_offset > fp->ofdm_symbol_size) + re_offset -= (fp->ofdm_symbol_size); + + + + symbol_offset = (unsigned int)fp->ofdm_symbol_size*(l+(subframe*nsymb_pertti)); + txptr = &txdataF[0][symbol_offset]; + + //LOG_I(PHY,"ofdmSymb %d/%d, firstCarrierOffset %d, symbolOffset[sfn %d] %d, reOffset %d, &txptr: %x \n", l, nsymb, fp->first_carrier_offset, subframe, symbol_offset, re_offset, &txptr[0]); + + for (i=0; i<12; i++,j++) { + txptr[re_offset] = z[j]; + + re_offset++; + + if (re_offset==fp->ofdm_symbol_size) + re_offset -= (fp->ofdm_symbol_size); + +#ifdef DEBUG_PUCCH_TX + LOG_D(PHY,"[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]); +#endif + } + } +} + +/* PUCCH format3 >> */ +/* DFT */ +void pucchfmt3_Dft( int16_t *x, int16_t *y ) +{ + int16_t i, k; + int16_t tmp[2]; + int16_t calctmp[D_NSC1RB*2]={0}; + + for (i=0; i<D_NSC1RB; i++) { + for(k=0; k<D_NSC1RB; k++) { + tmp[0] = alphaTBL_re[(12-((i*k)%12))%12]; + tmp[1] = alphaTBL_im[(12-((i*k)%12))%12]; + + calctmp[2*i] += (((int32_t)x[2*k] * tmp[0] - (int32_t)x[2*k+1] * tmp[1])>>15); + calctmp[2*i+1] += (((int32_t)x[2*k+1] * tmp[0] + (int32_t)x[2*k] * tmp[1])>>15); + } + y[2*i] = (int16_t)( (double) calctmp[2*i] / sqrt(D_NSC1RB)); + y[2*i+1] = (int16_t)((double) calctmp[2*i+1] / sqrt(D_NSC1RB)); + } +} + +void generate_pucch3x(int32_t **txdataF, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t ncs_cell[20][7], + PUCCH_FMT_t fmt, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint16_t n3_pucch, + uint8_t shortened_format, + uint8_t *payload, + int16_t amp, + uint8_t subframe, + uint16_t rnti) +{ + + uint32_t u, v; + uint16_t i, j, re_offset; + uint32_t z[12*14], *zptr; + uint32_t y_tilda[12*14]={}, *y_tilda_ptr; + uint8_t ns, nsymb, n_oc, n_oc0, n_oc1; + uint8_t N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6; + uint8_t m, l; + uint8_t n_cs; + int16_t tmp_re, tmp_im, W_re=0, W_im=0; + int32_t *txptr; + uint32_t symbol_offset; + + uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30; + uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30; + uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + + // variables for channel coding + uint8_t chcod_tbl_idx = 0; + //uint8_t chcod_dt[48] = {}; + + // variables for Scrambling + uint32_t cinit = 0; + uint32_t x1; + uint32_t s,s0,s1; + uint8_t C[48] ={}; + uint8_t scr_dt[48]={}; + + // variables for Modulation + int16_t d_re[24]={}; + int16_t d_im[24]={}; + + // variables for orthogonal sequence selection + uint8_t N_PUCCH_SF0 = 5; + uint8_t N_PUCCH_SF1 = (shortened_format==0)? 5:4; + uint8_t first_slot = 0; + int16_t rot_re=0; + int16_t rot_im=0; + + uint8_t dt_offset; + uint8_t sym_offset; + int16_t y_re[14][12]; //={0}; + int16_t y_im[14][12]; //={0}; + + // DMRS + uint8_t alpha_idx=0; + uint8_t m_alpha_idx=0; + + // TODO + // "SR+ACK/NACK" length is only 7 bits. + // This restriction will be lifted in the future. + // "CQI/PMI/RI+ACK/NACK" will be supported in the future. + + // Channel Coding + for (uint8_t i=0; i<7; i++) { + chcod_tbl_idx += (payload[i]<<i); + } + + // Scrambling + cinit = (subframe + 1) * ((2 * frame_parms->Nid_cell + 1)<<16) + rnti; + s0 = lte_gold_generic(&x1,&cinit,1); + s1 = lte_gold_generic(&x1,&cinit,0); + + for (i=0; i<48; i++) { + s = (i<32)? s0:s1; + j = (i<32)? i:(i-32); + C[i] = ((s>>j)&1); + } + + for (i=0; i<48; i++) { + scr_dt[i] = chcod_tbl[chcod_tbl_idx][i] ^ C[i]; + } + + // Modulation + for (uint8_t i=0; i<48; i+=2){ + if (scr_dt[i]==0 && scr_dt[i+1]==0){ + d_re[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); + d_im[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); + } else if (scr_dt[i]==0 && scr_dt[i+1]==1) { + d_re[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); + d_im[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp) >>15); + } else if (scr_dt[i]==1 && scr_dt[i+1]==0) { + d_re[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); + d_im[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp)>>15); + } else if (scr_dt[i]==1 && scr_dt[i+1]==1) { + d_re[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); + d_im[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); + } else { + //***log Modulation Error! + } + } + + // Calculate Orthogonal Sequence index + n_oc0 = n3_pucch % N_PUCCH_SF1; + if (N_PUCCH_SF1 == 5) { + n_oc1 = (3 * n_oc0) % N_PUCCH_SF1; + } else { + n_oc1 = n_oc0 % N_PUCCH_SF1; + } + + y_tilda_ptr = y_tilda; + zptr = z; + + // loop over 2 slots + for (ns=(subframe<<1), u=u0, v=v0; ns<(2+(subframe<<1)); ns++, u=u1, v=v1) { + first_slot = (ns==(subframe<<1))?1:0; + + //loop over symbols in slot + for (l=0; l<N_UL_symb; l++) { + rot_re = RotTBL_re[(uint8_t) ncs_cell[ns][l]/64] ; + rot_im = RotTBL_im[(uint8_t) ncs_cell[ns][l]/64] ; + + // Comput W_noc(m) (36.211 p. 19) + if ( first_slot == 0 && shortened_format==1) { // second slot and shortened format + n_oc = n_oc1; + + if (l<1) { // data + W_re=W4_fmt3[n_oc][l]; + W_im=0; + } else if (l==1) { // DMRS + W_re=W2[0]; + W_im=0; + } else if (l>=2 && l<5) { // data + W_re=W4_fmt3[n_oc][l-1]; + W_im=0; + } else if (l==5) { // DMRS + W_re=W2[1]; + W_im=0; + } else if ((l>=N_UL_symb-2)) { // data + ; + } else { + //***log W Select Error! + } + } else { + if (first_slot == 1) { // 1st slot or 2nd slot and not shortened + n_oc=n_oc0; + } else { + n_oc=n_oc1; + } + + if (l<1) { // data + W_re=W5_fmt3_re[n_oc][l]; + W_im=W5_fmt3_im[n_oc][l]; + } else if (l==1) { // DMRS + W_re=W2[0]; + W_im=0; + } else if (l>=2 && l<5) { // data + W_re=W5_fmt3_re[n_oc][l-1]; + W_im=W5_fmt3_im[n_oc][l-1]; + } else if (l==5) { // DMRS + W_re=W2[1]; + W_im=0; + } else if ((l>=N_UL_symb-1)) { // data + W_re=W5_fmt3_re[n_oc][l-N_UL_symb+5]; + W_im=W5_fmt3_im[n_oc][l-N_UL_symb+5]; + } else { + //***log W Select Error! + } + } // W Selection end + + // Compute n_cs (36.211 p. 18) + n_cs = ncs_cell[ns][l]; + if (N_PUCCH_SF1 == 5) { + alpha_idx = (n_cs + Np5_TBL[n_oc]) % 12; + } else { + alpha_idx = (n_cs + Np4_TBL[n_oc]) % 12; + } + + // generate pucch data + dt_offset = (first_slot == 1) ? 0:12; + sym_offset = (first_slot == 1) ? 0:7; + + for (i=0; i<12; i++) { + // Calculate yn(i) + tmp_re = (((int32_t) (W_re*rot_re - W_im*rot_im)) >>15); + tmp_im = (((int32_t) (W_re*rot_im + W_im*rot_re)) >>15); + y_re[l+sym_offset][i] = (((int32_t) (tmp_re*d_re[i+dt_offset] - tmp_im*d_im[i+dt_offset]))>>15); + y_im[l+sym_offset][i] = (((int32_t) (tmp_re*d_im[i+dt_offset] + tmp_im*d_re[i+dt_offset]))>>15); + + // cyclic shift + ((int16_t *)&y_tilda_ptr[(l+sym_offset)*12+(i-(ncs_cell[ns][l]%12)+12)%12])[0] = y_re[l+sym_offset][i]; + ((int16_t *)&y_tilda_ptr[(l+sym_offset)*12+(i-(ncs_cell[ns][l]%12)+12)%12])[1] = y_im[l+sym_offset][i]; + + // DMRS + m_alpha_idx = (alpha_idx * i) % 12; + if (l==1 || l==5) { + ((int16_t *)&zptr[(l+sym_offset)*12+i])[0] =(((((int32_t) alphaTBL_re[m_alpha_idx]*ul_ref_sigs[u][v][0][i<<1] - (int32_t) alphaTBL_im[m_alpha_idx] * ul_ref_sigs[u][v][0][1+(i<<1)])>>15) * (int32_t)amp)>>15); + ((int16_t *)&zptr[(l+sym_offset)*12+i])[1] =(((((int32_t) alphaTBL_re[m_alpha_idx]*ul_ref_sigs[u][v][0][1+(i<<1)] + (int32_t) alphaTBL_im[m_alpha_idx] * ul_ref_sigs[u][v][0][i<<1])>>15) * (int32_t)amp)>>15); + } + } + + } // l loop + } // ns + + // DFT for pucch-data + for (l=0; l<14; l++) { + if (l==1 || l==5 || l==8 || l==12) { + ; + } else { + pucchfmt3_Dft((int16_t*)&y_tilda_ptr[l*12],(int16_t*)&zptr[l*12]); + } + } + + + // Mapping + m = n3_pucch / N_PUCCH_SF0; + + if (shortened_format == 1) { + nsymb = (N_UL_symb<<1) - 1; + } else { + nsymb = (N_UL_symb<<1); + } + + for (j=0,l=0; l<(nsymb); l++) { + + if ((l<7) && ((m&1) == 0)) + re_offset = (m*6) + frame_parms->first_carrier_offset; + else if ((l<7) && ((m&1) == 1)) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else if ((m&1) == 0) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else + re_offset = ((m-1)*6) + frame_parms->first_carrier_offset; + + if (re_offset > frame_parms->ofdm_symbol_size) + re_offset -= (frame_parms->ofdm_symbol_size); + + symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*(l+(subframe*14)); + txptr = &txdataF[0][symbol_offset]; + + for (i=0; i<12; i++,j++) { + txptr[re_offset++] = z[j]; + + if (re_offset==frame_parms->ofdm_symbol_size) + re_offset = 0; + +#ifdef DEBUG_PUCCH_TX + msg("[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]); +#endif + } + } + +} + + + diff --git a/openair1/PHY/LTE_UE_TRANSPORT/rar_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/rar_tools_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..03df4e7f690e86b00cd8d39e3d58a9ddf1db267c --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/rar_tools_ue.c @@ -0,0 +1,207 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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_UE_TRANSPORT/rar_tools_ue.c +* \brief Routine for filling the PUSCH/ULSCH data structures based on a random-access response (RAR) SDU from MAC. Note this is for UE +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "SCHED_UE/sched_UE.h" +#include "LAYER2/MAC/mac.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "transport_proto_ue.h" + +#include "assertions.h" + +extern uint16_t RIV2nb_rb_LUT6[32]; +extern uint16_t RIV2first_rb_LUT6[32]; +extern uint16_t RIV2nb_rb_LUT25[512]; +extern uint16_t RIV2first_rb_LUT25[512]; +extern uint16_t RIV2nb_rb_LUT50[1600]; +extern uint16_t RIV2first_rb_LUT50[1600]; +extern uint16_t RIV2nb_rb_LUT100[6000]; +extern uint16_t RIV2first_rb_LUT100[600]; + +extern uint16_t RIV_max6,RIV_max25,RIV_max50,RIV_max100; + +int8_t delta_PUSCH_msg2[8] = {-6,-4,-2,0,2,4,6,8}; + +int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue, + UE_rxtx_proc_t *proc, + unsigned char eNB_id ) +{ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_RAR,VCD_FUNCTION_IN); + + // RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)rar_pdu; + uint8_t transmission_mode = ue->transmission_mode[eNB_id]; + unsigned char *rar_pdu = ue->dlsch_ra[eNB_id]->harq_processes[0]->b; + unsigned char subframe = ue->ulsch_Msg3_subframe[eNB_id]; + LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; + PHY_MEASUREMENTS *meas = &ue->measurements; + + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + // int current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; + + uint8_t *rar = (uint8_t *)(rar_pdu+1); + uint8_t harq_pid = subframe2harq_pid(frame_parms,proc->frame_tx,subframe); + uint16_t rballoc; + uint8_t cqireq; + uint16_t *RIV2nb_rb_LUT, *RIV2first_rb_LUT; + uint16_t RIV_max = 0; + + LOG_D(PHY,"[eNB][RAPROC] Frame %d: generate_ue_ulsch_params_from_rar: subframe %d (harq_pid %d)\n",proc->frame_tx,subframe,harq_pid); + + switch (frame_parms->N_RB_DL) { + case 6: + RIV2nb_rb_LUT = &RIV2nb_rb_LUT6[0]; + RIV2first_rb_LUT = &RIV2first_rb_LUT6[0]; + RIV_max = RIV_max6; + break; + + case 25: + RIV2nb_rb_LUT = &RIV2nb_rb_LUT25[0]; + RIV2first_rb_LUT = &RIV2first_rb_LUT25[0]; + RIV_max = RIV_max25; + break; + + case 50: + RIV2nb_rb_LUT = &RIV2nb_rb_LUT50[0]; + RIV2first_rb_LUT = &RIV2first_rb_LUT50[0]; + RIV_max = RIV_max50; + break; + + case 100: + RIV2nb_rb_LUT = &RIV2nb_rb_LUT100[0]; + RIV2first_rb_LUT = &RIV2first_rb_LUT100[0]; + RIV_max = RIV_max100; + break; + + default: + DevParam(frame_parms->N_RB_DL, eNB_id, harq_pid); + break; + } + + + + ulsch->harq_processes[harq_pid]->TPC = (rar[3]>>2)&7;//rar->TPC; + + rballoc = (((uint16_t)(rar[1]&7))<<7)|(rar[2]>>1); + cqireq=rar[3]&1; + + if (rballoc>RIV_max) { + LOG_D(PHY,"rar_tools.c: ERROR: rb_alloc (%x) > RIV_max\n",rballoc); + return(-1); + } + + ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT[rballoc]; + ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT[rballoc]; + + AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb >0, "nb_rb == 0\n"); + + ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb]; + + AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb <= 6,"unlikely rb count for RAR grant : nb_rb > 6\n"); + + // ulsch->harq_processes[harq_pid]->Ndi = 1; + if (ulsch->harq_processes[harq_pid]->round == 0) + ulsch->harq_processes[harq_pid]->status = ACTIVE; + + if (cqireq==1) { + ulsch->O_RI = 1; + + if (meas->rank[eNB_id] == 1) { + ulsch->uci_format = wideband_cqi_rank2_2A; + ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; + ulsch->o_RI[0] = 1; + } else { + ulsch->uci_format = wideband_cqi_rank1_2A; + ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; + ulsch->o_RI[0] = 0; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + fill_CQI(ulsch,meas,eNB_id,0,ue->frame_parms.N_RB_DL,0, transmission_mode,ue->sinr_eff); + + if (((proc->frame_tx % 100) == 0) || (proc->frame_tx < 10)) + print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL); + } else { + ulsch->O_RI = 0; + ulsch->O = 0; + } + + ulsch->harq_processes[harq_pid]->O_ACK = 0;//2; + + ulsch->beta_offset_cqi_times8 = 18; + ulsch->beta_offset_ri_times8 = 10; + ulsch->beta_offset_harqack_times8 = 16; + + ulsch->Nsymb_pusch = 12-(frame_parms->Ncp<<1); + ulsch->rnti = (((uint16_t)rar[4])<<8)+rar[5]; //rar->t_crnti; + + if (ulsch->harq_processes[harq_pid]->round == 0) { + ulsch->harq_processes[harq_pid]->status = ACTIVE; + ulsch->harq_processes[harq_pid]->rvidx = 0; + ulsch->harq_processes[harq_pid]->mcs = ((rar[2]&1)<<3)|(rar[3]>>5); + ulsch->harq_processes[harq_pid]->TPC = (rar[3]>>2)&7; + //ulsch->harq_processes[harq_pid]->TBS = dlsch_tbs25[ulsch->harq_processes[harq_pid]->mcs][ulsch->harq_processes[harq_pid]->nb_rb-1]; + ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; + ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; + ulsch->harq_processes[harq_pid]->Nsymb_initial = 9; + ulsch->harq_processes[harq_pid]->round = 0; + } else { + ulsch->harq_processes[harq_pid]->rvidx = 0; + ulsch->harq_processes[harq_pid]->round++; + } + + // initialize power control based on PRACH power + ulsch->f_pusch = delta_PUSCH_msg2[ulsch->harq_processes[harq_pid]->TPC] + + get_deltaP_rampup(ue->Mod_id,ue->CC_id); + LOG_D(PHY,"[UE %d][PUSCH PC] Initializing f_pusch to %d dB, TPC %d (delta_PUSCH_msg2 %d dB), deltaP_rampup %d dB\n", + ue->Mod_id,ulsch->f_pusch,ulsch->harq_processes[harq_pid]->TPC,delta_PUSCH_msg2[ulsch->harq_processes[harq_pid]->TPC], + get_deltaP_rampup(ue->Mod_id,ue->CC_id)); + + + //#ifdef DEBUG_RAR + LOG_D(PHY,"ulsch ra (UE): harq_pid %d\n",harq_pid); + LOG_D(PHY,"ulsch ra (UE): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); + LOG_D(PHY,"ulsch ra (UE): first_rb %x\n",ulsch->harq_processes[harq_pid]->first_rb); + LOG_D(PHY,"ulsch ra (UE): nb_rb %d\n",ulsch->harq_processes[harq_pid]->nb_rb); + LOG_D(PHY,"ulsch ra (UE): round %d\n",ulsch->harq_processes[harq_pid]->round); + LOG_D(PHY,"ulsch ra (UE): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); + LOG_D(PHY,"ulsch ra (UE): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); + LOG_D(PHY,"ulsch ra (UE): TPC %d\n",ulsch->harq_processes[harq_pid]->TPC); + LOG_D(PHY,"ulsch ra (UE): O %d\n",ulsch->O); + LOG_D(PHY,"ulsch ra (UE): ORI %d\n",ulsch->O_RI); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_RAR,VCD_FUNCTION_OUT); + + //#endif + return(0); +} + diff --git a/openair1/PHY/LTE_UE_TRANSPORT/sldch.c b/openair1/PHY/LTE_UE_TRANSPORT/sldch.c new file mode 100644 index 0000000000000000000000000000000000000000..9c9d36c9746f5a8143544a21de67b5512210dd50 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/sldch.c @@ -0,0 +1,66 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/slss.c + * \brief Functions to Generate and Receive PSDCH + * \author R. Knopp + * \date 2017 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_SLSS__C__ +#define __LTE_TRANSPORT_SLSS__C__ +#include "PHY/defs_UE.h" + +extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP); + +void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch,int frame_tx,int subframe_tx) { + + UE_tport_t pdu; + size_t sldch_header_len = sizeof(UE_tport_header_t); + + pdu.header.packet_type = SLDCH; + pdu.header.absSF = (frame_tx*10)+subframe_tx; + + + AssertFatal((sldch->payload_length <=1500-sldch_header_len - sizeof(SLDCH_t) + sizeof(uint8_t*)), + "SLDCH payload length > %zd\n", + 1500-sldch_header_len - sizeof(SLDCH_t) + sizeof(uint8_t*)); + memcpy((void*)&pdu.sldch, + (void*)sldch, + sizeof(SLDCH_t)); + + LOG_I(PHY,"SLDCH configuration %zd bytes, TBS payload %d bytes => %zd bytes\n", + sizeof(SLDCH_t)-sizeof(uint8_t*), + sldch->payload_length, + sldch_header_len+sizeof(SLDCH_t)-sizeof(uint8_t*)+sldch->payload_length); + + multicast_link_write_sock(0, + (char *)&pdu, + sldch_header_len+sizeof(SLDCH_t)); + +} + + +#endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/slsch.c b/openair1/PHY/LTE_UE_TRANSPORT/slsch.c new file mode 100644 index 0000000000000000000000000000000000000000..e51e33626df38a277c41922b6150bfd392bff901 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/slsch.c @@ -0,0 +1,70 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/slss.c + * \brief Functions to Generate and Receive PSSCH + * \author R. Knopp + * \date 2017 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_SLSS__C__ +#define __LTE_TRANSPORT_SLSS__C__ +#include "PHY/defs_UE.h" + +extern int +multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP); + + +void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slsch,int frame_tx,int subframe_tx) { + + UE_tport_t pdu; + size_t slsch_header_len = sizeof(UE_tport_header_t); + + if (slsch->rvidx==0) { + pdu.header.packet_type = SLSCH; + pdu.header.absSF = (frame_tx*10)+subframe_tx; + + memcpy((void*)&pdu.slsch,(void*)slsch,sizeof(SLSCH_t)-sizeof(uint8_t*)); + + AssertFatal(slsch->payload_length <=1500-slsch_header_len - sizeof(SLSCH_t) + sizeof(uint8_t*), + "SLSCH payload length > %zd\n", + 1500-slsch_header_len - sizeof(SLSCH_t) + sizeof(uint8_t*)); + memcpy((void*)&pdu.payload[0], + (void*)slsch->payload, + slsch->payload_length); + + LOG_I(PHY,"SLSCH configuration %zd bytes, TBS payload %d bytes => %zd bytes\n", + sizeof(SLSCH_t)-sizeof(uint8_t*), + slsch->payload_length, + slsch_header_len+sizeof(SLSCH_t)-sizeof(uint8_t*)+slsch->payload_length); + + multicast_link_write_sock(0, + (char *)&pdu, + slsch_header_len+sizeof(SLSCH_t)-sizeof(uint8_t*)+slsch->payload_length); + + } +} + +#endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/slss.c b/openair1/PHY/LTE_UE_TRANSPORT/slss.c new file mode 100644 index 0000000000000000000000000000000000000000..18bc5a28dec8826a63ebef68eec43654561bf6da --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/slss.c @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/slss.c + * \brief Functions to Generate and Received Sidelink PSS,SSS and PSBCH + * \author R. Knopp + * \date 2017 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_SLSS__C__ +#define __LTE_TRANSPORT_SLSS__C__ +#include "PHY/defs_UE.h" + + +void generate_slss(PHY_VARS_UE *ue,SLSS_t *slss,int frame_tx,int subframe_tx) { + + AssertFatal(1==0,"Should get here yet for UE %d\n",ue->Mod_id); + +} + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c similarity index 99% rename from openair1/PHY/LTE_TRANSPORT/srs_modulation.c rename to openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c index c4c02e631279a3833da27c1b2aedceb431e55b7d..45508fcff27eb5ee25e6694b8903f114e2edcb19 100644 --- a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c @@ -29,8 +29,8 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #include "UTIL/LOG/log.h" unsigned short msrsb_6_40[8][4] = {{36,12,4,4}, diff --git a/openair1/PHY/LTE_UE_TRANSPORT/sss_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/sss_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..aee5d6bcf91a37fc50710f63c8cfb4d6048a8153 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/sss_ue.c @@ -0,0 +1,421 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/sss_ue.c +* \brief Top-level routines for decoding the secondary synchronization signal (SSS) V8.6 2009-03 +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#include "PHY/defs_UE.h" +#include "transport_ue.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/MODULATION/modulation_UE.h" + +//#define DEBUG_SSS + + + + +int pss_ch_est(PHY_VARS_UE *ue, + int32_t pss_ext[4][72], + int32_t sss_ext[4][72]) +{ + + int16_t *pss; + int16_t *pss_ext2,*sss_ext2,*sss_ext3,tmp_re,tmp_im,tmp_re2,tmp_im2; + uint8_t aarx,i; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + + switch (ue->common_vars.eNb_id) { + + case 0: + pss = &primary_synch0[10]; + break; + + case 1: + pss = &primary_synch1[10]; + break; + + case 2: + pss = &primary_synch2[10]; + break; + + default: + pss = &primary_synch0[10]; + break; + } + + sss_ext3 = (int16_t*)&sss_ext[0][5]; + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + + sss_ext2 = (int16_t*)&sss_ext[aarx][5]; + pss_ext2 = (int16_t*)&pss_ext[aarx][5]; + + for (i=0; i<62; i++) { + + // This is H*(PSS) = R* \cdot PSS + tmp_re = (int16_t)(((pss_ext2[i<<1] * (int32_t)pss[i<<1])>>15) + ((pss_ext2[1+(i<<1)] * (int32_t)pss[1+(i<<1)])>>15)); + tmp_im = (int16_t)(((pss_ext2[i<<1] * (int32_t)pss[1+(i<<1)])>>15) - ((pss_ext2[1+(i<<1)] * (int32_t)pss[(i<<1)])>>15)); + // printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im); + // This is R(SSS) \cdot H*(PSS) + tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i<<1])>>15) - ((tmp_im * (int32_t)sss_ext2[1+(i<<1)]>>15))); + tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[1+(i<<1)])>>15) + ((tmp_im * (int32_t)sss_ext2[(i<<1)]>>15))); + + // printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]); + // printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2); + // MRC on RX antennas + if (aarx==0) { + sss_ext3[i<<1] = tmp_re2; + sss_ext3[1+(i<<1)] = tmp_im2; + } else { + sss_ext3[i<<1] += tmp_re2; + sss_ext3[1+(i<<1)] += tmp_im2; + } + } + } + + // sss_ext now contains the compensated SSS + return(0); +} + + +int _do_pss_sss_extract(PHY_VARS_UE *ue, + int32_t pss_ext[4][72], + int32_t sss_ext[4][72], + uint8_t doPss, uint8_t doSss, + uint8_t subframe) // add flag to indicate extracting only PSS, only SSS, or both +{ + + + + uint16_t rb,nb_rb=6; + uint8_t i,aarx; + int32_t *pss_rxF,*pss_rxF_ext; + int32_t *sss_rxF,*sss_rxF_ext; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + uint8_t next_thread_id = ue->current_thread_id[subframe]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe]+1); + + int rx_offset = frame_parms->ofdm_symbol_size-3*12; + uint8_t pss_symb,sss_symb; + + int32_t **rxdataF; + + //LOG_I(PHY,"do_pss_sss_extract subframe %d \n",subframe); + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + + if (frame_parms->frame_type == FDD) { + pss_symb = 6-frame_parms->Ncp; + sss_symb = pss_symb-1; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; + pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + + } else { + pss_symb = 2; + sss_symb = frame_parms->symbols_per_tti-1; + + if(subframe==5 || subframe==0) + { + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; + sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; + pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else if(subframe==6 || subframe==1) + { + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; + pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; + sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else + { + AssertFatal(0,""); + } + + } + //printf("extract_rbs: symbol_mod=%d, rx_offset=%d, ch_offset=%d\n",symbol_mod, + // (rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))*2, + // LTE_CE_OFFSET+ch_offset+(symbol_mod*(frame_parms->ofdm_symbol_size))); + + pss_rxF_ext = &pss_ext[aarx][0]; + sss_rxF_ext = &sss_ext[aarx][0]; + + for (rb=0; rb<nb_rb; rb++) { + // skip DC carrier + if (rb==3) { + if(frame_parms->frame_type == FDD) + { + sss_rxF = &rxdataF[aarx][(1 + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + pss_rxF = &rxdataF[aarx][(1 + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else + { + if(subframe==5 || subframe==0) + { + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; + sss_rxF = &rxdataF[aarx][(1 + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; + pss_rxF = &rxdataF[aarx][(1 + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else if(subframe==6 || subframe==1) + { + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; + pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF; + sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else + { + AssertFatal(0,""); + } + } + } + + for (i=0; i<12; i++) { + if (doPss) {pss_rxF_ext[i]=pss_rxF[i];} + if (doSss) {sss_rxF_ext[i]=sss_rxF[i];} + } + + pss_rxF+=12; + sss_rxF+=12; + pss_rxF_ext+=12; + sss_rxF_ext+=12; + } + + } + + return(0); +} + +int pss_sss_extract(PHY_VARS_UE *phy_vars_ue, + int32_t pss_ext[4][72], + int32_t sss_ext[4][72], + uint8_t subframe) +{ + return _do_pss_sss_extract(phy_vars_ue, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe); +} + +int pss_only_extract(PHY_VARS_UE *phy_vars_ue, + int32_t pss_ext[4][72], + uint8_t subframe) +{ + static int32_t dummy[4][72]; + return _do_pss_sss_extract(phy_vars_ue, pss_ext, dummy, 1 /* doPss */, 0 /* doSss */, subframe); +} + + +int sss_only_extract(PHY_VARS_UE *phy_vars_ue, + int32_t sss_ext[4][72], + uint8_t subframe) +{ + static int32_t dummy[4][72]; + return _do_pss_sss_extract(phy_vars_ue, dummy, sss_ext, 0 /* doPss */, 1 /* doSss */, subframe); +} + + +int16_t phase_re[7] = {16383, 25101, 30791, 32767, 30791, 25101, 16383}; +int16_t phase_im[7] = {-28378, -21063, -11208, 0, 11207, 21062, 28377}; + + +int rx_sss(PHY_VARS_UE *ue,int32_t *tot_metric,uint8_t *flip_max,uint8_t *phase_max) +{ + + uint8_t i; + int32_t pss_ext[4][72]; + int32_t sss0_ext[4][72],sss5_ext[4][72]; + uint8_t Nid2 = ue->common_vars.eNb_id; + uint8_t flip,phase; + uint16_t Nid1; + int16_t *sss0,*sss5; + LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; + int32_t metric; + int16_t *d0,*d5; + + if (frame_parms->frame_type == FDD) { +#ifdef DEBUG_SSS + + if (frame_parms->Ncp == NORMAL) + msg("[PHY][UE%d] Doing SSS for FDD Normal Prefix\n",ue->Mod_id); + else + msg("[PHY][UE%d] Doing SSS for FDD Extended Prefix\n",ue->Mod_id); + +#endif + // Do FFTs for SSS/PSS + // SSS + slot_fep(ue, + (frame_parms->symbols_per_tti/2)-2, // second to last symbol of + 0, // slot 0 + ue->rx_offset, + 0, + 1); + // PSS + slot_fep(ue, + (frame_parms->symbols_per_tti/2)-1, // last symbol of + 0, // slot 0 + ue->rx_offset, + 0, + 1); + } else { // TDD +#ifdef DEBUG_SSS + if (ue->frame_parms->Ncp == NORMAL) + msg("[PHY][UE%d] Doing SSS for TDD Normal Prefix\n",ue->Mod_id); + else + msg("[PHY][UE%d] Doing SSS for TDD Extended Prefix\n",ue->Mod_id); + +#endif + // SSS + slot_fep(ue, + (frame_parms->symbols_per_tti>>1)-1, // last symbol of + 1, // slot 1 + ue->rx_offset, + 0, + 1); + // PSS + slot_fep(ue, + 2, // symbol 2 of + 2, // slot 2 + ue->rx_offset, + 0, + 1); + } + // pss sss extract for subframe 0 + pss_sss_extract(ue, + pss_ext, + sss0_ext,0); + /* + write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_tti,1,1); + write_output("rxdataF0.m","rxF0",&ue->common_vars.rxdataF[0][0],2*14*ue->frame_parms.ofdm_symbol_size,2,1); + write_output("pss_ext0.m","pssext0",pss_ext,72,1,1); + write_output("sss0_ext0.m","sss0ext0",sss0_ext,72,1,1); + */ + + // get conjugated channel estimate from PSS (symbol 6), H* = R* \cdot PSS + // and do channel estimation and compensation based on PSS + + pss_ch_est(ue, + pss_ext, + sss0_ext); + + // write_output("sss0_comp0.m","sss0comp0",sss0_ext,72,1,1); + + if (ue->frame_parms.frame_type == FDD) { // FDD + + // SSS + slot_fep(ue, + (frame_parms->symbols_per_tti/2)-2, + 10, + ue->rx_offset, + 0,1); + // PSS + slot_fep(ue, + (frame_parms->symbols_per_tti/2)-1, + 10, + ue->rx_offset, + 0,1); + } else { // TDD + // SSS + slot_fep(ue, + (frame_parms->symbols_per_tti>>1)-1, + 11, + ue->rx_offset, + 0, + 1); + // PSS + slot_fep(ue, + 2, + 12, + ue->rx_offset, + 0, + 1); + } + + // pss sss extract for subframe 5 + pss_sss_extract(ue, + pss_ext, + sss5_ext,5); + + // write_output("sss5_ext0.m","sss5ext0",sss5_ext,72,1,1); + // get conjugated channel estimate from PSS (symbol 6), H* = R* \cdot PSS + // and do channel estimation and compensation based on PSS + + pss_ch_est(ue, + pss_ext, + sss5_ext); + + + + // now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h + + *tot_metric = -99999999; + + + sss0 = (int16_t*)&sss0_ext[0][5]; + sss5 = (int16_t*)&sss5_ext[0][5]; + + for (flip=0; flip<2; flip++) { // d0/d5 flip in RX frame + for (phase=0; phase<7; phase++) { // phase offset between PSS and SSS + for (Nid1 = 0 ; Nid1 <= 167; Nid1++) { // 168 possible Nid1 values + metric = 0; + + if (flip==0) { + d0 = &d0_sss[62*(Nid2 + (Nid1*3))]; + d5 = &d5_sss[62*(Nid2 + (Nid1*3))]; + } else { + d5 = &d0_sss[62*(Nid2 + (Nid1*3))]; + d0 = &d5_sss[62*(Nid2 + (Nid1*3))]; + } + + // This is the inner product using one particular value of each unknown parameter + for (i=0; i<62; i++) { + metric += (int16_t)(((d0[i]*((((phase_re[phase]*(int32_t)sss0[i<<1])>>19)-((phase_im[phase]*(int32_t)sss0[1+(i<<1)])>>19)))) + + (d5[i]*((((phase_re[phase]*(int32_t)sss5[i<<1])>>19)-((phase_im[phase]*(int32_t)sss5[1+(i<<1)])>>19)))))); + } + + // if the current metric is better than the last save it + if (metric > *tot_metric) { + *tot_metric = metric; + ue->frame_parms.Nid_cell = Nid2+(3*Nid1); + *phase_max = phase; + *flip_max=flip; +#ifdef DEBUG_SSS + msg("(flip,phase,Nid1) (%d,%d,%d), metric_phase %d tot_metric %d, phase_max %d, flip_max %d\n",flip,phase,Nid1,metric,*tot_metric,*phase_max,*flip_max); +#endif + + } + } + } + } + + return(0); +} + diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h similarity index 74% rename from openair1/PHY/LTE_TRANSPORT/proto.h rename to openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h index 051f3cd92e0c34a514e6109975fe07d1d9d30473..ade621faa2a3fb3b386e4df3e8a1782549f56219 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file PHY/LTE_TRANSPORT/proto.h +/*! \file PHY/LTE_UE_TRANSPORT/transport_proto_ue.h * \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03 * \author R. Knopp, F. Kaltenberger * \date 2011 @@ -29,9 +29,10 @@ * \note * \warning */ -#ifndef __LTE_TRANSPORT_PROTO__H__ -#define __LTE_TRANSPORT_PROTO__H__ -#include "PHY/defs.h" +#ifndef __LTE_TRANSPORT_PROTO_UE__H__ +#define __LTE_TRANSPORT_PROTO_UE__H__ +#include "PHY/defs_UE.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include <math.h> #include "nfapi_interface.h" @@ -41,26 +42,6 @@ * @{ */ -/** \fn free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch,unsigned char N_RB_DL) - \brief This function frees memory allocated for a particular DLSCH at eNB - @param dlsch Pointer to DLSCH to be removed -*/ -void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch); - -void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); - -/** \fn new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms) - \brief This function allocates structures for a particular DLSCH at eNB - @returns Pointer to DLSCH to be removed - @param Kmimo Kmimo factor from 36-212/36-213 - @param Mdlharq Maximum number of HARQ rounds (36-212/36-213) - @param Nsoft Soft-LLR buffer size from UE-Category - @params N_RB_DL total number of resource blocks (determine the operating BW) - @param abstraction_flag Flag to indicate abstracted interface - @param frame_parms Pointer to frame descriptor structure -*/ -LTE_eNB_DLSCH_t *new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms); - /** \fn free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) \brief This function frees memory allocated for a particular DLSCH at UE @param dlsch Pointer to DLSCH to be removed @@ -68,7 +49,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch); /** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag) - \brief This function allocates structures for a particular DLSCH at eNB + \brief This function allocates structures for a particular DLSCH at UE @returns Pointer to DLSCH to be removed @param Kmimo Kmimo factor from 36-212/36-213 @param Mdlharq Maximum number of HARQ rounds (36-212/36-213) @@ -79,273 +60,13 @@ void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch); LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag); -void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch); -LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag); -/** \fn dlsch_encoding(PHY_VARS_eNB *eNB, - uint8_t *input_buffer, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe) - \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are: - - CRC computation and addition - - Code block segmentation and sub-block CRC addition - - Channel coding (Turbo coding) - - Rate matching (sub-block interleaving, bit collection, selection and transmission - - Code block concatenation - @param eNB Pointer to eNB PHY context - @param input_buffer Pointer to input buffer for sub-frame - @param frame_parms Pointer to frame descriptor structure - @param num_pdcch_symbols Number of PDCCH symbols in this subframe - @param dlsch Pointer to dlsch to be encoded - @param frame Frame number - @param subframe Subframe number - @param rm_stats Time statistics for rate-matching - @param te_stats Time statistics for turbo-encoding - @param i_stats Time statistics for interleaving - @returns status -*/ -int32_t dlsch_encoding(PHY_VARS_eNB *eNB, - uint8_t *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *i_stats); - -int32_t dlsch_encoding_SIC(PHY_VARS_UE *ue, - uint8_t *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *i_stats); - - - -/** \fn dlsch_encoding_2threads(PHY_VARS_eNB *eNB, - uint8_t *input_buffer, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe) - \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). This version spawns 1 worker thread. The implemented functions are: - - CRC computation and addition - - Code block segmentation and sub-block CRC addition - - Channel coding (Turbo coding) - - Rate matching (sub-block interleaving, bit collection, selection and transmission - - Code block concatenation - @param eNB Pointer to eNB PHY context - @param input_buffer Pointer to input buffer for sub-frame - @param num_pdcch_symbols Number of PDCCH symbols in this subframe - @param dlsch Pointer to dlsch to be encoded - @param frame Frame number - @param subframe Subframe number - @param rm_stats Time statistics for rate-matching - @param te_stats Time statistics for turbo-encoding - @param i_stats Time statistics for interleaving - @returns status -*/ -int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB, - uint8_t *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *i_stats); - -void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB, - uint8_t *DLSCH_pdu, - LTE_eNB_DLSCH_t *dlsch); - - -// Functions below implement 36-211 - -/** \fn allocate_REs_in_RB(int32_t **txdataF, - uint32_t *jj, - uint32_t *jj2, - uint16_t re_offset, - uint32_t symbol_offset, - LTE_DL_eNB_HARQ_t *dlsch0_harq, - LTE_DL_eNB_HARQ_t *dlsch1_harq, - uint8_t pilots, - int16_t amp, - int16_t *qam_table_s, - uint32_t *re_allocated, - uint8_t skip_dc, - uint8_t skip_half, - uint8_t use2ndpilots, - LTE_DL_FRAME_PARMS *frame_parms); - - \brief Fills RB with data - \param txdataF pointer to output data (frequency domain signal) - \param jj index to output (from CW 1) - \param jj2 index to output (from CW 2) - \param re_offset index of the first RE of the RB - \param symbol_offset index to the OFDM symbol - \param dlsch0_harq Pointer to Transport block 0 HARQ structure - \param dlsch0_harq Pointer to Transport block 1 HARQ structure - \param pilots =1 if symbol_offset is an OFDM symbol that contains pilots, 0 otherwise - \param amp Amplitude for symbols - \param qam_table_s0 pointer to scaled QAM table for Transport Block 0 (by rho_a or rho_b) - \param qam_table_s1 pointer to scaled QAM table for Transport Block 1 (by rho_a or rho_b) - \param re_allocated pointer to allocation counter - \param skip_dc offset for positive RBs - \param skip_half indicate that first or second half of RB must be skipped for PBCH/PSS/SSS - \param ue_spec_rs UE specific RS indicator - \param nb_antennas_tx_phy Physical antenna elements which can be different with antenna port number, especially in beamforming case - \param use2ndpilots Set to use the pilots from antenna port 1 for PDSCH - \param frame_parms Frame parameter descriptor -*/ - -// Functions below implement 36-211 - -/** \fn allocate_REs_in_RB(int32_t **txdataF, - uint32_t *jj, - uint32_t *jj2, - uint16_t re_offset, - uint32_t symbol_offset, - LTE_DL_eNB_HARQ_t *dlsch0_harq, - LTE_DL_eNB_HARQ_t *dlsch1_harq, - uint8_t pilots, - int16_t amp, - int16_t *qam_table_s, - uint32_t *re_allocated, - uint8_t skip_dc, - uint8_t skip_half, - uint8_t use2ndpilots, - LTE_DL_FRAME_PARMS *frame_parms); - - \brief Fills RB with data - \param txdataF pointer to output data (frequency domain signal) - \param jj index to output (from CW 1) - \param jj index to output (from CW 2) - \param re_offset index of the first RE of the RB - \param symbol_offset index to the OFDM symbol - \param dlsch0_harq Pointer to Transport block 0 HARQ structure - \param dlsch0_harq Pointer to Transport block 1 HARQ structure - \param pilots =1 if symbol_offset is an OFDM symbol that contains pilots, 0 otherwise - \param amp Amplitude for symbols - \param qam_table_s0 pointer to scaled QAM table for Transport Block 0 (by rho_a or rho_b) - \param qam_table_s1 pointer to scaled QAM table for Transport Block 1 (by rho_a or rho_b) - \param re_allocated pointer to allocation counter - \param skip_dc offset for positive RBs - \param skip_half indicate that first or second half of RB must be skipped for PBCH/PSS/SSS - \param use2ndpilots Set to use the pilots from antenna port 1 for PDSCH - \param frame_parms Frame parameter descriptor -*/ - -int32_t allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, - int32_t **txdataF, - uint32_t *jj, - uint32_t *jj2, - uint16_t re_offset, - uint32_t symbol_offset, - LTE_DL_eNB_HARQ_t *dlsch0_harq, - LTE_DL_eNB_HARQ_t *dlsch1_harq, - uint8_t pilots, - int16_t amp, - uint8_t precoder_index, - int16_t *qam_table_s0, - int16_t *qam_table_s1, - uint32_t *re_allocated, - uint8_t skip_dc, - uint8_t skip_half, - uint8_t lprime, - uint8_t mprime, - uint8_t Ns, - int *P1_SHIFT, - int *P2_SHIFT); - - -/** \fn int32_t dlsch_modulation(int32_t **txdataF, - int16_t amp, - uint32_t sub_frame_offset, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch); - - \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for DLSCH. - @param txdataF Table of pointers for frequency-domain TX signals - @param amp Amplitude of signal - @param sub_frame_offset Offset of this subframe in units of subframes (usually 0) - @param frame_parms Pointer to frame descriptor - @param num_pdcch_symbols Number of PDCCH symbols in this subframe - @param dlsch0 Pointer to Transport Block 0 DLSCH descriptor for this allocation - @param dlsch1 Pointer to Transport Block 0 DLSCH descriptor for this allocation -*/ -int32_t dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, - int32_t **txdataF, - int16_t amp, - int frame, - uint32_t sub_frame_offset, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch0, - LTE_eNB_DLSCH_t *dlsch1); - -int32_t dlsch_modulation_SIC(int32_t **sic_buffer, - uint32_t sub_frame_offset, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch0, - int G); -/* - \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH. - @param txdataF Table of pointers for frequency-domain TX signals - @param amp Amplitude of signal - @param subframe_offset Offset of this subframe in units of subframes (usually 0) - @param frame_parms Pointer to frame descriptor - @param dlsch Pointer to DLSCH descriptor for this allocation -*/ -int mch_modulation(int32_t **txdataF, - int16_t amp, - uint32_t subframe_offset, - LTE_DL_FRAME_PARMS *frame_parms, - LTE_eNB_DLSCH_t *dlsch); - -/** \brief Top-level generation function for eNB TX of MBSFN - @param phy_vars_eNB Pointer to eNB variables - @param a Pointer to transport block - @param abstraction_flag - -*/ -void generate_mch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t *a); - -/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) - @param phy_vars_eNB Pointer to eNB variables - @param proc Pointer to RXn-TXnp4 proc information - @param mcs MCS for MBSFN - @param ndi new data indicator - @param rdvix -*/ -void fill_eNB_dlsch_MCH(PHY_VARS_eNB *phy_vars_eNB,int mcs,int ndi,int rvidx); - -/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) - @param phy_vars_ue Pointer to UE variables - @param mcs MCS for MBSFN - @param eNB_id index of eNB in ue variables -*/ -void fill_UE_dlsch_MCH(PHY_VARS_UE *phy_vars_ue,int mcs,int ndi,int rvidx,int eNB_id); +void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id); -/** \brief Receiver processing for MBSFN, symbols can be done separately for time/CPU-scheduling purposes - @param phy_vars_ue Pointer to UE variables - @param eNB_id index of eNB in ue variables - @param subframe Subframe index of PMCH - @param symbol Symbol index on which to act -*/ int rx_pmch(PHY_VARS_UE *phy_vars_ue, unsigned char eNB_id, uint8_t subframe, @@ -361,66 +82,6 @@ int rx_pmch(PHY_VARS_UE *phy_vars_ue, void dump_mch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe); -/** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) - for N subframes. - @param phy_vars_eNB Pointer to eNB variables - @param txdataF Table of pointers for frequency-domain TX signals - @param amp Amplitude of signal - @param N Number of sub-frames to generate -*/ -void generate_pilots(PHY_VARS_eNB *phy_vars_eNB, - int32_t **txdataF, - int16_t amp, - uint16_t N); - -/** - \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) for one slot only - @param phy_vars_eNB Pointer to eNB variables - @param txdataF Table of pointers for frequency-domain TX signals - @param amp Amplitude of signal - @param slot index (0..19) - @param first_pilot_only (0 no) -*/ -int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB, - int32_t **txdataF, - int16_t amp, - uint16_t slot, - int first_pilot_only); - -int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, - int32_t **txdataF, - int16_t amp); - -void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB, - uint8_t UE_id, - int32_t **txdataF, - int16_t amp, - uint16_t Ntti, - uint8_t beamforming_mode); - -int32_t generate_pss(int32_t **txdataF, - int16_t amp, - LTE_DL_FRAME_PARMS *frame_parms, - uint16_t l, - uint16_t Ns); - -int32_t generate_pss_emul(PHY_VARS_eNB *phy_vars_eNB,uint8_t sect_id); - -int32_t generate_sss(int32_t **txdataF, - short amp, - LTE_DL_FRAME_PARMS *frame_parms, - unsigned short symbol, - unsigned short slot_offset); - -int32_t generate_pbch(LTE_eNB_PBCH *eNB_pbch, - int32_t **txdataF, - int32_t amp, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t *pbch_pdu, - uint8_t frame_mod4); - -int32_t generate_pbch_emul(PHY_VARS_eNB *phy_vars_eNB,uint8_t *pbch_pdu); /** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception. @param stream0_in Input from channel compensated (MR combined) stream 0 @@ -1327,6 +988,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); + uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, uint8_t subframe, PDSCH_t dlsch_id, @@ -1366,8 +1028,7 @@ int32_t rx_pdcch(PHY_VARS_UE *ue, uint8_t subframe, uint8_t eNB_id, MIMO_mode_t mimo_mode, - uint32_t high_speed_flag, - uint8_t is_secondary_ue); + uint32_t high_speed_flag); /*! \brief Extract PSS and SSS resource elements @param phy_vars_ue Pointer to UE variables @@ -1423,13 +1084,6 @@ uint16_t rx_pbch_emul(PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t pbch_phase); -/*! \brief PBCH scrambling. Applies 36.211 PBCH scrambling procedure. - \param frame_parms Pointer to frame descriptor - \param coded_data Output of the coding and rate matching - \param length Length of the sequence*/ -void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t* coded_data, - uint32_t length); /*! \brief PBCH unscrambling This is similar to pbch_scrabling with the difference that inputs are signed s16s (llr values) and instead of flipping bits we change signs. @@ -1442,47 +1096,33 @@ void pbch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, uint32_t length, uint8_t frame_mod4); -/*! \brief DCI Encoding. This routine codes an arbitrary DCI PDU after appending the 8-bit 3GPP CRC. It then applied sub-block interleaving and rate matching. - \param a Pointer to DCI PDU (coded in bytes) - \param A Length of DCI PDU in bits - \param E Length of DCI PDU in coded bits - \param e Pointer to sequence - \param rnti RNTI for CRC scrambling*/ -void dci_encoding(uint8_t *a, - uint8_t A, - uint16_t E, - uint8_t *e, - uint16_t rnti); - -/*! \brief Top-level DCI entry point. This routine codes an set of DCI PDUs and performs PDCCH modulation, interleaving and mapping. - \param num_dci Number of pdcch symbols - \param num_dci Number of DCI pdus to encode - \param dci_alloc Allocation vectors for each DCI pdu - \param n_rnti n_RNTI (see ) - \param amp Amplitude of QPSK symbols - \param frame_parms Pointer to DL Frame parameter structure - \param txdataF Pointer to tx signal buffers - \param sub_frame_offset subframe offset in frame - @returns Number of PDCCH symbols +/*! \brief Top-level generation route for Sidelink BCH,PSS and SSS + \param ue pointer to UE descriptor + \param slss pointer to SLSS configuration and payload + \param frame_tx Frame number + \param subframe_tx subframe number */ +void generate_slss(PHY_VARS_UE *ue,SLSS_t *slss,int frame_tx,int subframe_tx); -uint8_t generate_dci_top(uint8_t num_pdcch_symbols, - uint8_t num_dci, - DCI_ALLOC_t *dci_alloc, - uint32_t n_rnti, - int16_t amp, - LTE_DL_FRAME_PARMS *frame_parms, - int32_t **txdataF, - uint32_t sub_frame_offset); - -uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB, - int num_dci, - DCI_ALLOC_t *dci_alloc, - uint8_t subframe); +/*! \brief Top-level generation route for Sidelink Discovery Channel + \param ue pointer to UE descriptor + \param sldch pointer to SLDCH configuration and payload + \param frame_tx Frame number + \param subframe_tx subframe number +*/ +void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch,int frame_tx,int subframe_tx); +/*! \brief Top-level generation route for Sidelink Shared Channel + \param ue pointer to UE descriptor + \param slsch pointer to SLSCH configuration and payload + \param frame_tx Frame number + \param subframe_tx subframe number +*/ +void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slss,int frame_tx,int subframe_tx); void generate_64qam_table(void); void generate_16qam_table(void); +void generate_qpsk_table(void); uint16_t extract_crc(uint8_t *dci,uint8_t DCI_LENGTH); @@ -1635,8 +1275,6 @@ int generate_srs(LTE_DL_FRAME_PARMS *frame_parms, int16_t amp, uint32_t subframe); -int32_t generate_srs_tx_emul(PHY_VARS_UE *phy_vars_ue, - uint8_t subframe); /*! \brief This function is similar to generate_srs_tx but generates a conjugate sequence for channel estimation. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence. @@ -1689,16 +1327,9 @@ void ulsch_modulation(int32_t **txdataF, LTE_UE_ULSCH_t *ulsch); -void ulsch_extract_rbs_single(int32_t **rxdataF, - int32_t **rxdataF_ext, - uint32_t first_rb, - uint32_t nb_rb, - uint8_t l, - uint8_t Ns, - LTE_DL_FRAME_PARMS *frame_parms); -uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe); -uint8_t subframe2harq_pid_eNBrx(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); + + int generate_ue_dlsch_params_from_dci(int frame, uint8_t subframe, @@ -1716,38 +1347,6 @@ int generate_ue_dlsch_params_from_dci(int frame, uint8_t beamforming_mode, uint16_t tc_rnti); -void fill_dci_and_dlsch(PHY_VARS_eNB *eNB, - int frame, - int subframe, - eNB_rxtx_proc_t *proc, - DCI_ALLOC_t *dci_alloc, - nfapi_dl_config_dci_dl_pdu *pdu); - -void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu); - -void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, - nfapi_hi_dci0_dci_pdu *pdu); - -void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe); - -int32_t generate_eNB_dlsch_params_from_dci(int frame, - uint8_t subframe, - void *dci_pdu, - rnti_t rnti, - DCI_format_t dci_format, - LTE_eNB_DLSCH_t **dlsch_eNB, - LTE_DL_FRAME_PARMS *frame_parms, - PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint16_t DL_pmi_single, - uint8_t beamforming_mode); - -int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, - unsigned char *rar_pdu, - uint32_t frame, - unsigned char subframe); int generate_ue_ulsch_params_from_dci(void *dci_pdu, rnti_t rnti, @@ -1771,44 +1370,20 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *phy_vars_ue, uint8_t sinr2cqi(double sinr,uint8_t trans_mode); -int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB, - eNB_rxtx_proc_t *proc, - void *dci_pdu, - rnti_t rnti, - DCI_format_t dci_format, - uint8_t UE_id, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint16_t cba_rnti, - uint8_t use_srs); - - -void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id); int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci); int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, UE_rxtx_proc_t *proc, char* buffer, int length, runmode_t mode, int input_level_dBm); -int dump_eNB_stats(PHY_VARS_eNB *phy_vars_eNB, char* buffer, int length); void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms); -void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t subframe, - uint8_t *b, - uint8_t *bt); void pcfich_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, int16_t *d); -void generate_pcfich(uint8_t num_pdcch_symbols, - int16_t amp, - LTE_DL_FRAME_PARMS *frame_parms, - int32_t **txdataF, - uint8_t subframe); uint8_t rx_pcfich(LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, @@ -1831,14 +1406,6 @@ void generate_RIV_tables(void); */ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode); -void rx_ulsch(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, - uint8_t UE_id); - - -void rx_ulsch_emul(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, - uint8_t UE_index); /*! \brief Encoding of PUSCH/ACK/RI/ACK from 36-212. @@ -1859,73 +1426,8 @@ uint32_t ulsch_encoding(uint8_t *a, uint8_t control_only_flag, uint8_t Nbundled); -/*! - \brief Encoding of PUSCH/ACK/RI/ACK from 36-212 for emulation - @param ulsch_buffer Pointer to ulsch SDU - @param phy_vars_ue Pointer to UE top-level descriptor - @param eNB_id ID of eNB receiving this PUSCH - @param harq_pid HARQ process ID - @param control_only_flag Generate PUSCH with control information only -*/ -int32_t ulsch_encoding_emul(uint8_t *ulsch_buffer, - PHY_VARS_UE *phy_vars_ue, - uint8_t eNB_id, - uint8_t subframe_rx, - uint8_t harq_pid, - uint8_t control_only_flag); - -/*! - \brief Decoding of PUSCH/ACK/RI/ACK from 36-212. - @param phy_vars_eNB Pointer to eNB top-level descriptor - @param proc Pointer to RXTX proc variables - @param UE_id ID of UE transmitting this PUSCH - @param subframe Index of subframe for PUSCH - @param control_only_flag Receive PUSCH with control information only - @param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213 - @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used - @returns 0 on success -*/ -unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, - uint8_t UE_id, - uint8_t control_only_flag, - uint8_t Nbundled, - uint8_t llr8_flag); - -/*! - \brief Decoding of ULSCH data component from 36-212. This one spawns 1 worker thread in parallel,half of the segments in each thread. - @param phy_vars_eNB Pointer to eNB top-level descriptor - @param UE_id ID of UE transmitting this PUSCH - @param harq_pid HARQ process ID - @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used - @returns 0 on success -*/ -int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB, - int UE_id, - int harq_pid, - int llr8_flag); - -/*! - \brief Decoding of ULSCH data component from 36-212. This one is single thread. - @param phy_vars_eNB Pointer to eNB top-level descriptor - @param UE_id ID of UE transmitting this PUSCH - @param harq_pid HARQ process ID - @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used - @returns 0 on success -*/ -int ulsch_decoding_data(PHY_VARS_eNB *eNB, - int UE_id, - int harq_pid, - int llr8_flag); -uint32_t ulsch_decoding_emul(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, - uint8_t UE_index, - uint16_t *crnti); -void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, - int16_t amp); /* \brief This routine demodulates the PHICH and updates PUSCH/ULSCH parameters. @param phy_vars_ue Pointer to UE variables @@ -1957,8 +1459,6 @@ int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int sub void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL); -void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode); - void fill_CQI(LTE_UE_ULSCH_t *ulsch,PHY_MEASUREMENTS *meas,uint8_t eNB_id, uint8_t harq_pid,int N_RB_DL, rnti_t rnti, uint8_t trans_mode,double sinr_eff); void reset_cba_uci(void *o); @@ -1975,21 +1475,12 @@ int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb); uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands); -uint64_t pmi2hex_2Ar1(uint32_t pmi); -uint64_t pmi2hex_2Ar2(uint32_t pmi); uint64_t cqi2hex(uint32_t cqi); uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); -/** \brief This routine expands a single (wideband) PMI to subband PMI bitmap similar to the one used in the UCI and in the dlsch_modulation routine - @param frame_parms Pointer to DL frame configuration parameters - @param wideband_pmi (0,1,2,3 for rank 0 and 0,1 for rank 1) - @param rank (0 or 1) - @returns subband PMI bitmap -*/ -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank); /** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function @param N_RB_DL number of resource blocks @@ -2024,19 +1515,7 @@ void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, int8_t* llr, uint32_t length); -void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t subframe, - uint8_t *e, - uint32_t length); - -void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, - int mbsfn_flag, - LTE_eNB_DLSCH_t *dlsch, - int hard_pid, - int G, - uint8_t q, - uint16_t frame, - uint8_t Ns); + void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, int mbsfn_flag, @@ -2084,33 +1563,6 @@ void generate_pucch3x(int32_t **txdataF, uint8_t subframe, uint16_t rnti); -void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue, - UE_rxtx_proc_t *proc, - PUCCH_FMT_t format, - uint8_t ncs1, - uint8_t *pucch_ack_payload, - uint8_t sr); - - - -uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, - PUCCH_FMT_t fmt, - uint8_t UE_id, - uint16_t n1_pucch, - uint16_t n2_pucch, - uint8_t shortened_format, - uint8_t *payload, - int frame, - uint8_t subframe, - uint8_t pucch1_thres); - -int32_t rx_pucch_emul(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, - uint8_t UE_index, - PUCCH_FMT_t fmt, - uint8_t n1_pucch_sel, - uint8_t *payload); - void init_ulsch_power_LUT(void); @@ -2135,30 +1587,7 @@ int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t sub */ int32_t generate_prach(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint16_t Nf); -/*! - \brief Process PRACH waveform - @param phy_vars_eNB Pointer to eNB top-level descriptor. If NULL, then this is an RRU - @param ru Pointer to RU top-level descriptor. If NULL, then this is an eNB and we make use of the RU_list - @param max_preamble most likely preamble - @param max_preamble_energy Estimated Energy of most likely preamble - @param max_preamble_delay Estimated Delay of most likely preamble - @param Nf System frame number - @param tdd_mapindex Index of PRACH resource in Table 5.7.1-4 (TDD) - @param br_flag indicator to act on eMTC PRACH - @returns 0 on success -*/ -void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru, - uint16_t *max_preamble, - uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay, -#ifdef Rel14 - uint16_t Nf, uint8_t tdd_mapindex, - uint8_t br_flag -#else - uint16_t Nf, uint8_t tdd_mapindex -#endif - ); /*! \brief Helper for MAC, returns number of available PRACH in TDD for a particular configuration index @param frame_parms Pointer to LTE_DL_FRAME_PARMS structure @@ -2223,18 +1652,8 @@ uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB, uint8_t num_pdcch_symbols); // DL power control functions -double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated); - -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 get_pa_dB(uint8_t pa); -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 computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_UE_DLSCH_t *dlsch_ue, @@ -2258,12 +1677,5 @@ uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t n_ra_prboffset, uint8_t tdd_mapindex, uint16_t Nf); -uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); - -int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); - -int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); - -int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type); /**@}*/ #endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h new file mode 100644 index 0000000000000000000000000000000000000000..e97353a902868b1417240dfc2bc97e168db4e883 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h @@ -0,0 +1,336 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/defs.h +* \brief data structures for PDSCH/DLSCH/PUSCH/ULSCH physical and transport channel descriptors (TX/RX) +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr, florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it +* \note +* \warning +*/ +#ifndef __TRANSPORT_UE__H__ +#define __TRANSPORT_UE__H__ +#include "PHY/defs_UE.h" +#include "PHY/impl_defs_lte.h" +#include "../LTE_TRANSPORT/dci.h" +#include "../LTE_TRANSPORT/mdci.h" +#include "../LTE_TRANSPORT/uci_common.h" +#include "../LTE_TRANSPORT/transport_common.h" +#ifndef STANDALONE_COMPILE +#include "UTIL/LISTS/list.h" +#endif + +#include "../LTE_TRANSPORT/transport_common.h" + +// structures below implement 36-211 and 36-212 + +/** @addtogroup _PHY_TRANSPORT_ + * @{ + */ + + + +typedef struct { + /// Indicator of first transmission + uint8_t first_tx; + /// Last Ndi received for this process on DCI (used for C-RNTI only) + uint8_t DCINdi; + /// Flag indicating that this ULSCH has a new packet (start of new round) + // uint8_t Ndi; + /// Status Flag indicating for this ULSCH (idle,active,disabled) + SCH_status_t status; + /// Subframe scheduling indicator (i.e. Transmission opportunity indicator) + uint8_t subframe_scheduling_flag; + /// Subframe cba scheduling indicator (i.e. Transmission opportunity indicator) + uint8_t subframe_cba_scheduling_flag; + /// First Allocated RB + uint16_t first_rb; + /// Current Number of RBs + uint16_t nb_rb; + /// Last TPC command + uint8_t TPC; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits, "B" from 36-212 + uint32_t B; + /// Length of ACK information (bits) + uint8_t O_ACK; + /// Pointer to the payload + uint8_t *b; + /// Pointers to transport block segments + uint8_t *c[MAX_NUM_ULSCH_SEGMENTS]; + /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) + uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS]; + /// Index of current HARQ round for this ULSCH + uint8_t round; + /// MCS format of this ULSCH + uint8_t mcs; + /// Redundancy-version of the current sub-frame + uint8_t rvidx; + /// Turbo-code outputs (36-212 V8.6 2009-03, p.12 + uint8_t d[MAX_NUM_ULSCH_SEGMENTS][(96+3+(3*6144))]; + /// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17) + uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Total number of bits across all segments + uint32_t sumKr; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint16_t Msc_initial; + /// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint8_t Nsymb_initial; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) + uint8_t n_DMRS; + /// n_DMRS2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1) + uint8_t n_DMRS2; + /// Flag to indicate that this is a control only ULSCH (i.e. no MAC SDU) + uint8_t control_only; + /// Flag to indicate that this is a calibration ULSCH (i.e. no MAC SDU and filled with TDD calibration information) + // int calibration_flag; + /// Number of soft channel bits + uint32_t G; + + // decode phich + uint8_t decode_phich; +} LTE_UL_UE_HARQ_t; + +typedef struct { + /// Current Number of Symbols + uint8_t Nsymb_pusch; + /// SRS active flag + uint8_t srs_active; + /// Pointers to 8 HARQ processes for the ULSCH + LTE_UL_UE_HARQ_t *harq_processes[8]; + /// Pointer to CQI data (+1 for 8 bits crc) + uint8_t o[1+MAX_CQI_BYTES]; + /// Length of CQI data (bits) + uint8_t O; + /// Format of CQI data + UCI_format_t uci_format; + /// Rank information + uint8_t o_RI[2]; + /// Length of rank information (bits) + uint8_t O_RI; + /// Pointer to ACK + uint8_t o_ACK[4]; + /// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37) + uint8_t O_CQI_MIN; + /// ACK/NAK Bundling flag + uint8_t bundling; + /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + uint8_t e[MAX_NUM_CHANNEL_BITS]; + /// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + uint8_t h[MAX_NUM_CHANNEL_BITS]; + /// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14) + uint8_t b_tilde[MAX_NUM_CHANNEL_BITS]; + /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14) + int32_t d[MAX_NUM_RE]; + /// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15) + int32_t z[MAX_NUM_RE]; + /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) + uint8_t q[MAX_CQI_PAYLOAD]; + /// coded and interleaved CQI bits + uint8_t o_w[(MAX_CQI_BITS+8)*3]; + /// coded CQI bits + uint8_t o_d[96+((MAX_CQI_BITS+8)*3)]; + /// coded ACK bits + uint8_t q_ACK[MAX_ACK_PAYLOAD]; + /// coded RI bits + uint8_t q_RI[MAX_RI_PAYLOAD]; + /// beta_offset_cqi times 8 + uint16_t beta_offset_cqi_times8; + /// beta_offset_ri times 8 + uint16_t beta_offset_ri_times8; + /// beta_offset_harqack times 8 + uint16_t beta_offset_harqack_times8; + /// power_offset + uint8_t power_offset; + // for cooperative communication + uint8_t cooperation_flag; + /// RNTI attributed to this ULSCH + uint16_t rnti; + /// f_PUSCH parameter for PUSCH power control + int16_t f_pusch; + /// Po_PUSCH - target output power for PUSCH + int16_t Po_PUSCH; + /// PHR - current power headroom (based on last PUSCH transmission) + int16_t PHR; + /// Po_SRS - target output power for SRS + int16_t Po_SRS; + /// num active cba group + uint8_t num_active_cba_groups; + /// num dci found for cba + uint8_t num_cba_dci[10]; + /// allocated CBA RNTI + uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; + /// UL max-harq-retransmission + uint8_t Mlimit; +} LTE_UE_ULSCH_t; + + + + +typedef struct { + /// Indicator of first transmission + uint8_t first_tx; + /// Last Ndi received for this process on DCI (used for C-RNTI only) + uint8_t DCINdi; + /// DLSCH status flag indicating + SCH_status_t status; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits + uint32_t B; + /// Pointer to the payload + uint8_t *b; + /// Pointers to transport block segments + uint8_t *c[MAX_NUM_DLSCH_SEGMENTS]; + /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) + uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS]; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// MCS format for this DLSCH + uint8_t mcs; + /// Qm (modulation order) for this DLSCH + uint8_t Qm; + /// Redundancy-version of the current sub-frame + uint8_t rvidx; + /// MIMO mode for this DLSCH + MIMO_mode_t mimo_mode; + /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)]; + /// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + double w_abs[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)]; + /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t *d[MAX_NUM_DLSCH_SEGMENTS]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Nl; + /// current delta_pucch + int8_t delta_PUCCH; + /// Number of soft channel bits + uint32_t G; + /// Current Number of RBs + uint16_t nb_rb; + /// Current subband PMI allocation + uint16_t pmi_alloc; + /// Current RB allocation (even slots) + uint32_t rb_alloc_even[4]; + /// Current RB allocation (odd slots) + uint32_t rb_alloc_odd[4]; + /// distributed/localized flag + vrb_t vrb_type; + /// downlink power offset field + uint8_t dl_power_off; + /// trials per round statistics + uint32_t trials[8]; + /// error statistics per round + uint32_t errors[8]; + /// codeword this transport block is mapped to + uint8_t codeword; +} LTE_DL_UE_HARQ_t; + + +typedef struct { + /// HARQ process id + uint8_t harq_id; + /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX + uint8_t ack; + /// send status (for PUCCH) + uint8_t send_harq_status; + /// nCCE (for PUCCH) + uint8_t nCCE; + /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched + uint8_t vDAI_DL; + /// DAI value detected from DCI0/4. 0xff indicates not touched + uint8_t vDAI_UL; +} harq_status_t; + +typedef struct { + /// RNTI + uint16_t rnti; + /// Active flag for DLSCH demodulation + uint8_t active; + /// Transmission mode + uint8_t mode1_flag; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + /// Current HARQ process id threadRx Odd and threadRx Even + uint8_t current_harq_pid; + /// Current subband antenna selection + uint32_t antenna_alloc; + /// Current subband RI allocation + uint32_t ri_alloc; + /// Current subband CQI1 allocation + uint32_t cqi_alloc1; + /// Current subband CQI2 allocation + uint32_t cqi_alloc2; + /// saved subband PMI allocation from last PUSCH/PUCCH report + uint16_t pmi_alloc; + /// HARQ-ACKs + harq_status_t harq_ack[10]; + /// Pointers to up to 8 HARQ processes + LTE_DL_UE_HARQ_t *harq_processes[8]; + /// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17 + uint8_t Mdlharq; + /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Kmimo; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// Maximum number of Turbo iterations + uint8_t max_turbo_iterations; + /// number of iterations used in last turbo decoding + uint8_t last_iteration_cnt; + /// accumulated tx power adjustment for PUCCH + int8_t g_pucch; +} LTE_UE_DLSCH_t; + + + + +/**@}*/ +#endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/uci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/uci_tools_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..e687ccfd049f2704fd072e5ff0c196be3855f161 --- /dev/null +++ b/openair1/PHY/LTE_UE_TRANSPORT/uci_tools_ue.c @@ -0,0 +1,244 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/phich.c +* \brief Routines for generation of and computations regarding the uplink control information (UCI) for PUSCH. V8.6 2009-03 +* \author R. Knopp, F. Kaltenberger, A. Bhamri +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr, florian.kaltenberger@eurecom.fr, ankit.bhamri@eurecom.fr +* \note +* \warning +*/ +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#ifdef DEBUG_UCI_TOOLS +#include "PHY/phy_vars.h" +#endif + +//#define DEBUG_UCI 1 + + +uint64_t cqi2hex(uint32_t cqi) +{ + + uint64_t cqil = (uint64_t)cqi; + return ((cqil&3) + (((cqil>>2)&3)<<4) + (((cqil>>4)&3)<<8) + (((cqil>>6)&3)<<12) + + (((cqil>>8)&3)<<16) + (((cqil>>10)&3)<<20) + (((cqil>>12)&3)<<24) + + (((cqil>>14)&3)<<28) + (((cqil>>16)&3)<<32) + (((cqil>>18)&3)<<36) + + (((cqil>>20)&3)<<40) + (((cqil>>22)&3)<<44) + (((cqil>>24)&3)<<48)); +} + + +void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL) +{ + + + switch(uci_format) { + case wideband_cqi_rank1_2A: +#ifdef DEBUG_UCI + LOG_D(PHY,"[PRINT CQI] flat_LA %d\n", flag_LA); + switch(N_RB_DL) { + case 6: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, + ((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, + ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi, + pmi2hex_2Ar1(((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi)); + break; + + case 25: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, + ((wideband_cqi_rank1_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, + ((wideband_cqi_rank1_2A_5MHz *)o)->pmi, + pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)o)->pmi)); + break; + + case 50: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, + ((wideband_cqi_rank1_2A_10MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, + ((wideband_cqi_rank1_2A_10MHz *)o)->pmi, + pmi2hex_2Ar1(((wideband_cqi_rank1_2A_10MHz *)o)->pmi)); + break; + + case 100: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, cqi %d\n",eNB_id, + ((wideband_cqi_rank1_2A_20MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 1: eNB %d, pmi (%x) %8x\n",eNB_id, + ((wideband_cqi_rank1_2A_20MHz *)o)->pmi, + pmi2hex_2Ar1(((wideband_cqi_rank1_2A_20MHz *)o)->pmi)); + break; + } + +#endif //DEBUG_UCI + break; + + case wideband_cqi_rank2_2A: +#ifdef DEBUG_UCI + switch(N_RB_DL) { + case 6: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi)); + break; + + case 25: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_5MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_5MHz *)o)->pmi)); + break; + + case 50: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_10MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_10MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_10MHz *)o)->pmi)); + break; + + case 100: + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((wideband_cqi_rank2_2A_20MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((wideband_cqi_rank2_2A_20MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] wideband_cqi rank 2: eNB %d, pmi %8x\n",eNB_id,pmi2hex_2Ar2(((wideband_cqi_rank2_2A_20MHz *)o)->pmi)); + break; + } + +#endif //DEBUG_UCI + break; + + case HLC_subband_cqi_nopmi: +#ifdef DEBUG_UCI + switch(N_RB_DL) { + case 6: + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1)); + break; + + case 25: + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); + break; + + case 50: + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1)); + break; + + case 100: + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi (no pmi) : eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1)); + break; + } + +#endif //DEBUG_UCI + break; + + case HLC_subband_cqi_rank1_2A: +#ifdef DEBUG_UCI + switch(N_RB_DL) { + case 6: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); + break; + + case 25: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); + break; + + case 50: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); + break; + + case 100: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 1: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi); + break; + } + +#endif //DEBUG_UCI + break; + + case HLC_subband_cqi_rank2_2A: +#ifdef DEBUG_UCI + switch(N_RB_DL) { + case 6: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi); + break; + + case 25: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi); + break; + + case 50: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi); + break; + + case 100: + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi1 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, cqi2 %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi1 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, diffcqi2 %8x\n",eNB_id,cqi2hex(((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2)); + LOG_I(PHY,"[PRINT CQI] hlc_cqi rank 2: eNB %d, pmi %d\n",eNB_id,((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi); + break; + } + +#endif //DEBUG_UCI + break; + + case ue_selected: +#ifdef DEBUG_UCI + LOG_W(PHY,"[PRINT CQI] ue_selected CQI not supported yet!!!\n"); +#endif //DEBUG_UCI + break; + + default: +#ifdef DEBUG_UCI + LOG_E(PHY,"[PRINT CQI] unsupported CQI mode (%d)!!!\n",uci_format); +#endif //DEBUG_UCI + break; + } + +} + + + + + + diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c similarity index 95% rename from openair1/PHY/LTE_TRANSPORT/ulsch_coding.c rename to openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c index 87209e190b1749d27c9f96d3c04a3359eefb49c7..d913a6f77902bb33f657be1a5ea45cf64ba3b801 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c @@ -30,16 +30,13 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "PHY/CODING/defs.h" -#include "PHY/CODING/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/LTE_TRANSPORT/defs.h" -#include "defs.h" -#include "extern.h" -#include "SIMULATION/ETH_TRANSPORT/extern.h" +#include "PHY/LTE_UE_TRANSPORT/transport_ue.h" #include "UTIL/LOG/vcd_signal_dumper.h" //#define DEBUG_ULSCH_CODING @@ -66,33 +63,12 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) #endif for (i=0; i<8; i++) { -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d\n",i); -#endif - if (ulsch->harq_processes[i]) { -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d (%p)\n",i,ulsch->harq_processes[i]); -#endif - if (ulsch->harq_processes[i]->b) { free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES); ulsch->harq_processes[i]->b = NULL; -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d b (%p)\n",i,ulsch->harq_processes[i]->b); -#endif } - -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d c (%p)\n",i,ulsch->harq_processes[i]->c); -#endif - for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) { - -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d c[%d] (%p)\n",i,r,ulsch->harq_processes[i]->c[r]); -#endif - if (ulsch->harq_processes[i]->c[r]) { free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); ulsch->harq_processes[i]->c[r] = NULL; @@ -103,7 +79,6 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) ulsch->harq_processes[i] = NULL; } } - free16(ulsch,sizeof(LTE_UE_ULSCH_t)); ulsch = NULL; } @@ -129,7 +104,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) case 50: bw_scaling =2; break; - + default: bw_scaling =1; break; @@ -393,13 +368,13 @@ uint32_t ulsch_encoding(uint8_t *a, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(ulsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &ulsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? ulsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36212-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36212-820, page 14) - ); + encoder(ulsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &ulsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? ulsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36212-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36212-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_ULSCH_CODING diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c similarity index 97% rename from openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c rename to openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c index d1718f6e90f600927f5d93f3a18e93213bea86f8..92a8d16b44ad59045d890b4ad0e39634f3cfeb8f 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c @@ -29,14 +29,15 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/CODING/defs.h" -#include "PHY/CODING/extern.h" -#include "PHY/LTE_TRANSPORT/defs.h" -#include "defs.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/coding_extern.h" +#include "PHY/LTE_UE_TRANSPORT/transport_ue.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "UTIL/LOG/vcd_signal_dumper.h" - +#include "PHY/LTE_REFSIG/lte_refsig.h" //#define DEBUG_ULSCH_MODULATION @@ -381,7 +382,7 @@ void ulsch_modulation(int32_t **txdataF, DevAssert(frame_parms); - int re_offset,re_offset0,i,Msymb,j,k,nsymb,Msc_PUSCH,l; + int re_offset,re_offset0,i,ulsch_Msymb,j,k,nsymb,Msc_PUSCH,l; // uint8_t harq_pid = (rag_flag == 1) ? 0 : subframe2harq_pid_tdd(frame_parms->tdd_config,subframe); uint8_t harq_pid = subframe2harq_pid(frame_parms,frame,subframe); uint8_t Q_m; @@ -470,12 +471,12 @@ void ulsch_modulation(int32_t **txdataF, // Modulation - Msymb = G/Q_m; + ulsch_Msymb = G/Q_m; if(ulsch->cooperation_flag == 2) // For Distributed Alamouti Scheme in Collabrative Communication { - for (i=0,j=Q_m; i<Msymb; i+=2,j+=2*Q_m) { + for (i=0,j=Q_m; i<ulsch_Msymb; i+=2,j+=2*Q_m) { switch (Q_m) { @@ -609,7 +610,7 @@ void ulsch_modulation(int32_t **txdataF, }//for }//cooperation_flag == 2 else { - for (i=0,j=0; i<Msymb; i++,j+=Q_m) { + for (i=0,j=0; i<ulsch_Msymb; i++,j+=Q_m) { switch (Q_m) { @@ -685,7 +686,7 @@ void ulsch_modulation(int32_t **txdataF, #ifdef OFDMA_ULSCH - for (i=0; i<Msymb; i++) { + for (i=0; i<ulsch_Msymb; i++) { ulsch->z[i] = ulsch->d[i]; } diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 84863c81e89ce8c6742e8ca10896cd81ed3fa92c..e2ab0cd33b827307b8a004956177f5c2545dd19f 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -29,13 +29,14 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "PHY/CODING/defs.h" -#include "PHY/CODING/extern.h" +#include "PHY/defs_common.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" -#include "PHY/LTE_TRANSPORT/defs.h" -#include "defs.h" +#include "PHY/LTE_TRANSPORT/transport_eNB.h" +#include "modulation_eNB.h" #include "UTIL/LOG/vcd_signal_dumper.h" int beam_precoding(int32_t **txdataF, diff --git a/openair1/PHY/MODULATION/compute_bf_weights.c b/openair1/PHY/MODULATION/compute_bf_weights.c index 4ef8e88ca6652433efbad3ce761463bd41836325..89d76058e6d2b1859124a14408704403fc9f778b 100644 --- a/openair1/PHY/MODULATION/compute_bf_weights.c +++ b/openair1/PHY/MODULATION/compute_bf_weights.c @@ -2,6 +2,7 @@ #include <stdint.h> #include <stdlib.h> #include "PHY/impl_defs_lte.h" +#include "PHY/defs_common.h" int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs){ diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h deleted file mode 100644 index f9bbdcd27156e82cd7e41d010f406a58a905d6ca..0000000000000000000000000000000000000000 --- a/openair1/PHY/MODULATION/defs.h +++ /dev/null @@ -1,134 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef __MODULATION_DEFS__H__ -#define __MODULATION_DEFS__H__ -#include "PHY/defs.h" -/** @addtogroup _PHY_MODULATION_ - * @{ -*/ - -/** -\fn void PHY_ofdm_mod(int *input,int *output,int fftsize,unsigned char nb_symbols,unsigned short nb_prefix_samples,Extension_t etype) -This function performs OFDM modulation with cyclic extension or zero-padding. - -@param input The sequence input samples in the frequency-domain. This is a concatenation of the input symbols in SIMD redundant format -@param output The time-domain output signal -@param fftsize size of OFDM symbol size (\f$N_d\f$) -@param nb_symbols The number of OFDM symbols in the block -@param nb_prefix_samples The number of prefix/suffix/zero samples -@param etype Type of extension (CYCLIC_PREFIX,CYCLIC_SUFFIX,ZEROS) - -*/ -void PHY_ofdm_mod(int *input, - int *output, - int fftsize, - unsigned char nb_symbols, - unsigned short nb_prefix_samples, - Extension_t etype - ); - -#ifdef OPENAIR_LTE - -/*! -\brief This function implements the OFDM front end processor on reception (FEP) -\param phy_vars_ue Pointer to PHY variables -\param l symbol within slot (0..6/7) -\param Ns Slot number (0..19) -\param sample_offset offset within rxdata (points to beginning of subframe) -\param no_prefix if 1 prefix is removed by HW -\param reset_freq_est if non-zero it resets the frequency offset estimation loop -*/ - -int slot_fep(PHY_VARS_UE *phy_vars_ue, - unsigned char l, - unsigned char Ns, - int sample_offset, - int no_prefix, - int reset_freq_est); - -int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, - unsigned char l, - int subframe, - int sample_offset, - int no_prefix); - -int slot_fep_ul(RU_t *ru, - unsigned char l, - unsigned char Ns, - int no_prefix); - -int front_end_fft(PHY_VARS_UE *ue, - unsigned char l, - unsigned char Ns, - int sample_offset, - int no_prefix); - -int front_end_chanEst(PHY_VARS_UE *ue, - unsigned char l, - unsigned char Ns, - int reset_freq_est); - -void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms); - -void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); - -void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, RU_COMMON *common, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding); - -void remove_7_5_kHz(RU_t *ru,uint8_t subframe); - -void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t subframe); - -void init_prach625(LTE_DL_FRAME_PARMS *frame_parms); - -void remove_625_Hz(PHY_VARS_eNB *phy_vars_eNB,int16_t *prach); - -void apply_625_Hz(PHY_VARS_UE *phy_vars_ue,int16_t *prach); - -/** \brief This function performs beamforming precoding for common - * data - @param txdataF Table of pointers for frequency-domain TX signals - @param txdataF_BF Table of pointers for frequency-domain TX signals - @param frame_parms Frame descriptor structure -after beamforming - @param beam_weights Beamforming weights applied on each -antenna element and each carrier - @param slot Slot number - @param symbol Symbol index on which to act - @param aa physical antenna index*/ -int beam_precoding(int32_t **txdataF, - int32_t **txdataF_BF, - LTE_DL_FRAME_PARMS *frame_parms, - int32_t ***beam_weights, - int slot, - int symbol, - int aa); - -int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs); - -int estimate_DLCSI_from_ULCSI(int32_t **calib_dl_ch_estimates, int32_t **ul_ch_estimates, int32_t **tdd_calib_coeffs, int nb_ant, int nb_freq); - -int compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates, PRECODE_TYPE_t precode_type, int nb_ant, int nb_freq); - - -#endif -/** @}*/ -#endif diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h new file mode 100644 index 0000000000000000000000000000000000000000..7e2a3c8a27778f75b59866ea60392916baf9c684 --- /dev/null +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -0,0 +1,74 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __MODULATION_DEFS__H__ +#define __MODULATION_DEFS__H__ +#include "PHY/defs_common.h" +#include "modulation_common.h" +/** @addtogroup _PHY_MODULATION_ + * @{ +*/ + + + +/*! +\brief This function implements the OFDM front end processor on reception (FEP) +\param phy_vars_ue Pointer to PHY variables +\param l symbol within slot (0..6/7) +\param Ns Slot number (0..19) +\param sample_offset offset within rxdata (points to beginning of subframe) +\param no_prefix if 1 prefix is removed by HW +\param reset_freq_est if non-zero it resets the frequency offset estimation loop +*/ + +int slot_fep(PHY_VARS_UE *phy_vars_ue, + unsigned char l, + unsigned char Ns, + int sample_offset, + int no_prefix, + int reset_freq_est); + +int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, + unsigned char l, + int subframe, + int sample_offset, + int no_prefix); + +int front_end_fft(PHY_VARS_UE *ue, + unsigned char l, + unsigned char Ns, + int sample_offset, + int no_prefix); + +int front_end_chanEst(PHY_VARS_UE *ue, + unsigned char l, + unsigned char Ns, + int reset_freq_est); + +void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t subframe); + + +int compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates, PRECODE_TYPE_t precode_type, int nb_ant, int nb_freq); + + + +/** @}*/ +#endif diff --git a/openair1/PHY/MODULATION/modulation_common.h b/openair1/PHY/MODULATION/modulation_common.h new file mode 100644 index 0000000000000000000000000000000000000000..2ac0dc23b3012b5bc76aa8ad7acbdf9f4fedd318 --- /dev/null +++ b/openair1/PHY/MODULATION/modulation_common.h @@ -0,0 +1,56 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __MODULATION_COMMON__H__ +#define __MODULATION_COMMON__H__ +#include "PHY/defs_common.h" +/** @addtogroup _PHY_MODULATION_ + * @{ +*/ + +/** +\fn void PHY_ofdm_mod(int *input,int *output,int fftsize,unsigned char nb_symbols,unsigned short nb_prefix_samples,Extension_t etype) +This function performs OFDM modulation with cyclic extension or zero-padding. + +@param input The sequence input samples in the frequency-domain. This is a concatenation of the input symbols in SIMD redundant format +@param output The time-domain output signal +@param fftsize size of OFDM symbol size (\f$N_d\f$) +@param nb_symbols The number of OFDM symbols in the block +@param nb_prefix_samples The number of prefix/suffix/zero samples +@param etype Type of extension (CYCLIC_PREFIX,CYCLIC_SUFFIX,ZEROS) + +*/ +void PHY_ofdm_mod(int *input, + int *output, + int fftsize, + unsigned char nb_symbols, + unsigned short nb_prefix_samples, + Extension_t etype + ); + + +void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms); + +void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); + + +/** @}*/ +#endif diff --git a/openair1/PHY/MODULATION/modulation_eNB.h b/openair1/PHY/MODULATION/modulation_eNB.h new file mode 100644 index 0000000000000000000000000000000000000000..360861088721af9893767520af4af5cbc81a3f88 --- /dev/null +++ b/openair1/PHY/MODULATION/modulation_eNB.h @@ -0,0 +1,66 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __MODULATION_ENB__H__ +#define __MODULATION_ENB__H__ +#include "PHY/defs_common.h" +#include "modulation_common.h" + +/** @addtogroup _PHY_MODULATION_ + * @{ +*/ + +int slot_fep_ul(RU_t *ru, + unsigned char l, + unsigned char Ns, + int no_prefix); + +void remove_7_5_kHz(RU_t *ru,uint8_t subframe); + +/** \brief This function performs beamforming precoding for common + * data + @param txdataF Table of pointers for frequency-domain TX signals + @param txdataF_BF Table of pointers for frequency-domain TX signals + @param frame_parms Frame descriptor structure +after beamforming + @param beam_weights Beamforming weights applied on each +antenna element and each carrier + @param slot Slot number + @param symbol Symbol index on which to act + @param aa physical antenna index*/ +int beam_precoding(int32_t **txdataF, + int32_t **txdataF_BF, + LTE_DL_FRAME_PARMS *frame_parms, + int32_t ***beam_weights, + int slot, + int symbol, + int aa); + +int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs); + +int estimate_DLCSI_from_ULCSI(int32_t **calib_dl_ch_estimates, int32_t **ul_ch_estimates, int32_t **tdd_calib_coeffs, int nb_ant, int nb_freq); + +int compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates, PRECODE_TYPE_t precode_type, int nb_ant, int nb_freq); + + + +/** @}*/ +#endif diff --git a/openair1/PHY/MODULATION/modulation_extern.h b/openair1/PHY/MODULATION/modulation_extern.h new file mode 100644 index 0000000000000000000000000000000000000000..2834aa00f503113987b5fa27a52f631ff1d235c5 --- /dev/null +++ b/openair1/PHY/MODULATION/modulation_extern.h @@ -0,0 +1,38 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +extern int16_t s6n_kHz_7_5[1920]; +extern int16_t s6e_kHz_7_5[1920]; +extern int16_t s15n_kHz_7_5[3840]; +extern int16_t s15e_kHz_7_5[3840]; +extern int16_t s25n_kHz_7_5[7680]; +extern int16_t s25e_kHz_7_5[7680]; +extern int16_t s50n_kHz_7_5[15360]; +extern int16_t s50e_kHz_7_5[15360]; +extern int16_t s75n_kHz_7_5[23040]; +extern int16_t s75e_kHz_7_5[23040]; +extern int16_t s100n_kHz_7_5[30720]; +extern int16_t s100e_kHz_7_5[30720]; + + +extern short conjugate75[8]; +extern short conjugate75_2[8]; +extern short negate[8]; diff --git a/openair1/PHY/MODULATION/vars.h b/openair1/PHY/MODULATION/modulation_vars.h similarity index 80% rename from openair1/PHY/MODULATION/vars.h rename to openair1/PHY/MODULATION/modulation_vars.h index a05999afe1661142ecb9fbbce6c5f1d46bce0f4b..dbea92ab3f5e3e9998bab0bb417a8e7a11c629eb 100644 --- a/openair1/PHY/MODULATION/vars.h +++ b/openair1/PHY/MODULATION/modulation_vars.h @@ -19,13 +19,8 @@ * contact@openairinterface.org */ -mod_sym_t qpsk_table[4]; -mod_sym_t qam16_table[16]; -mod_sym_t qam64_table[64]; +#include "kHz_7_5.h" -int16_t kHz75_25PRB[1024] = {}; -int16_t kHz75_6PRB = {}; -int16_t kHz75_15PRB = {}; -int16_t kHz75_50PRB = {}; -int16_t kHz75_75PRB = {}; -int16_t kHz75_100PRB = {}; +short conjugate75[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; +short conjugate75_2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; +short negate[8]__attribute__((aligned(16))) = {-1,-1,-1,-1,-1,-1,-1,-1}; diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 37d1a483119cda97b5e455787d51bada349b83fc..dfb6c85f33abe7f7309a7b23173506fd125490bc 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -29,10 +29,12 @@ This section deals with basic functions for OFDM Modulation. */ -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/impl_defs_top.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" - +#include "modulation_common.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" //#define DEBUG_OFDM_MOD diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index 39ae90217f9b336d2afc397bd60106adc4ecb50f..b01979431dcf88212604aa71cf0d0470eb177d06 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -19,8 +19,10 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "defs.h" +#include "PHY/defs_UE.h" +#include "modulation_UE.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" + //#define DEBUG_FEP #define SOFFSET 0 diff --git a/openair1/PHY/MODULATION/slot_fep_mbsfn.c b/openair1/PHY/MODULATION/slot_fep_mbsfn.c index 7b902bb8f1524199980c08a7b9dc3bf1208ed403..272cbc5d60b0566562fb9d838c54f3396ac37b7e 100644 --- a/openair1/PHY/MODULATION/slot_fep_mbsfn.c +++ b/openair1/PHY/MODULATION/slot_fep_mbsfn.c @@ -19,8 +19,10 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "defs.h" +#include "PHY/defs_UE.h" +#include "modulation_UE.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" + //#define DEBUG_FEP #define SOFFSET 0 diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c index 1f2963017e137e940e1c0cbacc5db6c567ae8029..fe5488c73c7f29c136bb9730ca10e1f11149521c 100644 --- a/openair1/PHY/MODULATION/slot_fep_ul.c +++ b/openair1/PHY/MODULATION/slot_fep_ul.c @@ -19,11 +19,13 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "modulation_eNB.h" //#define DEBUG_FEP + + int slot_fep_ul(RU_t *ru, unsigned char l, unsigned char Ns, @@ -134,7 +136,7 @@ int slot_fep_ul(RU_t *ru, } #ifdef DEBUG_FEP - LOG_D(PHY,"slot_fep: done\n"); + // LOG_D(PHY,"slot_fep: done\n"); #endif return(0); } diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz.c b/openair1/PHY/MODULATION/ul_7_5_kHz.c index 80efc70c40cbe1159cdb18ea5414b21287684027..3d1d9c2b0470ad2a46c0b6534e4463d558d5d0ae 100644 --- a/openair1/PHY/MODULATION/ul_7_5_kHz.c +++ b/openair1/PHY/MODULATION/ul_7_5_kHz.c @@ -19,121 +19,11 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "extern.h" -#include "kHz_7_5.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" #include <math.h> #include "PHY/sse_intrin.h" - -short conjugate75[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; -short conjugate75_2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; -short negate[8]__attribute__((aligned(16))) = {-1,-1,-1,-1,-1,-1,-1,-1}; - -void apply_7_5_kHz(PHY_VARS_UE *ue,int32_t*txdata,uint8_t slot) -{ - - - uint16_t len; - uint32_t *kHz7_5ptr; -#if defined(__x86_64__) || defined(__i386__) - __m128i *txptr128,*kHz7_5ptr128,mmtmp_re,mmtmp_im,mmtmp_re2,mmtmp_im2; -#elif defined(__arm__) - int16x8_t *txptr128,*kHz7_5ptr128; - int32x4_t mmtmp_re,mmtmp_im; - int32x4_t mmtmp0,mmtmp1; -#endif - uint32_t slot_offset; - // uint8_t aa; - uint32_t i; - LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - - switch (frame_parms->N_RB_UL) { - - case 6: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s6n_kHz_7_5 : (uint32_t*)s6e_kHz_7_5; - break; - - case 15: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s15n_kHz_7_5 : (uint32_t*)s15e_kHz_7_5; - break; - - case 25: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_kHz_7_5 : (uint32_t*)s25e_kHz_7_5; - break; - - case 50: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s50n_kHz_7_5 : (uint32_t*)s50e_kHz_7_5; - break; - - case 75: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s75n_kHz_7_5 : (uint32_t*)s75e_kHz_7_5; - break; - - case 100: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s100n_kHz_7_5 : (uint32_t*)s100e_kHz_7_5; - break; - - default: - kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_kHz_7_5 : (uint32_t*)s25e_kHz_7_5; - break; - } - - slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2; - len = frame_parms->samples_per_tti/2; - -#if defined(__x86_64__) || defined(__i386__) - txptr128 = (__m128i *)&txdata[slot_offset]; - kHz7_5ptr128 = (__m128i *)kHz7_5ptr; -#elif defined(__arm__) - txptr128 = (int16x8_t*)&txdata[slot_offset]; - kHz7_5ptr128 = (int16x8_t*)kHz7_5ptr; -#endif - // apply 7.5 kHz - - for (i=0; i<(len>>2); i++) { -#if defined(__x86_64__) || defined(__i386__) - mmtmp_re = _mm_madd_epi16(*txptr128,*kHz7_5ptr128); - // Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work) - mmtmp_im = _mm_shufflelo_epi16(*kHz7_5ptr128,_MM_SHUFFLE(2,3,0,1)); - mmtmp_im = _mm_shufflehi_epi16(mmtmp_im,_MM_SHUFFLE(2,3,0,1)); - mmtmp_im = _mm_sign_epi16(mmtmp_im,*(__m128i*)&conjugate75[0]); - mmtmp_im = _mm_madd_epi16(mmtmp_im,txptr128[0]); - mmtmp_re = _mm_srai_epi32(mmtmp_re,15); - mmtmp_im = _mm_srai_epi32(mmtmp_im,15); - mmtmp_re2 = _mm_unpacklo_epi32(mmtmp_re,mmtmp_im); - mmtmp_im2 = _mm_unpackhi_epi32(mmtmp_re,mmtmp_im); - - txptr128[0] = _mm_packs_epi32(mmtmp_re2,mmtmp_im2); - txptr128++; - kHz7_5ptr128++; -#elif defined(__arm__) - - mmtmp0 = vmull_s16(((int16x4_t*)txptr128)[0],((int16x4_t*)kHz7_5ptr128)[0]); - //mmtmp0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] - mmtmp1 = vmull_s16(((int16x4_t*)txptr128)[1],((int16x4_t*)kHz7_5ptr128)[1]); - //mmtmp1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] - mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), - vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); - //mmtmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] - - mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)txptr128)[0],*(int16x4_t*)conjugate75_2)),((int16x4_t*)kHz7_5ptr128)[0]); - //mmtmp0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] - mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)txptr128)[1],*(int16x4_t*)conjugate75_2)), ((int16x4_t*)kHz7_5ptr128)[1]); - //mmtmp0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] - mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), - vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); - //mmtmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - - txptr128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im)); - txptr128++; - kHz7_5ptr128++; -#endif - } - - //} -} - +#include "modulation_extern.h" void remove_7_5_kHz(RU_t *ru,uint8_t slot) { @@ -188,7 +78,7 @@ void remove_7_5_kHz(RU_t *ru,uint8_t slot) } - slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2-ru->N_TA_offset; + slot_offset = ((uint32_t)slot * frame_parms->samples_per_tti/2)-ru->N_TA_offset; slot_offset2 = (uint32_t)(slot&1) * frame_parms->samples_per_tti/2; len = frame_parms->samples_per_tti/2; diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz_ue.c b/openair1/PHY/MODULATION/ul_7_5_kHz_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..3e3a839521b3e5be66c530b0af89172ac0d76ce6 --- /dev/null +++ b/openair1/PHY/MODULATION/ul_7_5_kHz_ue.c @@ -0,0 +1,136 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "modulation_extern.h" +#include <math.h> +#include "PHY/sse_intrin.h" + +extern short conjugate75[8]; +extern short conjugate75_2[8]; +extern short negate[8]; + +void apply_7_5_kHz(PHY_VARS_UE *ue,int32_t*txdata,uint8_t slot) +{ + + + uint16_t len; + uint32_t *kHz7_5ptr; +#if defined(__x86_64__) || defined(__i386__) + __m128i *txptr128,*kHz7_5ptr128,mmtmp_re,mmtmp_im,mmtmp_re2,mmtmp_im2; +#elif defined(__arm__) + int16x8_t *txptr128,*kHz7_5ptr128; + int32x4_t mmtmp_re,mmtmp_im; + int32x4_t mmtmp0,mmtmp1; +#endif + uint32_t slot_offset; + // uint8_t aa; + uint32_t i; + LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; + + switch (frame_parms->N_RB_UL) { + + case 6: + kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s6n_kHz_7_5 : (uint32_t*)s6e_kHz_7_5; + break; + + case 15: + kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s15n_kHz_7_5 : (uint32_t*)s15e_kHz_7_5; + break; + + case 25: + kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_kHz_7_5 : (uint32_t*)s25e_kHz_7_5; + break; + + case 50: + kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s50n_kHz_7_5 : (uint32_t*)s50e_kHz_7_5; + break; + + case 75: + kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s75n_kHz_7_5 : (uint32_t*)s75e_kHz_7_5; + break; + + case 100: + kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s100n_kHz_7_5 : (uint32_t*)s100e_kHz_7_5; + break; + + default: + kHz7_5ptr = (frame_parms->Ncp==0) ? (uint32_t*)s25n_kHz_7_5 : (uint32_t*)s25e_kHz_7_5; + break; + } + + slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2; + len = frame_parms->samples_per_tti/2; + +#if defined(__x86_64__) || defined(__i386__) + txptr128 = (__m128i *)&txdata[slot_offset]; + kHz7_5ptr128 = (__m128i *)kHz7_5ptr; +#elif defined(__arm__) + txptr128 = (int16x8_t*)&txdata[slot_offset]; + kHz7_5ptr128 = (int16x8_t*)kHz7_5ptr; +#endif + // apply 7.5 kHz + + for (i=0; i<(len>>2); i++) { +#if defined(__x86_64__) || defined(__i386__) + mmtmp_re = _mm_madd_epi16(*txptr128,*kHz7_5ptr128); + // Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work) + mmtmp_im = _mm_shufflelo_epi16(*kHz7_5ptr128,_MM_SHUFFLE(2,3,0,1)); + mmtmp_im = _mm_shufflehi_epi16(mmtmp_im,_MM_SHUFFLE(2,3,0,1)); + mmtmp_im = _mm_sign_epi16(mmtmp_im,*(__m128i*)&conjugate75[0]); + mmtmp_im = _mm_madd_epi16(mmtmp_im,txptr128[0]); + mmtmp_re = _mm_srai_epi32(mmtmp_re,15); + mmtmp_im = _mm_srai_epi32(mmtmp_im,15); + mmtmp_re2 = _mm_unpacklo_epi32(mmtmp_re,mmtmp_im); + mmtmp_im2 = _mm_unpackhi_epi32(mmtmp_re,mmtmp_im); + + txptr128[0] = _mm_packs_epi32(mmtmp_re2,mmtmp_im2); + txptr128++; + kHz7_5ptr128++; +#elif defined(__arm__) + + mmtmp0 = vmull_s16(((int16x4_t*)txptr128)[0],((int16x4_t*)kHz7_5ptr128)[0]); + //mmtmp0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] + mmtmp1 = vmull_s16(((int16x4_t*)txptr128)[1],((int16x4_t*)kHz7_5ptr128)[1]); + //mmtmp1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] + mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + //mmtmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] + + mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)txptr128)[0],*(int16x4_t*)conjugate75_2)),((int16x4_t*)kHz7_5ptr128)[0]); + //mmtmp0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] + mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)txptr128)[1],*(int16x4_t*)conjugate75_2)), ((int16x4_t*)kHz7_5ptr128)[1]); + //mmtmp0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] + mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)), + vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1))); + //mmtmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] + + txptr128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im)); + txptr128++; + kHz7_5ptr128++; +#endif + } + + //} +} + + diff --git a/openair1/PHY/NBIoT_TRANSPORT/README b/openair1/PHY/NBIoT_TRANSPORT/README new file mode 100644 index 0000000000000000000000000000000000000000..938b70815c5e7019b0ca89013a71855a032d6d1f --- /dev/null +++ b/openair1/PHY/NBIoT_TRANSPORT/README @@ -0,0 +1 @@ +NB-IoT transport channel procedures for NB-IoT are here diff --git a/openair1/PHY/NR_REFSIG/README b/openair1/PHY/NR_REFSIG/README new file mode 100644 index 0000000000000000000000000000000000000000..ea7e5013f9e3581965eba215f182b50a874e54a7 --- /dev/null +++ b/openair1/PHY/NR_REFSIG/README @@ -0,0 +1 @@ +Reference signal definitions for NR diff --git a/openair1/PHY/NR_TRANSPORT/README b/openair1/PHY/NR_TRANSPORT/README new file mode 100644 index 0000000000000000000000000000000000000000..fc7dd3a338c8bfd129e29409052284ee25c642ea --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/README @@ -0,0 +1 @@ +NR gNB transport channel procedures are here diff --git a/openair1/PHY/NR_UE_TRANSPORT/README b/openair1/PHY/NR_UE_TRANSPORT/README new file mode 100644 index 0000000000000000000000000000000000000000..62393afe9343c5c70ce98a48ffa2a7756ab05d34 --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/README @@ -0,0 +1 @@ +UE NR transport/physical channel procedures are here diff --git a/openair1/PHY/TOOLS/cadd_vv.c b/openair1/PHY/TOOLS/cadd_vv.c index 34808552fcaab7966d46249853b2ed4a6c9093d8..77346a97f7facdcf1e68a78b7397a709d9af6b12 100644 --- a/openair1/PHY/TOOLS/cadd_vv.c +++ b/openair1/PHY/TOOLS/cadd_vv.c @@ -19,7 +19,8 @@ * contact@openairinterface.org */ -#include "defs.h" +#include "PHY/defs_common.h" +#include "tools_defs.h" int add_vector16(short *x, diff --git a/openair1/PHY/TOOLS/cdot_prod.c b/openair1/PHY/TOOLS/cdot_prod.c index 91ba246bddf51afeb637976ace75c8decec83cae..60bdcf45dd722f98a3eccab80a76963e01f9db1a 100644 --- a/openair1/PHY/TOOLS/cdot_prod.c +++ b/openair1/PHY/TOOLS/cdot_prod.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -#include "defs.h" +#include "tools_defs.h" #include "PHY/sse_intrin.h" // returns the complex dot product of x and y diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index 61970ca2b69afa6d8ce38df8fe9d3bf3cc9c9636..013fedc6e9204ed042a7f1025434301532b93656 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -20,7 +20,7 @@ */ #include "PHY/sse_intrin.h" -#include "defs.h" +#include "tools_defs.h" #if defined(__x86_64__) || defined(__i386__) #define simd_q15_t __m128i diff --git a/openair1/PHY/TOOLS/cmult_vv.c b/openair1/PHY/TOOLS/cmult_vv.c index 13facf69077a165a0f6c05378bb1f847c6c4ab0b..ce3ebec65fe0e29f4bd34e816f484902e7531112 100644 --- a/openair1/PHY/TOOLS/cmult_vv.c +++ b/openair1/PHY/TOOLS/cmult_vv.c @@ -19,7 +19,8 @@ * contact@openairinterface.org */ -#include "defs.h" +#include "PHY/defs_common.h" +#include "tools_defs.h" #include <stdio.h> #if defined(__x86_64__) || defined(__i386__) diff --git a/openair1/PHY/TOOLS/dB_routines.c b/openair1/PHY/TOOLS/dB_routines.c index c99703eaf3c6139682f098aa932691a6522bcfc5..572759a68ca14ed47c4ba785816dc3ddf99f27c2 100644 --- a/openair1/PHY/TOOLS/dB_routines.c +++ b/openair1/PHY/TOOLS/dB_routines.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -#include "defs.h" +#include "tools_defs.h" // Approximate 10*log10(x) in fixed point : x = 0...(2^32)-1 diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index e0e171f6bfc601fd839fe40e4b8ead6a29a69b23..9a5a504ec41eea3d6f69ecf84ed20e5d03c0ed9f 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -26,9 +26,9 @@ #include <stdint.h> #ifndef MR_MAIN -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "defs.h" +#include "PHY/defs_common.h" +#include "PHY/impl_defs_top.h" +#include "tools_defs.h" #else #include "time_meas.h" #include <math.h> @@ -2047,6 +2047,8 @@ const static int16_t tw16c[24] __attribute__((aligned(32))) = { 0,32767,12540,30 0,32767,30273,12539,23170,-23170,-12539,-30273 }; +#ifdef __AVX2__ + const static int16_t tw16rep[48] __attribute__((aligned(32))) = { 32767,0,30272,-12540,23169 ,-23170,12539 ,-30273,32767,0,30272,-12540,23169 ,-23170,12539 ,-30273, 32767,0,23169,-23170,0 ,-32767,-23170,-23170,32767,0,23169,-23170,0 ,-32767,-23170,-23170, 32767,0,12539,-30273,-23170,-23170,-30273,12539,32767,0,12539,-30273,-23170,-23170,-30273,12539 @@ -2067,6 +2069,8 @@ const static int16_t tw16crep[48] __attribute__((aligned(32))) = { 0,32767,12540 0,32767,30273,12539,23170,-23170,-12539,-30273,0,32767,30273,12539,23170,-23170,-12539,-30273 }; +#endif /* __AVX2__ */ + static inline void dft16(int16_t *x,int16_t *y) __attribute__((always_inline)); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 30e57c1c62530e80a22c22d979e9a887f297231f..9f2ec54744941e783e0cb27cabeb19b93c95e4d5 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -23,6 +23,8 @@ #include <stdlib.h> #include "lte_phy_scope.h" +#include "PHY/defs_common.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #define TPUT_WINDOW_LENGTH 100 int otg_enabled; @@ -162,7 +164,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, int16_t **chest_t; int16_t **chest_f; int16_t *pusch_llr; - int16_t *pusch_comp; + int32_t *pusch_comp; int32_t *pucch1_comp; int32_t *pucch1_thres; int32_t *pucch1ab_comp; @@ -200,7 +202,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates[eNB_id]; chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0]; + pusch_comp = (int32_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; diff --git a/openair1/PHY/TOOLS/lte_phy_scope.h b/openair1/PHY/TOOLS/lte_phy_scope.h index 1d2b2ea1ed99c5b579aaa6f77b16bf5485108a7d..af9858ebad97796def7d13b4d007171fd61ca920 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.h +++ b/openair1/PHY/TOOLS/lte_phy_scope.h @@ -25,10 +25,9 @@ #define FD_lte_scope_h_ #include <forms.h> -#include "../impl_defs_lte.h" -#include "../impl_defs_top.h" -#include "../defs.h" -#include "../../SCHED/defs.h" // for OPENAIR_DAQ_VARS +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/impl_defs_top.h" /* Forms and Objects */ diff --git a/openair1/PHY/TOOLS/signal_energy.c b/openair1/PHY/TOOLS/signal_energy.c index 918d2e3ba0043c636dcd67a2a875f338e7234063..13f37c4c8dbe9de6362a63abe6bd0f174321c9ef 100644 --- a/openair1/PHY/TOOLS/signal_energy.c +++ b/openair1/PHY/TOOLS/signal_energy.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -#include "defs.h" +#include "tools_defs.h" #include "PHY/sse_intrin.h" diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c index d80832e243c9b0af7cea98e1d3da9fca0ff01b67..cb7775904099a769091795d62d23cc1b1d950b25 100644 --- a/openair1/PHY/TOOLS/time_meas.c +++ b/openair1/PHY/TOOLS/time_meas.c @@ -53,7 +53,7 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){ if (ts->trials>0) { //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->diff_now/(cpu_freq_GHz*1000000.0)),subframe,ts->diff_now); - fprintf(file_name,"%15.3f ms, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000000.0)),(double)ts->diff_now); + fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000.0)),(double)ts->diff_now); } } diff --git a/openair1/PHY/TOOLS/defs.h b/openair1/PHY/TOOLS/tools_defs.h similarity index 99% rename from openair1/PHY/TOOLS/defs.h rename to openair1/PHY/TOOLS/tools_defs.h index b92c2a42367b59acae680d167af8665f3de7093e..e3b04babdc8f2320f3a319914fbaefbaa20f4a2a 100644 --- a/openair1/PHY/TOOLS/defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -30,7 +30,6 @@ */ #include <stdint.h> - #include "PHY/sse_intrin.h" diff --git a/openair1/PHY/MODULATION/extern.h b/openair1/PHY/TOOLS/tools_extern.h similarity index 100% rename from openair1/PHY/MODULATION/extern.h rename to openair1/PHY/TOOLS/tools_extern.h diff --git a/openair1/PHY/TOOLS/extern.h b/openair1/PHY/TOOLS/tools_vars.h similarity index 100% rename from openair1/PHY/TOOLS/extern.h rename to openair1/PHY/TOOLS/tools_vars.h diff --git a/openair1/PHY/TOOLS/vars.h b/openair1/PHY/TOOLS/vars.h deleted file mode 100644 index 4690bba42e5b91f4721d727b38d41da928e0c55a..0000000000000000000000000000000000000000 --- a/openair1/PHY/TOOLS/vars.h +++ /dev/null @@ -1,21 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 - */ - diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..bb08d5122dd68033f1c7871a37faabd4a1355a68 --- /dev/null +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -0,0 +1,1029 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/defs.h + \brief Top-level defines and structure definitions + \author R. Knopp, F. Kaltenberger + \date 2011 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr + \note + \warning +*/ +#ifndef __PHY_DEFS_NB_IOT__H__ +#define __PHY_DEFS_NB_IOT__H__ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <string.h> +#include <math.h> +#include "common_lib.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "defs_eNB.h" +//#include <complex.h> +#include "assertions.h" +#ifdef MEX +# define msg mexPrintf +#else +# ifdef OPENAIR2 +# if ENABLE_RAL +# include "collection/hashtable/hashtable.h" +# include "COMMON/ral_messages_types.h" +# include "UTIL/queue.h" +# endif +# include "log.h" +# define msg(aRGS...) LOG_D(PHY, ##aRGS) +# else +# define msg printf +# endif +#endif +//use msg in the real-time thread context +#define msg_nrt printf +//use msg_nrt in the non real-time context (for initialization, ...) +#ifndef malloc16 +# ifdef __AVX2__ +# define malloc16(x) memalign(32,x) +# else +# define malloc16(x) memalign(16,x) +# endif +#endif +#define free16(y,x) free(y) +#define bigmalloc malloc +#define bigmalloc16 malloc16 +#define openair_free(y,x) free((y)) +#define PAGE_SIZE 4096 + +//#ifdef SHRLIBDEV +//extern int rxrescale; +//#define RX_IQRESCALELEN rxrescale +//#else +//#define RX_IQRESCALELEN 15 +//#endif + +//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards. +//! If no more memory is available, this function will terminate the program with an assertion error. +//****************************************************************************************************** +/* +static inline void* malloc16_clear( size_t size ) +{ +#ifdef __AVX2__ + void* ptr = memalign(32, size); +#else + void* ptr = memalign(16, size); +#endif + DevAssert(ptr); + memset( ptr, 0, size ); + return ptr; +} + +*/ + + +// #define PAGE_MASK 0xfffff000 +// #define virt_to_phys(x) (x) + +// #define openair_sched_exit() exit(-1) + + +// #define max(a,b) ((a)>(b) ? (a) : (b)) +// #define min(a,b) ((a)<(b) ? (a) : (b)) + + +// #define bzero(s,n) (memset((s),0,(n))) + +// #define cmax(a,b) ((a>b) ? (a) : (b)) +// #define cmin(a,b) ((a<b) ? (a) : (b)) + +// #define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) + +// /// suppress compiler warning for unused arguments +// #define UNUSED(x) (void)x; + + +#include "PHY/impl_defs_top_NB_IoT.h" +//#include "impl_defs_top.h" +//#include "impl_defs_lte.h" +#include "PHY/impl_defs_lte_NB_IoT.h" + +#include "PHY/TOOLS/time_meas.h" +//#include "PHY/CODING/defs.h" +#include "PHY/CODING/defs_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +//#include "PHY/TOOLS/defs.h" +//#include "platform_types.h" +///#include "openair1/PHY/LTE_TRANSPORT/defs_nb_iot.h" + +////////////////////////////////////////////////////////////////////#ifdef OPENAIR_LTE (check if this is required) + +//#include "PHY/LTE_TRANSPORT/defs.h" +#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include <pthread.h> + +#include "targets/ARCH/COMMON/common_lib.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#define NUM_DCI_MAX_NB_IoT 32 + +#define NUMBER_OF_eNB_SECTORS_MAX_NB_IoT 3 + +#define NB_BANDS_MAX_NB_IoT 8 + + +#ifdef OCP_FRAMEWORK +#include <enums.h> +#else +typedef enum {normal_txrx_NB_IoT=0,rx_calib_ue_NB_IoT=1,rx_calib_ue_med_NB_IoT=2,rx_calib_ue_byp_NB_IoT=3,debug_prach_NB_IoT=4,no_L2_connect_NB_IoT=5,calib_prach_tx_NB_IoT=6,rx_dump_frame_NB_IoT=7,loop_through_memory_NB_IoT=8} runmode_NB_IoT_t; +#endif +/* +enum transmission_access_mode { + NO_ACCESS=0, + POSTPONED_ACCESS, + CANCELED_ACCESS, + UNKNOWN_ACCESS, + SCHEDULED_ACCESS, + CBA_ACCESS}; + +typedef enum { + eNodeB_3GPP=0, // classical eNodeB function + eNodeB_3GPP_BBU, // eNodeB with NGFI IF5 + NGFI_RCC_IF4p5, // NGFI_RCC (NGFI radio cloud center) + NGFI_RAU_IF4p5, + NGFI_RRU_IF5, // NGFI_RRU (NGFI remote radio-unit,IF5) + NGFI_RRU_IF4p5 // NGFI_RRU (NGFI remote radio-unit,IF4p5) +} eNB_func_t; + +typedef enum { + synch_to_ext_device=0, // synch to RF or Ethernet device + synch_to_other // synch to another source (timer, other CC_id) +} eNB_timing_t; +#endif +*/ +typedef struct UE_SCAN_INFO_NB_IoT_s { + /// 10 best amplitudes (linear) for each pss signals + int32_t amp[3][10]; + /// 10 frequency offsets (kHz) corresponding to best amplitudes, with respect do minimum DL frequency in the band + int32_t freq_offset_Hz[3][10]; + +} UE_SCAN_INFO_NB_IoT_t; + +/// Top-level PHY Data Structure for RN +typedef struct { + /// Module ID indicator for this instance + uint8_t Mod_id; + uint32_t frame; + // phy_vars_eNB_NB_IoT + // phy_vars ue + // cuurently only used to store and forward the PMCH + uint8_t mch_avtive[10]; + uint8_t sync_area[10]; // num SF + NB_IoT_UE_DLSCH_t *dlsch_rn_MCH[10]; + +} PHY_VARS_RN_NB_IoT; +/* +#ifdef OCP_FRAMEWORK +#include <enums.h> +#else +//typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5,calib_prach_tx=6,rx_dump_frame=7,loop_through_memory=8} runmode_t; +*/ +// enum transmission_access_mode { +// NO_ACCESS=0, +// POSTPONED_ACCESS, +// CANCELED_ACCESS, +// UNKNOWN_ACCESS, +// SCHEDULED_ACCESS, +// CBA_ACCESS}; + +typedef enum { + eNodeB_3GPP_NB_IoT=0, // classical eNodeB function + eNodeB_3GPP_BBU_NB_IoT, // eNodeB with NGFI IF5 + NGFI_RCC_IF4p5_NB_IoT, // NGFI_RCC (NGFI radio cloud center) + NGFI_RAU_IF4p5_NB_IoT, + NGFI_RRU_IF5_NB_IoT, // NGFI_RRU (NGFI remote radio-unit,IF5) + NGFI_RRU_IF4p5_NB_IoT // NGFI_RRU (NGFI remote radio-unit,IF4p5) +} eNB_func_NB_IoT_t; + +typedef enum { + + synch_to_ext_device_NB_IoT=0, // synch to RF or Ethernet device + synch_to_other_NB_IoT // synch to another source (timer, other CC_id) + +} eNB_timing_NB_IoT_t; +////////////////////////////////////////////////////////////////////#endif + + +typedef struct { + + struct PHY_VARS_eNB_NB_IoT_s *eNB; + NB_IoT_eNB_NDLSCH_t *dlsch; + int G; + +} te_params_NB_IoT; + + +typedef struct { + + struct PHY_VARS_eNB_NB_IoT_s *eNB; + int UE_id; + int harq_pid; + int llr8_flag; + int ret; + +} td_params_NB_IoT; + + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_rxtx; + /// scheduling parameters for RXn-TXnp4 thread + struct sched_param sched_param_rxtx; + /// NB-IoT for IF_Module + pthread_t pthread_l2; + pthread_cond_t cond_l2; + pthread_mutex_t mutex_l2; + int instance_cnt_l2; + pthread_attr_t attr_l2; + +} eNB_rxtx_proc_NB_IoT_t; +/* +typedef struct { + struct PHY_VARS_eNB_NB_IoT_s *eNB; + int UE_id; + int harq_pid; + int llr8_flag; + int ret; +} td_params; + +typedef struct { + struct PHY_VARS_eNB_NB_IoT_s *eNB; + LTE_eNB_DLSCH_t *dlsch; + int G; +} te_params; +*/ + +/// Context data structure for eNB subframe processing +typedef struct eNB_proc_NB_IoT_t_s { + /// thread index + int thread_index; + /// timestamp received from HW + openair0_timestamp timestamp_rx; + /// timestamp to send to "slave rru" + openair0_timestamp timestamp_tx; + /// subframe to act upon for reception + int subframe_rx; + /// symbol mask for IF4p5 reception per subframe + uint32_t symbol_mask[10]; + /// subframe to act upon for PRACH + int subframe_prach; + /// frame to act upon for reception + int frame_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame offset for secondary eNBs (to correct for frame asynchronism at startup) + int frame_offset; + /// frame to act upon for PRACH + int frame_prach; + /// \internal This variable is protected by \ref mutex_fep. + int instance_cnt_fep; + /// \internal This variable is protected by \ref mutex_td. + int instance_cnt_td; + /// \internal This variable is protected by \ref mutex_te. + int instance_cnt_te; + /// \brief Instance count for FH processing thread. + /// \internal This variable is protected by \ref mutex_FH. + int instance_cnt_FH; + /// \brief Instance count for rx processing thread. + /// \internal This variable is protected by \ref mutex_prach. + int instance_cnt_prach; + // instance count for over-the-air eNB synchronization + int instance_cnt_synch; + /// \internal This variable is protected by \ref mutex_asynch_rxtx. + int instance_cnt_asynch_rxtx; + /// pthread structure for FH processing thread + pthread_t pthread_FH; + /// pthread structure for asychronous RX/TX processing thread + pthread_t pthread_asynch_rxtx; + /// flag to indicate first RX acquisition + int first_rx; + /// flag to indicate first TX transmission + int first_tx; + /// pthread attributes for parallel fep thread + pthread_attr_t attr_fep; + /// pthread attributes for parallel turbo-decoder thread + pthread_attr_t attr_td; + /// pthread attributes for parallel turbo-encoder thread + pthread_attr_t attr_te; + /// pthread attributes for FH processing thread + pthread_attr_t attr_FH; + /// pthread attributes for single eNB processing thread + pthread_attr_t attr_single; + /// pthread attributes for prach processing thread + pthread_attr_t attr_prach; + /// pthread attributes for over-the-air synch thread + pthread_attr_t attr_synch; + /// pthread attributes for asynchronous RX thread + pthread_attr_t attr_asynch_rxtx; + /// scheduling parameters for parallel fep thread + struct sched_param sched_param_fep; + /// scheduling parameters for parallel turbo-decoder thread + struct sched_param sched_param_td; + /// scheduling parameters for parallel turbo-encoder thread + struct sched_param sched_param_te; + /// scheduling parameters for FH thread + struct sched_param sched_param_FH; + /// scheduling parameters for single eNB thread + struct sched_param sched_param_single; + /// scheduling parameters for prach thread + struct sched_param sched_param_prach; + /// scheduling parameters for over-the-air synchronization thread + struct sched_param sched_param_synch; + /// scheduling parameters for asynch_rxtx thread + struct sched_param sched_param_asynch_rxtx; + /// pthread structure for parallel fep thread + pthread_t pthread_fep; + /// pthread structure for parallel turbo-decoder thread + pthread_t pthread_td; + /// pthread structure for parallel turbo-encoder thread + pthread_t pthread_te; + /// pthread structure for PRACH thread + pthread_t pthread_prach; + /// pthread structure for eNB synch thread + pthread_t pthread_synch; + /// condition variable for parallel fep thread + pthread_cond_t cond_fep; + /// condition variable for parallel turbo-decoder thread + pthread_cond_t cond_td; + /// condition variable for parallel turbo-encoder thread + pthread_cond_t cond_te; + /// condition variable for FH thread + pthread_cond_t cond_FH; + /// condition variable for PRACH processing thread; + pthread_cond_t cond_prach; + // condition variable for over-the-air eNB synchronization + pthread_cond_t cond_synch; + /// condition variable for asynch RX/TX thread + pthread_cond_t cond_asynch_rxtx; + /// mutex for RU access to processing (NPDSCH/PUSCH) + pthread_mutex_t mutex_RU; + /// mutex for parallel fep thread + pthread_mutex_t mutex_fep; + /// mutex for parallel turbo-decoder thread + pthread_mutex_t mutex_td; + /// mutex for parallel turbo-encoder thread + pthread_mutex_t mutex_te; + /// mutex for FH + pthread_mutex_t mutex_FH; + /// mutex for PRACH thread + pthread_mutex_t mutex_prach; + // mutex for over-the-air eNB synchronization + pthread_mutex_t mutex_synch; + /// mutex for RU access to NB-IoT processing (NPRACH) + pthread_mutex_t mutex_RU_PRACH; + /// mutex for asynch RX/TX thread + pthread_mutex_t mutex_asynch_rxtx; + /// mask for RUs serving nbiot (NPDSCH/NPUSCH) + int RU_mask; + /// mask for RUs serving nbiot (PRACH) + int RU_mask_prach; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// mask for RUs serving eNB (PRACH) + int RU_mask_prach_br; +#endif + /// parameters for turbo-decoding worker thread + td_params_NB_IoT tdp; + /// parameters for turbo-encoding worker thread + te_params_NB_IoT tep; + /// number of slave threads + int num_slaves; + /// array of pointers to slaves + struct eNB_proc_NB_IoT_t_s **slave_proc; + /// set of scheduling variables RXn-TXnp4 threads + // newly added for NB_IoT + eNB_rxtx_proc_NB_IoT_t proc_rxtx[2]; + +} eNB_proc_NB_IoT_t; + + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// index of the current UE RX/TX proc + int proc_id; + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + 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_NB_IoT_t; + +/// Context data structure for eNB subframe processing +typedef struct { + /// Last RX timestamp + openair0_timestamp timestamp_rx; + /// pthread attributes for main UE thread + pthread_attr_t attr_ue; + /// scheduling parameters for main UE thread + struct sched_param sched_param_ue; + /// pthread descriptor main UE thread + pthread_t pthread_ue; + /// \brief Instance count for synch thread. + /// \internal This variable is protected by \ref mutex_synch. + int instance_cnt_synch; + /// pthread attributes for synch processing thread + pthread_attr_t attr_synch; + /// scheduling parameters for synch thread + struct sched_param sched_param_synch; + /// pthread descriptor synch thread + pthread_t pthread_synch; + /// condition variable for UE synch thread; + pthread_cond_t cond_synch; + /// mutex for UE synch thread + pthread_mutex_t mutex_synch; + /// set of scheduling variables RXn-TXnp4 threads + UE_rxtx_proc_NB_IoT_t proc_rxtx[2]; + +} UE_proc_NB_IoT_t; + + + +/// Top-level PHY Data Structure for eNB +typedef struct PHY_VARS_eNB_NB_IoT_s { + /// Module ID indicator for this instance + module_id_t Mod_id; + uint8_t configured; + eNB_proc_NB_IoT_t proc; + int num_RU; + RU_t *RU_list[MAX_NUM_RU_PER_eNB]; + /// Ethernet parameters for northbound midhaul interface (L1 to Mac) + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface (upper L1 to Radio head) + eth_params_t eth_params; + int single_thread_flag; + openair0_rf_map rf_map; + int abstraction_flag; + openair0_timestamp ts_offset; + // indicator for synchronization state of eNB + int in_synch; + // indicator for master/slave (RRU) + int is_slave; + // indicator for precoding function (eNB,3GPP_eNB_BBU) + int do_precoding; + IF_Module_NB_IoT_t *if_inst_NB_IoT; + UL_IND_NB_IoT_t UL_INFO_NB_IoT; + pthread_mutex_t UL_INFO_mutex; + void (*do_prach)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int frame,int subframe); + void (*fep)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc); + int (*td)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int UE_id,int harq_pid,int llr8_flag); + int (*te)(struct PHY_VARS_eNB_NB_IoT_s *,uint8_t *,uint8_t,NB_IoT_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); + void (*proc_uespec_rx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,const relaying_type_t_NB_IoT r_type); + void (*proc_tx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,relaying_type_t_NB_IoT r_type,PHY_VARS_RN_NB_IoT *rn); + void (*tx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc); + void (*rx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe); + int (*start_rf)(struct PHY_VARS_eNB_NB_IoT_s *eNB); + int (*start_if)(struct PHY_VARS_eNB_NB_IoT_s *eNB); + void (*fh_asynch)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe); + uint8_t local_flag; + uint32_t rx_total_gain_dB; + NB_IoT_DL_FRAME_PARMS frame_parms; + PHY_MEASUREMENTS_eNB_NB_IoT measurements[NUMBER_OF_eNB_SECTORS_MAX_NB_IoT]; /// Measurement variables + NB_IoT_eNB_COMMON common_vars; + NB_IoT_eNB_SRS srs_vars[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_PBCH pbch; + NB_IoT_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_PRACH prach_vars; + //LTE_eNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX_NB_IoT][2]; // Nusers times two spatial streams + NB_IoT_eNB_NULSCH_t *ulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; // Nusers + number of RA (the ulsch[0] contains RAR) + //LTE_eNB_DLSCH_t *dlsch_SI,*dlsch_ra; + //LTE_eNB_DLSCH_t *dlsch_MCH; + NB_IoT_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX_NB_IoT]; + //LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX_NB_IoT]; + /// cell-specific reference symbols + uint32_t lte_gold_table_NB_IoT[20][2][14]; + /// UE-specific reference symbols (p=5), TM 7 + uint32_t lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX_NB_IoT][20][38]; + /// UE-specific reference symbols (p=7...14), TM 8/9/10 + uint32_t lte_gold_uespec_table[2][20][2][21]; + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_table[10][3][42]; + /// + uint32_t X_u[64][839]; + /// + uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE + /// + char eNB_generate_rar; + /// Indicator set to 0 after first SR + uint8_t first_sr[NUMBER_OF_UE_MAX_NB_IoT]; + + uint32_t max_peak_val; + /// + int max_eNB_id, max_sync_pos; + /// + int N_TA_offset; ///timing offset used in TDD + /// \brief sinr for all subcarriers of the current link (used only for abstraction). + /// first index: ? [0..N_RB_DL*12[ + double *sinr_dB; + /// N0 (used for abstraction) + double N0; + /// + unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX_NB_IoT]; + unsigned char first_run_I0_measurements; + + unsigned char cooperation_flag; // for cooperative communication + + unsigned char is_secondary_eNB; // primary by default + unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system. + unsigned char has_valid_precoder; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created. + unsigned char PeNB_id; /// id of Primary eNB + int rx_offset; /// Timing offset (used if is_secondary_eNB) + + /// hold the precoder for NULL beam to the primary user + int **dl_precoder_SeNB[3]; + /// + char log2_maxp; /// holds the maximum channel/precoder coefficient + /// if ==0 enables phy only test mode + int mac_enabled; + /// For emulation only (used by UE abstraction to retrieve DCI) + uint8_t num_common_dci[2]; // num_dci in even/odd subframes + /// + uint8_t num_ue_spec_dci[2]; // num_dci in even/odd subframes + /// + DCI_ALLOC_NB_IoT_t dci_alloc[2][NUM_DCI_MAX_NB_IoT]; // dci_alloc from even/odd subframes + ///////////// + // PDSCH Variables + PDSCH_CONFIG_DEDICATED_NB_IoT pdsch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // PUSCH Variables + PUSCH_CONFIG_DEDICATED_NB_IoT pusch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // PUCCH variables + PUCCH_CONFIG_DEDICATED_NB_IoT pucch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // UL-POWER-Control + UL_POWER_CONTROL_DEDICATED_NB_IoT ul_power_control_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // TPC + TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX_NB_IoT]; + /// + TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX_NB_IoT]; + // CQI reporting + CQI_REPORT_CONFIG_NB_IoT cqi_report_config[NUMBER_OF_UE_MAX_NB_IoT]; + // SRS Variables + SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + /// + uint8_t ncs_cell[20][7]; + // Scheduling Request Config + SCHEDULING_REQUEST_CONFIG_NB_IoT scheduling_request_config[NUMBER_OF_UE_MAX_NB_IoT]; + // Transmission mode per UE + uint8_t transmission_mode[NUMBER_OF_UE_MAX_NB_IoT]; + /// cba_last successful reception for each group, used for collision detection + uint8_t cba_last_reception[4]; + // Pointers for active physicalConfigDedicated to be applied in current subframe + struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX_NB_IoT]; + //Pointers for actve physicalConfigDedicated for NB-IoT to be applied in current subframe + struct PhysicalConfigDedicated_NB_r13 *phy_config_dedicated_NB_IoT[NUMBER_OF_UE_MAX_NB_IoT]; + /// + uint32_t rb_mask_ul[4]; + /// Information regarding TM5 + MU_MIMO_mode_NB_IoT mu_mimo_mode[NUMBER_OF_UE_MAX_NB_IoT]; + /// target_ue_dl_mcs : only for debug purposes + uint32_t target_ue_dl_mcs; + /// target_ue_ul_mcs : only for debug purposes + uint32_t target_ue_ul_mcs; + /// target_ue_dl_rballoc : only for debug purposes + uint32_t ue_dl_rb_alloc; + /// target ul PRBs : only for debug + uint32_t ue_ul_nb_rb; + ///check for Total Transmissions + uint32_t check_for_total_transmissions; + ///check for MU-MIMO Transmissions + uint32_t check_for_MUMIMO_transmissions; + ///check for SU-MIMO Transmissions + uint32_t check_for_SUMIMO_transmissions; + ///check for FULL MU-MIMO Transmissions + uint32_t FULL_MUMIMO_transmissions; + /// Counter for total bitrate, bits and throughput in downlink + uint32_t total_dlsch_bitrate; + /// + uint32_t total_transmitted_bits; + /// + uint32_t total_system_throughput; + /// + int hw_timing_advance; + /// + time_stats_t phy_proc; + time_stats_t phy_proc_tx; + time_stats_t phy_proc_rx; + time_stats_t rx_prach; + + time_stats_t ofdm_mod_stats; + time_stats_t dlsch_encoding_stats; + time_stats_t dlsch_modulation_stats; + time_stats_t dlsch_scrambling_stats; + time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_interleaving_stats; + + time_stats_t ofdm_demod_stats; + time_stats_t rx_dft_stats; + time_stats_t ulsch_channel_estimation_stats; + time_stats_t ulsch_freq_offset_estimation_stats; + time_stats_t ulsch_decoding_stats; + time_stats_t ulsch_demodulation_stats; + time_stats_t ulsch_rate_unmatching_stats; + time_stats_t ulsch_turbo_decoding_stats; + time_stats_t ulsch_deinterleaving_stats; + time_stats_t ulsch_demultiplexing_stats; + time_stats_t ulsch_llr_stats; + time_stats_t ulsch_tc_init_stats; + time_stats_t ulsch_tc_alpha_stats; + time_stats_t ulsch_tc_beta_stats; + time_stats_t ulsch_tc_gamma_stats; + time_stats_t ulsch_tc_ext_stats; + time_stats_t ulsch_tc_intl1_stats; + time_stats_t ulsch_tc_intl2_stats; + + #ifdef LOCALIZATION + /// time state for localization + time_stats_t localization_stats; + #endif + + int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10]; + int32_t pucch1_stats[NUMBER_OF_UE_MAX_NB_IoT][10*1024]; + int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX_NB_IoT][10*1024]; + int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10]; + int32_t pucch1ab_stats[NUMBER_OF_UE_MAX_NB_IoT][2*10*1024]; + int32_t pusch_stats_rb[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_round[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_BO[NUMBER_OF_UE_MAX_NB_IoT][10240]; + + /// RF and Interface devices per CC + openair0_device rfdevice; + openair0_device ifdevice; + /// Pointer for ifdevice buffer struct + if_buffer_t ifbuffer; + + //------------------------ + // NB-IoT + //------------------------ + + /* + * NUMBER_OF_UE_MAX_NB_IoT maybe in the future should be dynamic because could be very large and the memory may explode + * (is almost the indication of the number of UE context that we are storing at PHY layer) + * + * reasoning: the following data structure (ndlsch, nulsch ecc..) are used to store the context that should be transmitted in at least n+4 subframe later + * (the minimum interval between NPUSCH and the ACK for this) + * the problem is that in NB_IoT the ACK for the UPLINK is contained in the DCI through the NDI field (if this value change from the previous one then it means ACK) + * but may we could schedule this DCI long time later so may lots of contents shuld be stored (there is no concept of phich channel in NB-IoT) + * For the DL transmission the UE send a proper ACK/NACK message + * + * *the HARQ process should be killed when the NDI change + * + * *In the Structure for nulsch we should also store the information related to the subframe (because each time we should read it and understand what should be done + * in that subframe) + * + */ + + + /* + * TIMING + * the entire transmission and scheduling are done for the "subframe" concept but the subframe = proc->subframe_tx (that in reality is the subframe_rx +4) + * (see USER/lte-enb/wakeup_rxtx ) + * + * Related to FAPI: + * DCI and DL_CONFIG.request (also more that 1) and MAC_PDU are transmitted in the same subframe (our assumption) so will be all contained in the schedule_response getting from the scheduler + * DCI0 and UL_CONFIG.request are transmitted in the same subframe (our assumption) so contained in the schedule_response + * + */ + + //TODO: check what should be NUMBER_OF_UE_MAX_NB_IoT value + NB_IoT_eNB_NPBCH_t *npbch; + NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT][2]; + NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR + NB_IoT_eNB_NDLSCH_t *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1; + + NB_IoT_DL_FRAME_PARMS frame_parms_NB_IoT; + // DCI for at most 2 DCI pdus + DCI_PDU_NB_IoT *DCI_pdu; + + + +} PHY_VARS_eNB_NB_IoT; + +//#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg + +/// Top-level PHY Data Structure for UE +typedef struct { + /// \brief Module ID indicator for this instance + uint8_t Mod_id; + /// \brief Mapping of CC_id antennas to cards + openair0_rf_map rf_map; + //uint8_t local_flag; + /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach) + runmode_NB_IoT_t mode; + /// \brief Indicator that UE should perform band scanning + int UE_scan; + /// \brief Indicator that UE should perform coarse scanning around carrier + int UE_scan_carrier; + /// \brief Indicator that UE is synchronized to an eNB + int is_synchronized; + /// Data structure for UE process scheduling + UE_proc_NB_IoT_t proc; + /// Flag to indicate the UE shouldn't do timing correction at all + int no_timing_correction; + /// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna) + uint32_t tx_total_gain_dB; + /// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card. + uint32_t rx_total_gain_dB; + /// \brief Total gains with maximum RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_max[4]; + /// \brief Total gains with medium RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_med[4]; + /// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_byp[4]; + /// \brief Current transmit power + int16_t tx_power_dBm[10]; + /// \brief Total number of REs in current transmission + int tx_total_RE[10]; + /// \brief Maximum transmit power + int8_t tx_power_max_dBm; + /// \brief Number of eNB seen by UE + uint8_t n_connected_eNB; + /// \brief indicator that Handover procedure has been initiated + uint8_t ho_initiated; + /// \brief indicator that Handover procedure has been triggered + uint8_t ho_triggered; + /// \brief Measurement variables. + PHY_MEASUREMENTS_NB_IoT measurements; + NB_IoT_DL_FRAME_PARMS frame_parms; + /// \brief Frame parame before ho used to recover if ho fails. + NB_IoT_DL_FRAME_PARMS frame_parms_before_ho; + NB_IoT_UE_COMMON common_vars; + + NB_IoT_UE_PDSCH *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads + NB_IoT_UE_DLSCH_t *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads + //Paging parameters + uint32_t IMSImod1024; + uint32_t PF; + uint32_t PO; + // For abstraction-purposes only + uint8_t sr[10]; + uint8_t pucch_sel[10]; + uint8_t pucch_payload[22]; + //UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + //cell-specific reference symbols + uint32_t lte_gold_table[7][20][2][14]; + //UE-specific reference symbols (p=5), TM 7 + uint32_t lte_gold_uespec_port5_table[20][38]; + //ue-specific reference symbols + uint32_t lte_gold_uespec_table[2][20][2][21]; + //mbsfn reference symbols + uint32_t lte_gold_mbsfn_table[10][3][42]; + /// + uint32_t X_u[64][839]; + /// + uint32_t high_speed_flag; + uint32_t perfect_ce; + int16_t ch_est_alpha; + int generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX]; + /// + UE_SCAN_INFO_NB_IoT_t scan_info[NB_BANDS_MAX_NB_IoT]; + /// + char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX]; + +/* + + unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX]; + uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX]; + PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX]; + int turbo_iterations, turbo_cntl_iterations; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; + uint8_t generate_prach; + uint8_t prach_cnt; + uint8_t prach_PreambleIndex; + // uint8_t prach_timer; + uint8_t decode_SIB; + uint8_t decode_MIB; + int rx_offset; /// Timing offset + int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP + int timing_advance; ///timing advance signalled from eNB + int hw_timing_advance; + int N_TA_offset; ///timing offset used in TDD + /// Flag to tell if UE is secondary user (cognitive mode) + unsigned char is_secondary_ue; + /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from. + unsigned char has_valid_precoder; + /// hold the precoder for NULL beam to the primary eNB + int **ul_precoder_S_UE; + /// holds the maximum channel/precoder coefficient + char log2_maxp; +*/ + /// if ==0 enables phy only test mode + int mac_enabled; + /// Flag to initialize averaging of PHY measurements + int init_averaging; + /// \brief sinr for all subcarriers of the current link (used only for abstraction). + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_dB; + /// \brief sinr for all subcarriers of first symbol for the CQI Calculation. + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_CQI_dB; + /// sinr_effective used for CQI calulcation + double sinr_eff; + /// N0 (used for abstraction) + double N0; +/* + /// PDSCH Varaibles + PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH Varaibles + PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH contention-based access vars + PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola + + /// PUCCH variables + + PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + uint8_t ncs_cell[20][7]; + + /// UL-POWER-Control + UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// TPC + TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX]; + TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// CQI reporting + CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SRS Variables + SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Scheduling Request Config + SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Transmission mode per eNB + uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + + time_stats_t phy_proc; + time_stats_t phy_proc_tx; + time_stats_t phy_proc_rx[2]; + + uint32_t use_ia_receiver; + + time_stats_t ofdm_mod_stats; + time_stats_t ulsch_encoding_stats; + time_stats_t ulsch_modulation_stats; + time_stats_t ulsch_segmentation_stats; + time_stats_t ulsch_rate_matching_stats; + time_stats_t ulsch_turbo_encoding_stats; + time_stats_t ulsch_interleaving_stats; + time_stats_t ulsch_multiplexing_stats; + + time_stats_t generic_stat; + time_stats_t pdsch_procedures_stat; + time_stats_t dlsch_procedures_stat; + + time_stats_t ofdm_demod_stats; + time_stats_t dlsch_rx_pdcch_stats; + time_stats_t rx_dft_stats; + time_stats_t dlsch_channel_estimation_stats; + time_stats_t dlsch_freq_offset_estimation_stats; + time_stats_t dlsch_decoding_stats[2]; + time_stats_t dlsch_demodulation_stats; + time_stats_t dlsch_rate_unmatching_stats; + time_stats_t dlsch_turbo_decoding_stats; + time_stats_t dlsch_deinterleaving_stats; + time_stats_t dlsch_llr_stats; + time_stats_t dlsch_unscrambling_stats; + time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_interleaving_stats; + time_stats_t dlsch_tc_init_stats; + time_stats_t dlsch_tc_alpha_stats; + time_stats_t dlsch_tc_beta_stats; + time_stats_t dlsch_tc_gamma_stats; + time_stats_t dlsch_tc_ext_stats; + time_stats_t dlsch_tc_intl1_stats; + time_stats_t dlsch_tc_intl2_stats; + time_stats_t tx_prach; + + /// RF and Interface devices per CC + openair0_device rfdevice; + time_stats_t dlsch_encoding_SIC_stats; + time_stats_t dlsch_scrambling_SIC_stats; + time_stats_t dlsch_modulation_SIC_stats; + time_stats_t dlsch_llr_stripping_unit_SIC_stats; + time_stats_t dlsch_unscrambling_SIC_stats; + +#if ENABLE_RAL + hash_table_t *ral_thresholds_timed; + SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; + SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; +#endif +*/ +} PHY_VARS_UE_NB_IoT; + + + +#include "PHY/INIT/defs_NB_IoT.h" +#include "PHY/LTE_REFSIG/defs_NB_IoT.h" +#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h" +#endif // __PHY_DEFS__H__ diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h new file mode 100644 index 0000000000000000000000000000000000000000..e36b88c036b1f7426f9bcba8f4519f0b46c86d34 --- /dev/null +++ b/openair1/PHY/defs_UE.h @@ -0,0 +1,863 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/defs.h + \brief Top-level defines and structure definitions + \author R. Knopp, F. Kaltenberger + \date 2011 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr + \note + \warning +*/ +#ifndef __PHY_DEFS_UE_H__ +#define __PHY_DEFS_UE_H__ + + +#define _GNU_SOURCE +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <linux/sched.h> +#include <signal.h> +#include <execinfo.h> +#include <getopt.h> +#include <sys/sysinfo.h> + + +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <string.h> +#include <math.h> +#include "common_lib.h" +#include "msc.h" + +#include "defs_common.h" +#include "impl_defs_top.h" + +#include "PHY/TOOLS/time_meas.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/TOOLS/tools_defs.h" +#include "platform_types.h" +#include "PHY/LTE_UE_TRANSPORT/transport_ue.h" +#include "PHY/LTE_TRANSPORT/transport_eNB.h" // for SIC +#include <pthread.h> +#include "assertions.h" + + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// index of the current UE RX/TX proc + int proc_id; + /// Component Carrier index + uint8_t CC_id; + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_rxtx; + /// scheduling parameters for RXn-TXnp4 thread + struct sched_param sched_param_rxtx; + + /// internal This variable is protected by ref mutex_fep_slot1. + //int instance_cnt_slot0_dl_processing; + int instance_cnt_slot1_dl_processing; + /// pthread descriptor fep_slot1 thread + //pthread_t pthread_slot0_dl_processing; + pthread_t pthread_slot1_dl_processing; + /// pthread attributes for fep_slot1 processing thread + // pthread_attr_t attr_slot0_dl_processing; + pthread_attr_t attr_slot1_dl_processing; + /// condition variable for UE fep_slot1 thread; + //pthread_cond_t cond_slot0_dl_processing; + pthread_cond_t cond_slot1_dl_processing; + /// mutex for UE synch thread + //pthread_mutex_t mutex_slot0_dl_processing; + pthread_mutex_t mutex_slot1_dl_processing; + // + uint8_t chan_est_pilot0_slot1_available; + uint8_t chan_est_slot1_available; + uint8_t llr_slot1_available; + uint8_t dci_slot0_available; + uint8_t first_symbol_available; + //uint8_t channel_level; + /// scheduling parameters for fep_slot1 thread + struct sched_param sched_param_fep_slot1; + + int sub_frame_start; + int sub_frame_step; + unsigned long long gotIQs; +} UE_rxtx_proc_t; + +/// Context data structure for eNB subframe processing +typedef struct { + /// Component Carrier index + uint8_t CC_id; + /// Last RX timestamp + openair0_timestamp timestamp_rx; + /// pthread attributes for main UE thread + pthread_attr_t attr_ue; + /// scheduling parameters for main UE thread + struct sched_param sched_param_ue; + /// pthread descriptor main UE thread + pthread_t pthread_ue; + /// \brief Instance count for synch thread. + /// \internal This variable is protected by \ref mutex_synch. + int instance_cnt_synch; + /// pthread attributes for synch processing thread + pthread_attr_t attr_synch; + /// scheduling parameters for synch thread + struct sched_param sched_param_synch; + /// pthread descriptor synch thread + pthread_t pthread_synch; + /// condition variable for UE synch thread; + pthread_cond_t cond_synch; + /// mutex for UE synch thread + pthread_mutex_t mutex_synch; + /// instance count for eNBs + int instance_cnt_eNBs; + /// set of scheduling variables RXn-TXnp4 threads + UE_rxtx_proc_t proc_rxtx[RX_NB_TH]; +} UE_proc_t; + +/// Panos: Structure holding timer_thread related elements (phy_stub_UE mode) +typedef struct { + pthread_t pthread_timer; + /// Panos: mutex for waiting SF ticking + pthread_mutex_t mutex_ticking; + /// Panos: \brief ticking var for ticking thread. + /// \internal This variable is protected by \ref mutex_ticking. + int ticking_var; + /// condition variable for timer_thread; + pthread_cond_t cond_ticking; + //time_stats_t timer_stats; +} SF_ticking; + +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // RRC measurements + uint32_t rssi; + int n_adj_cells; + unsigned int adj_cell_id[6]; + uint32_t rsrq[7]; + uint32_t rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! total estimated noise power (dB) + unsigned short n0_power_tot_dB; + //! average estimated noise power (linear) + unsigned int n0_power_avg; + //! average estimated noise power (dB) + unsigned short n0_power_avg_dB; + //! total estimated noise power (dBm) + short n0_power_tot_dBm; + + // UE measurements + //! estimated received spatial signal power (linear) + int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + + /// estimated received signal power (sum over all TX/RX antennas) + int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + /// estimated received signal power (sum over all TX/RX antennas) + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + + //! estimated received signal power (sum of all TX/RX antennas, time average) + int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SINR (sum of all TX/RX antennas, in dB) + int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + /// SINR (sum of all TX/RX antennas, time average, in dB) + int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + + /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) + int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + /// Subband CQI per RX antenna (= SINR) + int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI (= SINR) + int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Subband CQI in dB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband Rank indication + unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Number of RX Antennas + unsigned char nb_antennas_rx; + /// DLSCH error counter + // short dlsch_errors; + +} PHY_MEASUREMENTS; + +typedef struct { + + /// \brief Holds the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..28*ofdm_symbol_size[ + int32_t **rxdataF; + + /// \brief Hold the channel estimates in frequency domain. + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_ch_estimates[7]; + + /// \brief Hold the channel estimates in time domain (used for tracking). + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..2*ofdm_symbol_size[ + int32_t **dl_ch_estimates_time[7]; +}LTE_UE_COMMON_PER_THREAD; + +typedef struct { + /// \brief Holds the transmit data in time domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES[ + int32_t **txdata; + /// \brief Holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX[ + int32_t **txdataF; + + /// \brief Holds the received data in time domain. + /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ + int32_t **rxdata; + + LTE_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX]; + + /// holds output of the sync correlator + int32_t *sync_corr; + /// estimated frequency offset (in radians) for all subcarriers + int32_t freq_offset; + /// eNb_id user is synched to + int32_t eNb_id; +} LTE_UE_COMMON; + +typedef struct { + /// \brief Received frequency-domain signal after extraction. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_ext; + /// \brief Received frequency-domain ue specific pilots. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..12*N_RB_DL[ + int32_t **rxdataF_uespec_pilots; + /// \brief Received frequency-domain signal after extraction and channel compensation. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp0; + /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp1[8][8]; + /// \brief Downlink channel estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho_ext[8][8]; + /// \brief Downlink beamforming channel estimates in frequency domain. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_bf_ch_estimates; + /// \brief Downlink beamforming channel estimates. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_bf_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho2_ext; + /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. + /// - first index: ressource block [0..N_RB_DL[ + uint8_t *pmi_ext; + /// \brief Magnitude of Downlink Channel first layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag0; + /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag1[8][8]; + /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb0; + /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb1[8][8]; + /// \brief Cross-correlation of two eNB signals. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..] + int32_t **rho; + /// never used... always send dl_ch_rho_ext instead... + int32_t **rho_i; + /// \brief Pointers to llr vectors (2 TBs). + /// - first index: ? [0..1] (hard coded) + /// - second index: ? [0..1179743] (hard coded) + int16_t *llr[2]; + /// \f$\log_2(\max|H_i|^2)\f$ + int16_t log2_maxh; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation + int16_t log2_maxh0; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation + int16_t log2_maxh1; + /// \brief LLR shifts for subband scaling. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts; + /// \brief Pointer to LLR shifts. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts_p; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128_2ndstream; + //uint32_t *rb_alloc; + //uint8_t Qm[2]; + //MIMO_mode_t mimo_mode; + // llr offset per ofdm symbol + uint32_t llr_offset[14]; + // llr length per ofdm symbol + uint32_t llr_length[14]; +} LTE_UE_PDSCH; + +typedef struct { + /// \brief Received frequency-domain signal after extraction. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..] + int32_t **rxdataF_ext; + /// \brief Received frequency-domain signal after extraction and channel compensation. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..] + double **rxdataF_comp; + /// \brief Downlink channel estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..] + int32_t **dl_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..] + double **dl_ch_rho_ext; + /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. + /// - first index: ressource block [0..N_RB_DL[ + uint8_t *pmi_ext; + /// \brief Magnitude of Downlink Channel (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..] + double **dl_ch_mag; + /// \brief Magnitude of Downlink Channel (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..] + double **dl_ch_magb; + /// \brief Cross-correlation of two eNB signals. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..] + double **rho; + /// never used... always send dl_ch_rho_ext instead... + double **rho_i; + /// \brief Pointers to llr vectors (2 TBs). + /// - first index: ? [0..1] (hard coded) + /// - second index: ? [0..1179743] (hard coded) + int16_t *llr[2]; + /// \f$\log_2(\max|H_i|^2)\f$ + uint8_t log2_maxh; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128; + //uint32_t *rb_alloc; + //uint8_t Qm[2]; + //MIMO_mode_t mimo_mode; +} LTE_UE_PDSCH_FLP; + +typedef struct { + /// \brief Pointers to extracted PDCCH symbols in frequency-domain. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_ext; + /// \brief Pointers to extracted and compensated PDCCH symbols in frequency-domain. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp; + /// \brief Pointers to extracted channel estimates of PDCCH symbols. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_estimates_ext; + /// \brief Pointers to channel cross-correlation vectors for multi-eNB detection. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho_ext; + /// \brief Pointers to channel cross-correlation vectors for multi-eNB detection. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..] + int32_t **rho; + /// \brief Pointer to llrs, 4-bit resolution. + /// - first index: ? [0..48*N_RB_DL[ + uint16_t *llr; + /// \brief Pointer to llrs, 16-bit resolution. + /// - first index: ? [0..96*N_RB_DL[ + uint16_t *llr16; + /// \brief \f$\overline{w}\f$ from 36-211. + /// - first index: ? [0..48*N_RB_DL[ + uint16_t *wbar; + /// \brief PDCCH/DCI e-sequence (input to rate matching). + /// - first index: ? [0..96*N_RB_DL[ + int8_t *e_rx; + /// number of PDCCH symbols in current subframe + uint8_t num_pdcch_symbols; + /// Allocated CRNTI for UE + uint16_t crnti; + /// 1: the allocated crnti is Temporary C-RNTI / 0: otherwise + uint8_t crnti_is_temporary; + /// Total number of PDU errors (diagnostic mode) + uint32_t dci_errors; + /// Total number of PDU received + uint32_t dci_received; + /// Total number of DCI False detection (diagnostic mode) + uint32_t dci_false; + /// Total number of DCI missed (diagnostic mode) + uint32_t dci_missed; + /// nCCE for PUCCH per subframe + uint8_t nCCE[10]; + //Check for specific DCIFormat and AgregationLevel + uint8_t dciFormat; + uint8_t agregationLevel; +} LTE_UE_PDCCH; + + +typedef struct { + /// \brief Pointers to extracted PBCH symbols in frequency-domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..287] (hard coded) + int32_t **rxdataF_ext; + /// \brief Pointers to extracted and compensated PBCH symbols in frequency-domain. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..287] (hard coded) + int32_t **rxdataF_comp; + /// \brief Pointers to downlink channel estimates in frequency-domain extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..287] (hard coded) + int32_t **dl_ch_estimates_ext; + /// \brief Pointer to PBCH llrs. + /// - first index: ? [0..1919] (hard coded) + int8_t *llr; + /// \brief Pointer to PBCH decoded output. + /// - first index: ? [0..63] (hard coded) + uint8_t *decoded_output; + /// \brief Total number of PDU errors. + uint32_t pdu_errors; + /// \brief Total number of PDU errors 128 frames ago. + uint32_t pdu_errors_last; + /// \brief Total number of consecutive PDU errors. + uint32_t pdu_errors_conseq; + /// \brief FER (in percent) . + uint32_t pdu_fer; +} LTE_UE_PBCH; + +typedef struct { + int16_t amp; + int16_t *prachF; + int16_t *prach; +} LTE_UE_PRACH; + + + +typedef enum { + /// do not detect any DCIs in the current subframe + NO_DCI = 0x0, + /// detect only downlink DCIs in the current subframe + UL_DCI = 0x1, + /// detect only uplink DCIs in the current subframe + DL_DCI = 0x2, + /// detect both uplink and downlink DCIs in the current subframe + UL_DL_DCI = 0x3} dci_detect_mode_t; + +typedef struct UE_SCAN_INFO_s { + /// 10 best amplitudes (linear) for each pss signals + int32_t amp[3][10]; + /// 10 frequency offsets (kHz) corresponding to best amplitudes, with respect do minimum DL frequency in the band + int32_t freq_offset_Hz[3][10]; +} UE_SCAN_INFO_t; + +/// Top-level PHY Data Structure for UE +typedef struct { + /// \brief Module ID indicator for this instance + uint8_t Mod_id; + /// \brief Component carrier ID for this PHY instance + uint8_t CC_id; + /// \brief Mapping of CC_id antennas to cards + openair0_rf_map rf_map; + //uint8_t local_flag; + /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach) + runmode_t mode; + /// \brief Indicator that UE should perform band scanning + int UE_scan; + /// \brief Indicator that UE should perform coarse scanning around carrier + int UE_scan_carrier; + /// \brief Indicator that UE is synchronized to an eNB + int is_synchronized; + /// Data structure for UE process scheduling + UE_proc_t proc; + /// Flag to indicate the UE shouldn't do timing correction at all + int no_timing_correction; + /// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna) + uint32_t tx_total_gain_dB; + /// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card. + uint32_t rx_total_gain_dB; + /// \brief Total gains with maximum RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_max[4]; + /// \brief Total gains with medium RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_med[4]; + /// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_byp[4]; + /// \brief Current transmit power + int16_t tx_power_dBm[10]; + /// \brief Total number of REs in current transmission + int tx_total_RE[10]; + /// \brief Maximum transmit power + int8_t tx_power_max_dBm; + /// \brief Number of eNB seen by UE + uint8_t n_connected_eNB; + /// \brief indicator that Handover procedure has been initiated + uint8_t ho_initiated; + /// \brief indicator that Handover procedure has been triggered + uint8_t ho_triggered; + /// \brief Measurement variables. + PHY_MEASUREMENTS measurements; + LTE_DL_FRAME_PARMS frame_parms; + /// \brief Frame parame before ho used to recover if ho fails. + LTE_DL_FRAME_PARMS frame_parms_before_ho; + LTE_UE_COMMON common_vars; + + // point to the current rxTx thread index + uint8_t current_thread_id[10]; + + LTE_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads + LTE_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1]; + LTE_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1]; + LTE_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1]; + LTE_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1]; + LTE_UE_PDSCH *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads + LTE_UE_ULSCH_t *ulsch[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_DLSCH_t *dlsch_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; + // This is for SIC in the UE, to store the reencoded data + LTE_eNB_DLSCH_t *dlsch_eNB[NUMBER_OF_CONNECTED_eNB_MAX]; + + //Paging parameters + uint32_t IMSImod1024; + uint32_t PF; + uint32_t PO; + + // For abstraction-purposes only + uint8_t sr[10]; + uint8_t pucch_sel[10]; + uint8_t pucch_payload[22]; + + UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + /// cell-specific reference symbols + uint32_t lte_gold_table[7][20][2][14]; + + /// UE-specific reference symbols (p=5), TM 7 + uint32_t lte_gold_uespec_port5_table[20][38]; + + /// ue-specific reference symbols + uint32_t lte_gold_uespec_table[2][20][2][21]; + + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_table[10][3][42]; + + uint32_t X_u[64][839]; + + uint32_t high_speed_flag; + uint32_t perfect_ce; + int16_t ch_est_alpha; + int generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX]; + + UE_SCAN_INFO_t scan_info[NB_BANDS_MAX]; + + char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX]; + + + + unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX]; + uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX]; + PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX]; + int turbo_iterations, turbo_cntl_iterations; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; + uint8_t generate_prach; + uint8_t prach_cnt; + uint8_t prach_PreambleIndex; + // uint8_t prach_timer; + uint8_t decode_SIB; + uint8_t decode_MIB; + int rx_offset; /// Timing offset + int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP + int time_sync_cell; + int timing_advance; ///timing advance signalled from eNB + int hw_timing_advance; + int N_TA_offset; ///timing offset used in TDD + /// Flag to tell if UE is secondary user (cognitive mode) + unsigned char is_secondary_ue; + /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from. + unsigned char has_valid_precoder; + /// hold the precoder for NULL beam to the primary eNB + int **ul_precoder_S_UE; + /// holds the maximum channel/precoder coefficient + char log2_maxp; + + /// if ==0 enables phy only test mode + int mac_enabled; + + /// Flag to initialize averaging of PHY measurements + int init_averaging; + + /// \brief sinr for all subcarriers of the current link (used only for abstraction). + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_dB; + + /// \brief sinr for all subcarriers of first symbol for the CQI Calculation. + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_CQI_dB; + + /// sinr_effective used for CQI calulcation + double sinr_eff; + + /// N0 (used for abstraction) + double N0; + + /// PDSCH Varaibles + PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH Varaibles + PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH contention-based access vars + PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola + + /// PUCCH variables + + PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + uint8_t ncs_cell[20][7]; + + /// UL-POWER-Control + UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// TPC + TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX]; + TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// CQI reporting + CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SRS Variables + SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Scheduling Request Config + SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Transmission mode per eNB + uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + + time_stats_t phy_proc[RX_NB_TH]; + time_stats_t phy_proc_tx; + time_stats_t phy_proc_rx[RX_NB_TH]; + + uint32_t use_ia_receiver; + + time_stats_t ofdm_mod_stats; + time_stats_t ulsch_encoding_stats; + time_stats_t ulsch_modulation_stats; + time_stats_t ulsch_segmentation_stats; + time_stats_t ulsch_rate_matching_stats; + time_stats_t ulsch_turbo_encoding_stats; + time_stats_t ulsch_interleaving_stats; + time_stats_t ulsch_multiplexing_stats; + + time_stats_t generic_stat; + time_stats_t generic_stat_bis[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; + time_stats_t ue_front_end_stat[RX_NB_TH]; + time_stats_t ue_front_end_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; + time_stats_t pdcch_procedures_stat[RX_NB_TH]; + time_stats_t pdsch_procedures_stat[RX_NB_TH]; + time_stats_t pdsch_procedures_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; + time_stats_t dlsch_procedures_stat[RX_NB_TH]; + + time_stats_t ofdm_demod_stats; + time_stats_t dlsch_rx_pdcch_stats; + time_stats_t rx_dft_stats; + time_stats_t dlsch_channel_estimation_stats; + time_stats_t dlsch_freq_offset_estimation_stats; + time_stats_t dlsch_decoding_stats[2]; + time_stats_t dlsch_demodulation_stats; + time_stats_t dlsch_rate_unmatching_stats; + time_stats_t dlsch_turbo_decoding_stats; + time_stats_t dlsch_deinterleaving_stats; + time_stats_t dlsch_llr_stats; + time_stats_t dlsch_llr_stats_parallelization[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; + time_stats_t dlsch_unscrambling_stats; + time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_interleaving_stats; + time_stats_t dlsch_tc_init_stats; + time_stats_t dlsch_tc_alpha_stats; + time_stats_t dlsch_tc_beta_stats; + time_stats_t dlsch_tc_gamma_stats; + time_stats_t dlsch_tc_ext_stats; + time_stats_t dlsch_tc_intl1_stats; + time_stats_t dlsch_tc_intl2_stats; + time_stats_t tx_prach; + time_stats_t timer_stats; + + pthread_mutex_t timer_mutex; + pthread_cond_t timer_cond; + int instance_cnt_timer; + + /// RF and Interface devices per CC + + openair0_device rfdevice; +} PHY_VARS_UE; + +/* this structure is used to pass both UE phy vars and + * proc to the function UE_thread_rxn_txnp4 + */ +struct rx_tx_thread_data { + PHY_VARS_UE *UE; + UE_rxtx_proc_t *proc; +}; + + +#endif // __PHY_DEFS__H__ diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h new file mode 100644 index 0000000000000000000000000000000000000000..fff53b8576f6bd0b776a869ec5ca77fe3fdf1bd5 --- /dev/null +++ b/openair1/PHY/defs_common.h @@ -0,0 +1,1083 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/defs.h + \brief Top-level defines and structure definitions + \author R. Knopp, F. Kaltenberger + \date 2011 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr + \note + \warning +*/ +#ifndef __PHY_DEFS_COMMON_H__ +#define __PHY_DEFS_COMMON_H__ + + +#define _GNU_SOURCE +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <linux/sched.h> +#include <signal.h> +#include <execinfo.h> +#include <getopt.h> +#include <sys/sysinfo.h> + + +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <string.h> +#include <math.h> +#include "common_lib.h" +#include "msc.h" + + +//#include <complex.h> + + + + + + + +#include "PHY/TOOLS/time_meas.h" +#include "platform_types.h" +#define MAX_NUM_RU_PER_eNB 64 + +#include <pthread.h> + +#include "targets/ARCH/COMMON/common_lib.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#include "types.h" +#include "nfapi_interface.h" +//#include "defs.h" +#include "openair2/COMMON/platform_types.h" + +#define RX_NB_TH_MAX 2 +#define RX_NB_TH 2 + +#define LTE_SLOTS_PER_SUBFRAME 2 + +#define LTE_NUMBER_OF_SUBFRAMES_PER_FRAME 10 +#define LTE_SLOTS_PER_FRAME 20 +#define LTE_CE_FILTER_LENGTH 5 +#define LTE_CE_OFFSET LTE_CE_FILTER_LENGTH +#define TX_RX_SWITCH_SYMBOL (NUMBER_OF_SYMBOLS_PER_FRAME>>1) +#define PBCH_PDU_SIZE 3 //bytes + +#define PRACH_SYMBOL 3 //position of the UL PSS wrt 2nd slot of special subframe + +#define NUMBER_OF_FREQUENCY_GROUPS (lte_frame_parms->N_RB_DL) + +#define SSS_AMP 1148 + +#define MAX_NUM_PHICH_GROUPS 56 //110 RBs Ng=2, p.60 36-212, Sec. 6.9 + +#define MAX_MBSFN_AREA 8 + +#define NB_RX_ANTENNAS_MAX 64 + +#ifdef OCP_FRAMEWORK +#include "enums.h" +#else +typedef enum {TDD=1,FDD=0} lte_frame_type_t; + +typedef enum {EXTENDED=1,NORMAL=0} lte_prefix_type_t; + +typedef enum {LOCALIZED=0,DISTRIBUTED=1} vrb_t; + +/// Enumeration for parameter PHICH-Duration \ref PHICH_CONFIG_COMMON::phich_duration. +typedef enum { + normal=0, + extended=1 +} PHICH_DURATION_t; + +/// Enumeration for parameter Ng \ref PHICH_CONFIG_COMMON::phich_resource. +typedef enum { + oneSixth=1, + half=3, + one=6, + two=12 +} PHICH_RESOURCE_t; +#endif +/// PHICH-Config from 36.331 RRC spec +typedef struct { + /// Parameter: PHICH-Duration, see TS 36.211 (Table 6.9.3-1). + PHICH_DURATION_t phich_duration; + /// Parameter: Ng, see TS 36.211 (6.9). \details Value oneSixth corresponds to 1/6, half corresponds to 1/2 and so on. + PHICH_RESOURCE_t phich_resource; +} PHICH_CONFIG_COMMON; + +/// PRACH-ConfigInfo from 36.331 RRC spec +typedef struct { + /// Parameter: prach-ConfigurationIndex, see TS 36.211 (5.7.1). \vr{[0..63]} + uint8_t prach_ConfigIndex; + /// Parameter: High-speed-flag, see TS 36.211 (5.7.2). \vr{[0..1]} 1 corresponds to Restricted set and 0 to Unrestricted set. + uint8_t highSpeedFlag; + /// Parameter: \f$N_\text{CS}\f$, see TS 36.211 (5.7.2). \vr{[0..15]}\n Refer to table 5.7.2-2 for preamble format 0..3 and to table 5.7.2-3 for preamble format 4. + uint8_t zeroCorrelationZoneConfig; + /// Parameter: prach-FrequencyOffset, see TS 36.211 (5.7.1). \vr{[0..94]}\n For TDD the value range is dependent on the value of \ref prach_ConfigIndex. + uint8_t prach_FreqOffset; +} PRACH_CONFIG_INFO; + + + +/// PRACH-ConfigSIB or PRACH-Config from 36.331 RRC spec +typedef struct { + /// Parameter: RACH_ROOT_SEQUENCE, see TS 36.211 (5.7.1). \vr{[0..837]} + uint16_t rootSequenceIndex; + /// prach_Config_enabled=1 means enabled. \vr{[0..1]} + uint8_t prach_Config_enabled; + /// PRACH Configuration Information + PRACH_CONFIG_INFO prach_ConfigInfo; +} PRACH_CONFIG_COMMON; + +#ifdef Rel14 + +/// PRACH-eMTC-Config from 36.331 RRC spec +typedef struct { + /// Parameter: High-speed-flag, see TS 36.211 (5.7.2). \vr{[0..1]} 1 corresponds to Restricted set and 0 to Unrestricted set. + uint8_t highSpeedFlag; +/// Parameter: \f$N_\text{CS}\f$, see TS 36.211 (5.7.2). \vr{[0..15]}\n Refer to table 5.7.2-2 for preamble format 0..3 and to table 5.7.2-3 for preamble format 4. + uint8_t zeroCorrelationZoneConfig; + /// Parameter: prach-FrequencyOffset, see TS 36.211 (5.7.1). \vr{[0..94]}\n For TDD the value range is dependent on the value of \ref prach_ConfigIndex. + + /// PRACH starting subframe periodicity, expressed in number of subframes available for preamble transmission (PRACH opportunities), see TS 36.211. Value 2 corresponds to 2 subframes, 4 corresponds to 4 subframes and so on. EUTRAN configures the PRACH starting subframe periodicity larger than or equal to the Number of PRACH repetitions per attempt for each CE level (numRepetitionPerPreambleAttempt). + uint8_t prach_starting_subframe_periodicity[4]; + /// number of repetitions per preamble attempt per CE level + uint8_t prach_numRepetitionPerPreambleAttempt[4]; + /// prach configuration index for each CE level + uint8_t prach_ConfigIndex[4]; + /// indicator for CE level activation + uint8_t prach_CElevel_enable[4]; + /// prach frequency offset for each CE level + uint8_t prach_FreqOffset[4]; + /// indicator for CE level hopping activation + uint8_t prach_hopping_enable[4]; + /// indicator for CE level hopping activation + uint8_t prach_hopping_offset[4]; +} PRACH_eMTC_CONFIG_INFO; + +/// PRACH-ConfigSIB or PRACH-Config from 36.331 RRC spec +typedef struct { + /// Parameter: RACH_ROOT_SEQUENCE, see TS 36.211 (5.7.1). \vr{[0..837]} + uint16_t rootSequenceIndex; + /// prach_Config_enabled=1 means enabled. \vr{[0..1]} + uint8_t prach_Config_enabled; + /// PRACH Configuration Information +#ifdef Rel14 + PRACH_eMTC_CONFIG_INFO prach_ConfigInfo; +#endif +} PRACH_eMTC_CONFIG_COMMON; + +#endif + +/// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor. +typedef enum { + n2=0, + n4, + n6 +} ACKNAKREP_t; + +/// Enumeration for \ref PUCCH_CONFIG_DEDICATED::tdd_AckNackFeedbackMode. +typedef enum { + bundling=0, + multiplexing +} ANFBmode_t; + +/// PUCCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Flag to indicate ACK NAK repetition activation, see TS 36.213 (10.1). \vr{[0..1]} + uint8_t ackNackRepetition; + /// Parameter: \f$N_\text{ANRep}\f$, see TS 36.213 (10.1). + ACKNAKREP_t repetitionFactor; + /// Parameter: \f$n^{(1)}_\text{PUCCH,ANRep}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t n1PUCCH_AN_Rep; + /// Feedback mode, see TS 36.213 (7.3). \details Applied to both PUCCH and PUSCH feedback. For TDD, should always be set to bundling. + ANFBmode_t tdd_AckNackFeedbackMode; +} PUCCH_CONFIG_DEDICATED; + +/// PUCCH-ConfigCommon from 36.331 RRC spec +typedef struct { + /// Parameter: \f$\Delta^\text{PUCCH}_\text{shift}\f$, see TS 36.211 (5.4.1). \vr{[1..3]} \note the specification sais it is an enumerated value. + uint8_t deltaPUCCH_Shift; + /// Parameter: \f$N^{(2)}_\text{RB}\f$, see TS 36.211 (5.4). \vr{[0..98]} + uint8_t nRB_CQI; + /// Parameter: \f$N^{(1)}_\text{CS}\f$, see TS 36.211 (5.4). \vr{[0..7]} + uint8_t nCS_AN; + /// Parameter: \f$N^{(1)}_\text{PUCCH}\f$ see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t n1PUCCH_AN; + + /// group hopping sequence for DRS \note not part of offical UL-PUCCH_CONFIG_COMMON ASN1 specification. + uint8_t grouphop[20]; + /// sequence hopping sequence for DRS \note not part of offical UL-PUCCH_CONFIG_COMMON ASN1 specification. + uint8_t seqhop[20]; +} PUCCH_CONFIG_COMMON; + +/// UL-ReferenceSignalsPUSCH from 36.331 RRC spec +typedef struct { + /// Parameter: Group-hopping-enabled, see TS 36.211 (5.5.1.3). \vr{[0..1]} + uint8_t groupHoppingEnabled; + /// Parameter: \f$\Delta SS\f$, see TS 36.211 (5.5.1.3). \vr{[0..29]} + uint8_t groupAssignmentPUSCH; + /// Parameter: Sequence-hopping-enabled, see TS 36.211 (5.5.1.4). \vr{[0..1]} + uint8_t sequenceHoppingEnabled; + /// Parameter: cyclicShift, see TS 36.211 (Table 5.5.2.1.1-2). \vr{[0..7]} + uint8_t cyclicShift; + /// nPRS for cyclic shift of DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t nPRS[20]; + /// group hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t grouphop[20]; + /// sequence hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t seqhop[20]; +} UL_REFERENCE_SIGNALS_PUSCH_t; + +/// Enumeration for parameter Hopping-mode \ref PUSCH_CONFIG_COMMON::hoppingMode. +#ifndef OCP_FRAMEWORK +typedef enum { + interSubFrame=0, + intraAndInterSubFrame=1 +} PUSCH_HOPPING_t; +#endif + +/// PUSCH-ConfigCommon from 36.331 RRC spec. +typedef struct { + /// Parameter: \f$N_{sb}\f$, see TS 36.211 (5.3.4). \vr{[1..4]} + uint8_t n_SB; + /// Parameter: Hopping-mode, see TS 36.211 (5.3.4). + PUSCH_HOPPING_t hoppingMode; + /// Parameter: \f$N^{HO}_{RB}\f$, see TS 36.211 (5.3.4). \vr{[0..98]} + uint8_t pusch_HoppingOffset; + /// See TS 36.213 (8.6.1). \vr{[0..1]} 1 indicates 64QAM is allowed, 0 not allowed. + uint8_t enable64QAM; + /// Ref signals configuration + UL_REFERENCE_SIGNALS_PUSCH_t ul_ReferenceSignalsPUSCH; +} PUSCH_CONFIG_COMMON; + +/// UE specific PUSCH configuration. +typedef struct { + /// Parameter: \f$I^\text{HARQ-ACK}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-1). \vr{[0..15]} + uint16_t betaOffset_ACK_Index; + /// Parameter: \f$I^{RI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-2). \vr{[0..15]} + uint16_t betaOffset_RI_Index; + /// Parameter: \f$I^{CQI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-3). \vr{[0..15]} + uint16_t betaOffset_CQI_Index; +} PUSCH_CONFIG_DEDICATED; + +/// lola CBA information +typedef struct { + /// + uint16_t betaOffset_CA_Index; + /// + uint16_t cShift; +} PUSCH_CA_CONFIG_DEDICATED; + +/// PDSCH-ConfigCommon from 36.331 RRC spec +typedef struct { + /// Parameter: Reference-signal power, see TS 36.213 (5.2). \vr{[-60..50]}\n Provides the downlink reference-signal EPRE. The actual value in dBm. + int8_t referenceSignalPower; + /// Parameter: \f$P_B\f$, see TS 36.213 (Table 5.2-1). \vr{[0..3]} + uint8_t p_b; +} PDSCH_CONFIG_COMMON; + +/// Enumeration for Parameter \f$P_A\f$ \ref PDSCH_CONFIG_DEDICATED::p_a. +typedef enum { + dBm6=0, ///< (dB-6) corresponds to -6 dB + dBm477, ///< (dB-4dot77) corresponds to -4.77 dB + dBm3, ///< (dB-3) corresponds to -3 dB + dBm177, ///< (dB-1dot77) corresponds to -1.77 dB + dB0, ///< corresponds to 0 dB + dB1, ///< corresponds to 1 dB + dB2, ///< corresponds to 2 dB + dB3 ///< corresponds to 3 dB +} PA_t; + +/// PDSCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_A\f$, see TS 36.213 (5.2). + PA_t p_a; +} PDSCH_CONFIG_DEDICATED; + +/// SoundingRS-UL-ConfigCommon Information Element from 36.331 RRC spec +typedef struct { + /// enabled flag=1 means SRS is enabled. \vr{[0..1]} + uint8_t enabled_flag; + /// Parameter: SRS Bandwidth Configuration, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..7]}\n Actual configuration depends on UL bandwidth. \note the specification sais it is an enumerated value. + uint8_t srs_BandwidthConfig; + /// Parameter: SRS SubframeConfiguration, see TS 36.211 (table 5.5.3.3-1 for FDD, table 5.5.3.3-2 for TDD). \vr{[0..15]} \note the specification sais it is an enumerated value. + uint8_t srs_SubframeConfig; + /// Parameter: Simultaneous-AN-and-SRS, see TS 36.213 (8.2). \vr{[0..1]} + uint8_t ackNackSRS_SimultaneousTransmission; + /// Parameter: srsMaxUpPts, see TS 36.211 (5.5.3.2). \details If this field is present, reconfiguration of \f$m^\text{max}_\text{SRS,0}\f$ applies for UpPts, otherwise reconfiguration does not apply. + uint8_t srs_MaxUpPts; +} SOUNDINGRS_UL_CONFIG_COMMON; + +/// \note UNUSED +typedef enum { + ulpc_al0=0, + ulpc_al04=1, + ulpc_al05=2, + ulpc_al06=3, + ulpc_al07=4, + ulpc_al08=5, + ulpc_al09=6, + ulpc_al11=7 +} UL_POWER_CONTROL_COMMON_alpha_t; + +/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format1. +typedef enum { + deltaF_PUCCH_Format1_deltaF_2 = 0, + deltaF_PUCCH_Format1_deltaF0 = 1, + deltaF_PUCCH_Format1_deltaF2 = 2 +} deltaF_PUCCH_Format1_t; + +/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format1b. +typedef enum { + deltaF_PUCCH_Format1b_deltaF1 = 0, + deltaF_PUCCH_Format1b_deltaF3 = 1, + deltaF_PUCCH_Format1b_deltaF5 = 2 +} deltaF_PUCCH_Format1b_t; + +/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format2. +typedef enum { + deltaF_PUCCH_Format2_deltaF_2 = 0, + deltaF_PUCCH_Format2_deltaF0 = 1, + deltaF_PUCCH_Format2_deltaF1 = 2, + deltaF_PUCCH_Format2_deltaF2 = 3 +} deltaF_PUCCH_Format2_t; + +/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format2a. +typedef enum { + deltaF_PUCCH_Format2a_deltaF_2 = 0, + deltaF_PUCCH_Format2a_deltaF0 = 1, + deltaF_PUCCH_Format2a_deltaF2 = 2 +} deltaF_PUCCH_Format2a_t; + +/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format2b. +typedef enum { + deltaF_PUCCH_Format2b_deltaF_2 = 0, + deltaF_PUCCH_Format2b_deltaF0 = 1, + deltaF_PUCCH_Format2b_deltaF2 = 2 +} deltaF_PUCCH_Format2b_t; + +/// DeltaFList-PUCCH from 36.331 RRC spec +typedef struct { + deltaF_PUCCH_Format1_t deltaF_PUCCH_Format1; + deltaF_PUCCH_Format1b_t deltaF_PUCCH_Format1b; + deltaF_PUCCH_Format2_t deltaF_PUCCH_Format2; + deltaF_PUCCH_Format2a_t deltaF_PUCCH_Format2a; + deltaF_PUCCH_Format2b_t deltaF_PUCCH_Format2b; +} deltaFList_PUCCH_t; + +/// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec +typedef struct { + /// This descriptor is active + uint8_t active; + /// This descriptor's frame + uint16_t frame; + /// This descriptor's subframe + uint8_t subframe; + /// rnti + uint16_t rnti; + /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_Bandwidth; + /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_HoppingBandwidth; + /// Parameter: \f$n_\text{RRC}\f$, see TS 36.211 (5.5.3.2). \vr{[0..23]} + uint8_t freqDomainPosition; + /// Parameter: Duration, see TS 36.213 (8.2). \vr{[0..1]} 0 corresponds to "single" and 1 to "indefinite". + uint8_t duration; + /// Parameter: \f$k_\text{TC}\in\{0,1\}\f$, see TS 36.211 (5.5.3.2). \vr{[0..1]} + uint8_t transmissionComb; + /// Parameter: \f$I_\text{SRS}\f$, see TS 36.213 (table 8.2-1). \vr{[0..1023]} + uint16_t srs_ConfigIndex; + /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value. + uint8_t cyclicShift; + // Parameter: internal implementation: UE SRS configured + uint8_t srsConfigDedicatedSetup; + // Parameter: cell srs subframe for internal implementation + uint8_t srsCellSubframe; + // Parameter: ue srs subframe for internal implementation + uint8_t srsUeSubframe; +} SOUNDINGRS_UL_CONFIG_DEDICATED; + +/// UplinkPowerControlDedicated Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_\text{0\_UE\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dB. \vr{[-8..7]}\n This field is applicable for non-persistent scheduling, only. + int8_t p0_UE_PUSCH; + /// Parameter: Ks, see TS 36.213 (5.1.1.1). \vr{[0..1]}\n en0 corresponds to value 0 corresponding to state “disabledâ€. en1 corresponds to value 1.25 corresponding to “enabledâ€. \note the specification sais it is an enumerated value. \warning the enumeration values do not correspond to the given values in the specification (en1 should be 1.25). + uint8_t deltaMCS_Enabled; + /// Parameter: Accumulation-enabled, see TS 36.213 (5.1.1.1). \vr{[0..1]} 1 corresponds to "enabled" whereas 0 corresponds to "disabled". + uint8_t accumulationEnabled; + /// Parameter: \f$P_\text{0\_UE\_PUCCH}(1)\f$, see TS 36.213 (5.1.2.1), unit dB. \vr{[-8..7]} + int8_t p0_UE_PUCCH; + /// Parameter: \f$P_\text{SRS\_OFFSET}\f$, see TS 36.213 (5.1.3.1). \vr{[0..15]}\n For Ks=1.25 (\ref deltaMCS_Enabled), the actual parameter value is pSRS_Offset value - 3. For Ks=0, the actual parameter value is -10.5 + 1.5*pSRS_Offset value. + int8_t pSRS_Offset; + /// Specifies the filtering coefficient for RSRP measurements used to calculate path loss, as specified in TS 36.213 (5.1.1.1).\details The same filtering mechanism applies as for quantityConfig described in 5.5.3.2. \note the specification sais it is an enumerated value. + uint8_t filterCoefficient; +} UL_POWER_CONTROL_DEDICATED; + +#ifndef OCP_FRAMEWORK +/// Enumeration for parameter \f$\alpha\f$ \ref UL_POWER_CONTROL_CONFIG_COMMON::alpha. +typedef enum { + al0=0, + al04=1, + al05=2, + al06=3, + al07=4, + al08=5, + al09=6, + al1=7 +} PUSCH_alpha_t; +#endif + +/// \note UNUSED +typedef enum { + deltaFm2=0, + deltaF0, + deltaF1, + deltaF2, + deltaF3, + deltaF5 +} deltaF_PUCCH_t; + +/// UplinkPowerControlCommon Information Element from 36.331 RRC spec \note this structure does not currently make use of \ref deltaFList_PUCCH_t. +typedef struct { + /// Parameter: \f$P_\text{0\_NOMINAL\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dBm. \vr{[-126..24]}\n This field is applicable for non-persistent scheduling, only. + int8_t p0_NominalPUSCH; + /// Parameter: \f$\alpha\f$, see TS 36.213 (5.1.1.1) \warning the enumeration values do not correspond to the given values in the specification (al04 should be 0.4, ...)! + PUSCH_alpha_t alpha; + /// Parameter: \f$P_\text{0\_NOMINAL\_PUCCH}\f$ See TS 36.213 (5.1.2.1), unit dBm. \vr{[-127..-96]} + int8_t p0_NominalPUCCH; + /// Parameter: \f$\Delta_\text{PREAMBLE\_Msg3}\f$ see TS 36.213 (5.1.1.1). \vr{[-1..6]}\n Actual value = IE value * 2 [dB]. + int8_t deltaPreambleMsg3; + /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 1, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. + long deltaF_PUCCH_Format1; + /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 1a, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. + long deltaF_PUCCH_Format1a; + /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 1b, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. + long deltaF_PUCCH_Format1b; + /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 2, see TS 36.213 (5.1.2). \vr{[0..3]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. + long deltaF_PUCCH_Format2; + /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 2a, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. + long deltaF_PUCCH_Format2a; + /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 2b, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. + long deltaF_PUCCH_Format2b; +} UL_POWER_CONTROL_CONFIG_COMMON; + +/// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. +typedef union { + /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} + uint8_t indexOfFormat3; + /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} + uint8_t indexOfFormat3A; +} TPC_INDEX_t; + +/// TPC-PDCCH-Config Information Element from 36.331 RRC spec +typedef struct { + /// RNTI for power control using DCI format 3/3A, see TS 36.212. \vr{[0..65535]} + uint16_t rnti; + /// Index of N or M, see TS 36.212 (5.3.3.1.6 and 5.3.3.1.7), where N or M is dependent on the used DCI format (i.e. format 3 or 3a). + TPC_INDEX_t tpc_Index; +} TPC_PDCCH_CONFIG; + +/// Enumeration for parameter SR transmission \ref SCHEDULING_REQUEST_CONFIG::dsr_TransMax. +typedef enum { + sr_n4=0, + sr_n8=1, + sr_n16=2, + sr_n32=3, + sr_n64=4 +} DSR_TRANSMAX_t; + +/// SchedulingRequestConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$n^{(1)}_\text{PUCCH,SRI}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t sr_PUCCH_ResourceIndex; + /// Parameter: \f$I_\text{SR}\f$, see TS 36.213 (10.1). \vr{[0..155]} + uint8_t sr_ConfigIndex; + /// Parameter for SR transmission in TS 36.321 (5.4.4). \details The value n4 corresponds to 4 transmissions, n8 corresponds to 8 transmissions and so on. + DSR_TRANSMAX_t dsr_TransMax; +} SCHEDULING_REQUEST_CONFIG; + +/// CQI-ReportPeriodic +typedef struct { + /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}, -1 indicates inactivity + int16_t cqi_PUCCH_ResourceIndex; + /// Parameter: CQI/PMI Periodicity and Offset Configuration Index \f$I_\text{CQI/PMI}\f$, see TS 36.213 (tables 7.2.2-1A and 7.2.2-1C). \vr{[0..1023]} + int16_t cqi_PMI_ConfigIndex; + /// Parameter: K, see 36.213 (4.2.2). \vr{[1..4]} + uint8_t K; + /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}, -1 indicates inactivity + int16_t ri_ConfigIndex; + /// Parameter: Simultaneous-AN-and-CQI, see TS 36.213 (10.1). \vr{[0..1]} 1 indicates that simultaneous transmission of ACK/NACK and CQI is allowed. + uint8_t simultaneousAckNackAndCQI; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t Npd; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t N_OFFSET_CQI; +} CQI_REPORTPERIODIC; + +/// Enumeration for parameter reporting mode \ref CQI_REPORT_CONFIG::cqi_ReportModeAperiodic. +typedef enum { + rm12=0, + rm20=1, + rm22=2, + rm30=3, + rm31=4 +} CQI_REPORTMODEAPERIODIC; + +/// CQI-ReportConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: reporting mode. Value rm12 corresponds to Mode 1-2, rm20 corresponds to Mode 2-0, rm22 corresponds to Mode 2-2 etc. PUSCH reporting modes are described in TS 36.213 [23, 7.2.1]. + CQI_REPORTMODEAPERIODIC cqi_ReportModeAperiodic; + /// Parameter: \f$\Delta_\text{offset}\f$, see TS 36.213 (7.2.3). \vr{[-1..6]}\n Actual value = IE value * 2 [dB]. + int8_t nomPDSCH_RS_EPRE_Offset; + CQI_REPORTPERIODIC CQI_ReportPeriodic; +} CQI_REPORT_CONFIG; + +/// MBSFN-SubframeConfig Information Element from 36.331 RRC spec \note deviates from specification. +typedef struct { + /// MBSFN subframe occurance. \details Radio-frames that contain MBSFN subframes occur when equation SFN mod radioFrameAllocationPeriod = radioFrameAllocationOffset is satisfied. When fourFrames is used for subframeAllocation, the equation defines the first radio frame referred to in the description below. Values n1 and n2 are not applicable when fourFrames is used. \note the specification sais it is an enumerated value {n1, n2, n4, n8, n16, n32}. + int radioframeAllocationPeriod; + /// MBSFN subframe occurance. \vr{[0..7]}\n Radio-frames that contain MBSFN subframes occur when equation SFN mod radioFrameAllocationPeriod = radioFrameAllocationOffset is satisfied. When fourFrames is used for subframeAllocation, the equation defines the first radio frame referred to in the description below. Values n1 and n2 are not applicable when fourFrames is used. + int radioframeAllocationOffset; + /// oneFrame or fourFrames. \vr{[0..1]} + int fourFrames_flag; + /// Subframe configuration. \vr{[0..63]} (\ref fourFrames_flag == 0) or \vr{[0..16777215]} (\ref fourFrames_flag == 1) + /// \par fourFrames_flag == 0 + /// "1" denotes that the corresponding subframe is allocated for MBSFN. The following mapping applies:\n FDD: The first/leftmost bit defines the MBSFN allocation for subframe #1, the second bit for #2, third bit for #3 , fourth bit for #6, fifth bit for #7, sixth bit for #8.\n TDD: The first/leftmost bit defines the allocation for subframe #3, the second bit for #4, third bit for #7, fourth bit for #8, fifth bit for #9. Uplink subframes are not allocated. The last bit is not used. + /// \par fourFrames_flag == 1 + /// A bit-map indicating MBSFN subframe allocation in four consecutive radio frames, "1" denotes that the corresponding subframe is allocated for MBSFN. The bitmap is interpreted as follows:\n FDD: Starting from the first radioframe and from the first/leftmost bit in the bitmap, the allocation applies to subframes #1, #2, #3 , #6, #7, and #8 in the sequence of the four radio-frames.\n TDD: Starting from the first radioframe and from the first/leftmost bit in the bitmap, the allocation applies to subframes #3, #4, #7, #8, and #9 in the sequence of the four radio-frames. The last four bits are not used. Uplink subframes are not allocated. + int mbsfn_SubframeConfig; +} MBSFN_config_t; + +typedef struct { + /// Number of resource blocks (RB) in DL + uint8_t N_RB_DL; + /// Number of resource blocks (RB) in UL + uint8_t N_RB_UL; + /// EUTRA Band + uint8_t eutra_band; + /// DL carrier frequency + uint32_t dl_CarrierFreq; + /// UL carrier frequency + uint32_t ul_CarrierFreq; + /// TX attenuation + uint32_t att_tx; + /// RX attenuation + uint32_t att_rx; + /// total Number of Resource Block Groups: this is ceil(N_PRB/P) + uint8_t N_RBG; + /// Total Number of Resource Block Groups SubSets: this is P + uint8_t N_RBGS; + /// Cell ID + uint16_t Nid_cell; + /// MBSFN Area ID + uint16_t Nid_cell_mbsfn; + /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP) + lte_prefix_type_t Ncp; + /// Cyclic Prefix for UL (0=Normal CP, 1=Extended CP) + lte_prefix_type_t Ncp_UL; + /// shift of pilot position in one RB + uint8_t nushift; + /// Frame type (0 FDD, 1 TDD) + lte_frame_type_t frame_type; + /// TDD subframe assignment (0-7) (default = 3) (254=RX only, 255=TX only) + uint8_t tdd_config; + /// TDD S-subframe configuration (0-9) + uint8_t tdd_config_S; + /// srs extra symbol flag for TDD + uint8_t srsX; + /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0). + uint8_t node_id; + /// Indicator that 20 MHz channel uses 3/4 sampling frequency + uint8_t threequarter_fs; + /// Size of FFT + uint16_t ofdm_symbol_size; + /// Number of prefix samples in all but first symbol of slot + uint16_t nb_prefix_samples; + /// Number of prefix samples in first symbol of slot + uint16_t nb_prefix_samples0; + /// Carrier offset in FFT buffer for first RE in PRB0 + uint16_t first_carrier_offset; + /// Number of samples in a subframe + uint32_t samples_per_tti; + /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) + uint16_t symbols_per_tti; + /// Number of OFDM symbols in DL portion of S-subframe + uint16_t dl_symbols_in_S_subframe; + /// Number of SC-FDMA symbols in UL portion of S-subframe + uint16_t ul_symbols_in_S_subframe; + /// Number of Physical transmit antennas in node + uint8_t nb_antennas_tx; + /// Number of Receive antennas in node + uint8_t nb_antennas_rx; + /// Number of common transmit antenna ports in eNodeB (1 or 2) + uint8_t nb_antenna_ports_eNB; + /// PRACH_CONFIG + PRACH_CONFIG_COMMON prach_config_common; +#ifdef Rel14 + /// PRACH_eMTC_CONFIG + PRACH_eMTC_CONFIG_COMMON prach_emtc_config_common; +#endif + /// PUCCH Config Common (from 36-331 RRC spec) + PUCCH_CONFIG_COMMON pucch_config_common; + /// PDSCH Config Common (from 36-331 RRC spec) + PDSCH_CONFIG_COMMON pdsch_config_common; + /// PUSCH Config Common (from 36-331 RRC spec) + PUSCH_CONFIG_COMMON pusch_config_common; + /// PHICH Config (from 36-331 RRC spec) + PHICH_CONFIG_COMMON phich_config_common; + /// SRS Config (from 36-331 RRC spec) + SOUNDINGRS_UL_CONFIG_COMMON soundingrs_ul_config_common; + /// UL Power Control (from 36-331 RRC spec) + UL_POWER_CONTROL_CONFIG_COMMON ul_power_control_config_common; + /// Number of MBSFN Configurations + int num_MBSFN_config; + /// Array of MBSFN Configurations (max 8 (maxMBSFN-Allocations) elements as per 36.331) + MBSFN_config_t MBSFN_config[8]; + /// Maximum Number of Retransmissions of RRCConnectionRequest (from 36-331 RRC Spec) + uint8_t maxHARQ_Msg3Tx; + /// Size of SI windows used for repetition of one SI message (in frames) + uint8_t SIwindowsize; + /// Period of SI windows used for repetition of one SI message (in frames) + uint16_t SIPeriod; + /// REGs assigned to PCFICH + uint16_t pcfich_reg[4]; + /// Index of first REG assigned to PCFICH + uint8_t pcfich_first_reg_idx; + /// REGs assigned to PHICH + uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; + + struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[MAX_MBSFN_AREA]; + /// for fair RR scheduler + uint32_t ue_multiple_max; +} LTE_DL_FRAME_PARMS; + +typedef enum { + /// TM1 + SISO=0, + /// TM2 + ALAMOUTI=1, + /// TM3 + LARGE_CDD=2, + /// the next 6 entries are for TM5 + UNIFORM_PRECODING11=3, + UNIFORM_PRECODING1m1=4, + UNIFORM_PRECODING1j=5, + UNIFORM_PRECODING1mj=6, + PUSCH_PRECODING0=7, + PUSCH_PRECODING1=8, + /// the next 3 entries are for TM4 + DUALSTREAM_UNIFORM_PRECODING1=9, + DUALSTREAM_UNIFORM_PRECODINGj=10, + DUALSTREAM_PUSCH_PRECODING=11, + TM7=12, + TM8=13, + TM9_10=14 +} MIMO_mode_t; + + +typedef enum { + /// MRT + MRT=0, + /// ZF + ZF=1, + /// MMSE + MMSE=2 +} PRECODE_TYPE_t; + +typedef enum {format0, + format1, + format1A, + format1B, + format1C, + format1D, + format1E_2A_M10PRB, + format2, + format2A, + format2B, + format2C, + format2D, + format3, + format3A, + format4, + format5, + format6_0A, + format6_0B, + format6_1A, + format6_1B, + format6_2 + } DCI_format_t; + +typedef struct { + /// Length of DCI in bits + uint8_t dci_length; + /// Aggregation level + uint8_t L; + /// Position of first CCE of the dci + int firstCCE; + /// flag to indicate that this is a RA response + boolean_t ra_flag; + /// rnti + rnti_t rnti; + /// harq_pid + rnti_t harq_pid; + /// Format + DCI_format_t format; + /// DCI pdu + uint8_t dci_pdu[8]; +} DCI_ALLOC_t; + +#define MAX_EPDCCH_PRB 8 + +typedef struct { + /// Length of DCI in bits + uint8_t dci_length; + /// Aggregation level + uint8_t L; + /// Position of first CCE of the dci + int firstCCE; + /// flag to indicate that this is a RA response + boolean_t ra_flag; + /// rnti + rnti_t rnti; + /// Format + DCI_format_t format; + /// epdcch resource assignment (0=localized,1=distributed) + uint8_t epdcch_resource_assignment_flag; + /// epdcch index + uint16_t epdcch_id; + /// epdcch start symbol + uint8_t epdcch_start_symbol; + /// epdcch number of PRBs in set + uint8_t epdcch_num_prb; + /// vector of prb ids for set + uint8_t epdcch_prb_index[MAX_EPDCCH_PRB]; + /// LBT parameter for frame configuration + uint8_t dwpts_symbols; + /// LBT parameter for frame configuration + uint8_t initial_lbt_sf; + /// DCI pdu + uint8_t dci_pdu[8]; +} eDCI_ALLOC_t; + +typedef struct { + /// Length of DCI in bits + uint8_t dci_length; + /// Aggregation level + uint8_t L; + /// Position of first CCE of the dci + int firstCCE; + /// flag to indicate that this is a RA response + boolean_t ra_flag; + /// rnti + rnti_t rnti; + /// Format + DCI_format_t format; + /// harq process index + uint8_t harq_pid; + /// Narrowband index + uint8_t narrowband; + /// number of PRB pairs for MPDCCH + uint8_t number_of_prb_pairs; + /// mpdcch resource assignment (combinatorial index r) + uint8_t resource_block_assignment; + /// transmission type (0=localized,1=distributed) + uint8_t transmission_type; + /// mpdcch start symbol + uint8_t start_symbol; + /// CE mode (1=ModeA,2=ModeB) + uint8_t ce_mode; + /// 0-503 n_EPDCCHid_i + uint16_t dmrs_scrambling_init; + /// Absolute subframe of the initial transmission (0-10239) + uint16_t i0; + /// number of mdpcch repetitions + uint16_t reps; + /// current absolute subframe number + uint16_t absSF; + /// DCI pdu + uint8_t dci_pdu[8]; +} mDCI_ALLOC_t; + +typedef struct { + /// Preamble index for PRACH (0-63) + uint8_t ra_PreambleIndex; + /// RACH MaskIndex + uint8_t ra_RACH_MaskIndex; + /// Target received power at eNB (-120 ... -82 dBm) + int8_t ra_PREAMBLE_RECEIVED_TARGET_POWER; + /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex + uint8_t ra_TDD_map_index; + /// Corresponding RA-RNTI for UL-grant + uint16_t ra_RNTI; + /// Pointer to Msg3 payload for UL-grant + uint8_t *Msg3; +} PRACH_RESOURCES_t; + + +typedef struct { + /// Downlink Power offset field + uint8_t dl_pow_off; + ///Subband resource allocation field + uint8_t rballoc_sub[50]; + ///Total number of PRBs indicator + uint8_t pre_nb_available_rbs; +} MU_MIMO_mode; + +typedef enum { + NOT_SYNCHED=0, + PRACH=1, + RA_RESPONSE=2, + PUSCH=3, + RESYNCH=4 +} UE_MODE_t; + + + +typedef enum {SF_DL, SF_UL, SF_S} lte_subframe_t; + +#define NUMBER_OF_SUBBANDS_MAX 13 +#define NUMBER_OF_HARQ_PID_MAX 8 + +#define MAX_FRAME_NUMBER 0x400 + + + +#define NUMBER_OF_RN_MAX 3 +typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t; + + + +#define MCS_COUNT 28 +#define MCS_TABLE_LENGTH_MAX 64 + + +#define NUM_DCI_MAX 32 + +#define NUMBER_OF_eNB_SECTORS_MAX 3 + +#define NB_BANDS_MAX 8 + +#define MAX_BANDS_PER_RRU 4 + + +#ifdef OCP_FRAMEWORK +#include <enums.h> +#else +typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5,calib_prach_tx=6,rx_dump_frame=7,loop_through_memory=8} runmode_t; + +/*! \brief Extension Type */ +typedef enum { + CYCLIC_PREFIX, + CYCLIC_SUFFIX, + ZEROS, + NONE +} Extension_t; + +enum transmission_access_mode { + NO_ACCESS=0, + POSTPONED_ACCESS, + CANCELED_ACCESS, + UNKNOWN_ACCESS, + SCHEDULED_ACCESS, + CBA_ACCESS}; + +typedef enum { + eNodeB_3GPP=0, // classical eNodeB function + NGFI_RAU_IF5, // RAU with NGFI IF5 + NGFI_RAU_IF4p5, // RAU with NFGI IF4p5 + NGFI_RRU_IF5, // NGFI_RRU (NGFI remote radio-unit,IF5) + NGFI_RRU_IF4p5, // NGFI_RRU (NGFI remote radio-unit,IF4p5) + MBP_RRU_IF5 // Mobipass RRU +} node_function_t; + +typedef enum { + + synch_to_ext_device=0, // synch to RF or Ethernet device + synch_to_other, // synch to another source_(timer, other RU) + synch_to_mobipass_standalone // special case for mobipass in standalone mode +} node_timing_t; +#endif + + +void exit_fun(const char* s); + +#include "UTIL/LOG/log_extern.h" +extern pthread_cond_t sync_cond; +extern pthread_mutex_t sync_mutex; +extern int sync_var; + + +#define MODE_DECODE_NONE 0 +#define MODE_DECODE_SSE 1 +#define MODE_DECODE_C 2 +#define MODE_DECODE_AVX2 3 + +#define DECODE_INITTD8_SSE_FPTRIDX 0 +#define DECODE_INITTD16_SSE_FPTRIDX 1 +#define DECODE_INITTD_AVX2_FPTRIDX 2 +#define DECODE_TD8_SSE_FPTRIDX 3 +#define DECODE_TD16_SSE_FPTRIDX 4 +#define DECODE_TD_C_FPTRIDX 5 +#define DECODE_TD16_AVX2_FPTRIDX 6 +#define DECODE_FREETD8_FPTRIDX 7 +#define DECODE_FREETD16_FPTRIDX 8 +#define DECODE_FREETD_AVX2_FPTRIDX 9 +#define ENCODE_SSE_FPTRIDX 10 +#define ENCODE_C_FPTRIDX 11 +#define ENCODE_INIT_SSE_FPTRIDX 12 +#define DECODE_NUM_FPTR 13 + + +typedef uint8_t(*decoder_if_t)(int16_t *y, + int16_t *y2, + uint8_t *decoded_bytes, + uint8_t *decoded_bytes2, + uint16_t n, + uint16_t f1, + uint16_t f2, + uint8_t max_iterations, + uint8_t crc_type, + uint8_t F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats); + +typedef uint8_t(*encoder_if_t)(uint8_t *input, + uint16_t input_length_bytes, + uint8_t *output, + uint8_t F, + uint16_t interleaver_f1, + uint16_t interleaver_f2); + + +static inline void wait_sync(char *thread_name) { + + printf( "waiting for sync (%s)\n",thread_name); + pthread_mutex_lock( &sync_mutex ); + + while (sync_var<0) + pthread_cond_wait( &sync_cond, &sync_mutex ); + + pthread_mutex_unlock(&sync_mutex); + + printf( "got sync (%s)\n", thread_name); + +} + +static inline int wakeup_thread(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { + + if (pthread_mutex_lock(mutex) != 0) { + LOG_E( PHY, "error locking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + *instance_cnt = *instance_cnt + 1; + // the thread can now be woken up + if (pthread_cond_signal(cond) != 0) { + LOG_E( PHY, "ERROR pthread_cond_signal\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock(mutex); + return(0); +} + +static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { + if (pthread_mutex_lock(mutex) != 0) { + LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + + while (*instance_cnt < 0) { + // most of the time the thread is waiting here + // proc->instance_cnt_rxtx is -1 + pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again + } + + if (pthread_mutex_unlock(mutex) != 0) { + LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + return(0); +} + +static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { + + if (pthread_mutex_lock(mutex) != 0) { + LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + + while (*instance_cnt == 0) { + // most of the time the thread will skip this + // waits only if proc->instance_cnt_rxtx is 0 + pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again + } + + if (pthread_mutex_unlock(mutex) != 0) { + LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + return(0); +} + +static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) { + + if (pthread_mutex_lock(mutex) != 0) { + LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + + *instance_cnt=*instance_cnt-1; + + if (pthread_mutex_unlock(mutex) != 0) { + LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for %s\n",name); + exit_fun("nothing to add"); + return(-1); + } + return(0); +} + + +#endif // __PHY_DEFS__H__ diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs_eNB.h similarity index 54% rename from openair1/PHY/defs.h rename to openair1/PHY/defs_eNB.h index e15978106d35d6a8a3032e44fe3e5e6fe7dca1ab..f0bfbbe683f236b70ac4fbf3bda9de73cc152d88 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs_eNB.h @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file PHY/defs.h - \brief Top-level defines and structure definitions +/*! \file PHY/defs_eNB.h + \brief Top-level defines and structure definitions for eNB \author R. Knopp, F. Kaltenberger \date 2011 \version 0.1 @@ -29,8 +29,8 @@ \note \warning */ -#ifndef __PHY_DEFS__H__ -#define __PHY_DEFS__H__ +#ifndef __PHY_DEFS_ENB__H__ +#define __PHY_DEFS_ENB__H__ #define _GNU_SOURCE @@ -57,229 +57,20 @@ #include "common_lib.h" #include "msc.h" -#include "openair2/PHY_INTERFACE/IF_Module.h" - -//#include <complex.h> -#include "assertions.h" -#ifdef MEX -# define msg mexPrintf -#endif -//use msg in the real-time thread context -#define msg_nrt printf -//use msg_nrt in the non real-time context (for initialization, ...) -#ifndef malloc16 -# ifdef __AVX2__ -# define malloc16(x) memalign(32,x) -# else -# define malloc16(x) memalign(16,x) -# endif -#endif -#define free16(y,x) free(y) -#define bigmalloc malloc -#define bigmalloc16 malloc16 -#define openair_free(y,x) free((y)) -#define PAGE_SIZE 4096 - -#define RX_NB_TH_MAX 2 -#define RX_NB_TH 2 - - -//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards. -//! If no more memory is available, this function will terminate the program with an assertion error. -static inline void* malloc16_clear( size_t size ) -{ -#ifdef __AVX2__ - void* ptr = memalign(32, size); -#else - void* ptr = memalign(16, size); -#endif - DevAssert(ptr); - memset( ptr, 0, size ); - return ptr; -} - - - -#define PAGE_MASK 0xfffff000 -#define virt_to_phys(x) (x) - -#define openair_sched_exit() exit(-1) - - -#define max(a,b) ((a)>(b) ? (a) : (b)) -#define min(a,b) ((a)<(b) ? (a) : (b)) - - -#define bzero(s,n) (memset((s),0,(n))) - -#define cmax(a,b) ((a>b) ? (a) : (b)) -#define cmin(a,b) ((a<b) ? (a) : (b)) - -#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) - -/// suppress compiler warning for unused arguments -#define UNUSED(x) (void)x; - +#include "defs_common.h" #include "impl_defs_top.h" -#include "impl_defs_lte.h" - #include "PHY/TOOLS/time_meas.h" -#include "PHY/CODING/defs.h" -#include "PHY/TOOLS/defs.h" +//#include "PHY/CODING/coding_defs.h" +#include "PHY/TOOLS/tools_defs.h" #include "platform_types.h" -#define MAX_NUM_RU_PER_eNB 64 - -#include "PHY/LTE_TRANSPORT/defs.h" +#include "PHY/LTE_TRANSPORT/transport_common.h" +#include "PHY/LTE_TRANSPORT/transport_eNB.h" #include <pthread.h> -#include "targets/ARCH/COMMON/common_lib.h" -#include "targets/COMMON/openairinterface5g_limits.h" - -#if 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 3 -//#define NUMBER_OF_UE_MAX 16 -//#define NUMBER_OF_RU_MAX 64 -//#define NUMBER_OF_CONNECTED_eNB_MAX 1 -#endif -#endif -#define NUMBER_OF_SUBBANDS_MAX 13 -#define NUMBER_OF_HARQ_PID_MAX 8 - -#define MAX_FRAME_NUMBER 0x400 - - - -#define NUMBER_OF_RN_MAX 3 -typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t; - - - -#define MCS_COUNT 28 -#define MCS_TABLE_LENGTH_MAX 64 - - -#define NUM_DCI_MAX 32 - -#define NUMBER_OF_eNB_SECTORS_MAX 3 - -#define NB_BANDS_MAX 8 - -#define MAX_BANDS_PER_RRU 4 - - -#ifdef OCP_FRAMEWORK -#include <enums.h> -#else -typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5,calib_prach_tx=6,rx_dump_frame=7,loop_through_memory=8} runmode_t; - -/*! \brief Extension Type */ -typedef enum { - CYCLIC_PREFIX, - CYCLIC_SUFFIX, - ZEROS, - NONE -} Extension_t; - -enum transmission_access_mode { - NO_ACCESS=0, - POSTPONED_ACCESS, - CANCELED_ACCESS, - UNKNOWN_ACCESS, - SCHEDULED_ACCESS, - CBA_ACCESS}; - -typedef enum { - eNodeB_3GPP=0, // classical eNodeB function - NGFI_RAU_IF5, // RAU with NGFI IF5 - NGFI_RAU_IF4p5, // RAU with NFGI IF4p5 - NGFI_RRU_IF5, // NGFI_RRU (NGFI remote radio-unit,IF5) - NGFI_RRU_IF4p5, // NGFI_RRU (NGFI remote radio-unit,IF4p5) - MBP_RRU_IF5 // Mobipass RRU -} node_function_t; - -typedef enum { - - synch_to_ext_device=0, // synch to RF or Ethernet device - synch_to_other, // synch to another source_(timer, other RU) - synch_to_mobipass_standalone // special case for mobipass in standalone mode -} node_timing_t; -#endif - -typedef struct UE_SCAN_INFO_s { - /// 10 best amplitudes (linear) for each pss signals - int32_t amp[3][10]; - /// 10 frequency offsets (kHz) corresponding to best amplitudes, with respect do minimum DL frequency in the band - int32_t freq_offset_Hz[3][10]; -} UE_SCAN_INFO_t; - -/// Top-level PHY Data Structure for RN -typedef struct { - /// Module ID indicator for this instance - uint8_t Mod_id; - uint32_t frame; - // phy_vars_eNB - // phy_vars ue - // cuurently only used to store and forward the PMCH - uint8_t mch_avtive[10]; - uint8_t sync_area[10]; // num SF - LTE_UE_DLSCH_t *dlsch_rn_MCH[10]; - -} PHY_VARS_RN; - -/// Context data structure for RX/TX portion of subframe processing -typedef struct { - /// Component Carrier index - uint8_t CC_id; - /// timestamp transmitted to HW - openair0_timestamp timestamp_tx; - /// subframe to act upon for transmission - int subframe_tx; - /// subframe to act upon for reception - int subframe_rx; - /// frame to act upon for transmission - int frame_tx; - /// frame to act upon for reception - int frame_rx; - /// \brief Instance count for RXn-TXnp4 processing thread. - /// \internal This variable is protected by \ref mutex_rxtx. - int instance_cnt_rxtx; - /// pthread structure for RXn-TXnp4 processing thread - pthread_t pthread_rxtx; - /// pthread attributes for RXn-TXnp4 processing thread - pthread_attr_t attr_rxtx; - /// condition variable for tx processing thread - pthread_cond_t cond_rxtx; - /// mutex for RXn-TXnp4 processing thread - pthread_mutex_t mutex_rxtx; - /// scheduling parameters for RXn-TXnp4 thread - struct sched_param sched_param_rxtx; -} eNB_rxtx_proc_t; -typedef struct { - struct PHY_VARS_eNB_s *eNB; - int UE_id; - int harq_pid; - int llr8_flag; - int ret; -} td_params; +#include "openair2/PHY_INTERFACE/IF_Module.h" -typedef struct { - struct PHY_VARS_eNB_s *eNB; - LTE_eNB_DLSCH_t *dlsch; - int G; - int harq_pid; -} te_params; typedef struct RU_proc_t_s { /// Pointer to associated RU descriptor @@ -294,7 +85,7 @@ typedef struct RU_proc_t_s { int subframe_tx; /// subframe to act upon for reception of prach int subframe_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// subframe to act upon for reception of prach BL/CE UEs int subframe_prach_br; #endif @@ -306,7 +97,7 @@ typedef struct RU_proc_t_s { int frame_tx_unwrap; /// frame to act upon for reception of prach int frame_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// frame to act upon for reception of prach int frame_prach_br; #endif @@ -315,9 +106,10 @@ typedef struct RU_proc_t_s { /// \brief Instance count for FH processing thread. /// \internal This variable is protected by \ref mutex_FH. int instance_cnt_FH; + int instance_cnt_FH1; /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach_br; #endif @@ -330,13 +122,16 @@ typedef struct RU_proc_t_s { int instance_cnt_asynch_rxtx; /// \internal This variable is protected by \ref mutex_fep int instance_cnt_fep; - /// \internal This variable is protected by \ref mutex_fep + /// \internal This variable is protected by \ref mutex_feptx int instance_cnt_feptx; + /// This varible is protected by \ref mutex_emulatedRF + int instance_cnt_emulateRF; /// pthread structure for RU FH processing thread pthread_t pthread_FH; + pthread_t pthread_FH1; /// pthread structure for RU prach processing thread pthread_t pthread_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// pthread structure for RU prach processing thread BL/CE UEs pthread_t pthread_prach_br; #endif @@ -344,8 +139,10 @@ typedef struct RU_proc_t_s { pthread_t pthread_synch; /// pthread struct for RU RX FEP worker thread pthread_t pthread_fep; - /// pthread struct for RU RX FEPTX worker thread + /// pthread struct for RU TX FEP worker thread pthread_t pthread_feptx; + /// pthread struct for emulated RF + pthread_t pthread_emulateRF; /// pthread structure for asychronous RX/TX processing thread pthread_t pthread_asynch_rxtx; /// flag to indicate first RX acquisition @@ -354,9 +151,10 @@ typedef struct RU_proc_t_s { int first_tx; /// pthread attributes for RU FH processing thread pthread_attr_t attr_FH; + pthread_attr_t attr_FH1; /// pthread attributes for RU prach pthread_attr_t attr_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// pthread attributes for RU prach BL/CE UEs pthread_attr_t attr_prach_br; #endif @@ -368,11 +166,14 @@ typedef struct RU_proc_t_s { pthread_attr_t attr_fep; /// pthread attributes for worker feptx thread pthread_attr_t attr_feptx; + /// pthread attributes for emulated RF + pthread_attr_t attr_emulateRF; /// scheduling parameters for RU FH thread struct sched_param sched_param_FH; + struct sched_param sched_param_FH1; /// scheduling parameters for RU prach thread struct sched_param sched_param_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// scheduling parameters for RU prach thread BL/CE UEs struct sched_param sched_param_prach_br; #endif @@ -382,9 +183,10 @@ typedef struct RU_proc_t_s { struct sched_param sched_param_asynch_rxtx; /// condition variable for RU FH thread pthread_cond_t cond_FH; + pthread_cond_t cond_FH1; /// condition variable for RU prach thread pthread_cond_t cond_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// condition variable for RU prach thread BL/CE UEs pthread_cond_t cond_prach_br; #endif @@ -392,17 +194,20 @@ typedef struct RU_proc_t_s { pthread_cond_t cond_synch; /// condition variable for asynch RX/TX thread pthread_cond_t cond_asynch_rxtx; - /// condition varaible for RU RX FEP thread + /// condition varible for RU RX FEP thread pthread_cond_t cond_fep; - /// condition varaible for RU RX FEPTX thread + /// condition varible for RU TX FEP thread pthread_cond_t cond_feptx; + /// condition varible for emulated RF + pthread_cond_t cond_emulateRF; /// condition variable for eNB signal pthread_cond_t cond_eNBs; /// mutex for RU FH pthread_mutex_t mutex_FH; + pthread_mutex_t mutex_FH1; /// mutex for RU prach pthread_mutex_t mutex_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// mutex for RU prach BL/CE UEs pthread_mutex_t mutex_prach_br; #endif @@ -416,6 +221,8 @@ typedef struct RU_proc_t_s { pthread_mutex_t mutex_fep; /// mutex for fep TX worker thread pthread_mutex_t mutex_feptx; + /// mutex for emulated RF thread + pthread_mutex_t mutex_emulateRF; /// symbol mask for IF4p5 reception per subframe uint32_t symbol_mask[10]; /// number of slave threads @@ -450,234 +257,11 @@ typedef struct RU_proc_t_s { pthread_mutex_t mutex_pre_scd; int instance_pre_scd; #endif + /// pipeline ready state + int ru_rx_ready; + int ru_tx_ready; } RU_proc_t; -/// Context data structure for eNB subframe processing -typedef struct eNB_proc_t_s { - /// Component Carrier index - uint8_t CC_id; - /// thread index - int thread_index; - /// timestamp received from HW - openair0_timestamp timestamp_rx; - /// timestamp to send to "slave rru" - openair0_timestamp timestamp_tx; - /// subframe to act upon for reception - int subframe_rx; - /// subframe to act upon for PRACH - int subframe_prach; -#ifdef Rel14 - /// subframe to act upon for reception of prach BL/CE UEs - int subframe_prach_br; -#endif - /// frame to act upon for reception - int frame_rx; - /// frame to act upon for transmission - int frame_tx; - /// frame to act upon for PRACH - int frame_prach; -#ifdef Rel14 - /// frame to act upon for PRACH BL/CE UEs - int frame_prach_br; -#endif - /// \internal This variable is protected by \ref mutex_td. - int instance_cnt_td; - /// \internal This variable is protected by \ref mutex_te. - int instance_cnt_te; - /// \internal This variable is protected by \ref mutex_prach. - int instance_cnt_prach; -#ifdef Rel14 - /// \internal This variable is protected by \ref mutex_prach for BL/CE UEs. - int instance_cnt_prach_br; -#endif - // instance count for over-the-air eNB synchronization - int instance_cnt_synch; - /// \internal This variable is protected by \ref mutex_asynch_rxtx. - int instance_cnt_asynch_rxtx; - /// pthread structure for eNB single processing thread - pthread_t pthread_single; - /// pthread structure for asychronous RX/TX processing thread - pthread_t pthread_asynch_rxtx; - /// flag to indicate first RX acquisition - int first_rx; - /// flag to indicate first TX transmission - int first_tx; - /// pthread attributes for parallel turbo-decoder thread - pthread_attr_t attr_td; - /// pthread attributes for parallel turbo-encoder thread - pthread_attr_t attr_te; - /// pthread attributes for single eNB processing thread - pthread_attr_t attr_single; - /// pthread attributes for prach processing thread - pthread_attr_t attr_prach; -#ifdef Rel14 - /// pthread attributes for prach processing thread BL/CE UEs - pthread_attr_t attr_prach_br; -#endif - /// pthread attributes for asynchronous RX thread - pthread_attr_t attr_asynch_rxtx; - /// scheduling parameters for parallel turbo-decoder thread - struct sched_param sched_param_td; - /// scheduling parameters for parallel turbo-encoder thread - struct sched_param sched_param_te; - /// scheduling parameters for single eNB thread - struct sched_param sched_param_single; - /// scheduling parameters for prach thread - struct sched_param sched_param_prach; -#ifdef Rel14 - /// scheduling parameters for prach thread - struct sched_param sched_param_prach_br; -#endif - /// scheduling parameters for asynch_rxtx thread - struct sched_param sched_param_asynch_rxtx; - /// pthread structure for parallel turbo-decoder thread - pthread_t pthread_td; - /// pthread structure for parallel turbo-encoder thread - pthread_t pthread_te; - /// pthread structure for PRACH thread - pthread_t pthread_prach; -#ifdef Rel14 - /// pthread structure for PRACH thread BL/CE UEs - pthread_t pthread_prach_br; -#endif - /// condition variable for parallel turbo-decoder thread - pthread_cond_t cond_td; - /// condition variable for parallel turbo-encoder thread - pthread_cond_t cond_te; - /// condition variable for PRACH processing thread; - pthread_cond_t cond_prach; -#ifdef Rel14 - /// condition variable for PRACH processing thread BL/CE UEs; - pthread_cond_t cond_prach_br; -#endif - /// condition variable for asynch RX/TX thread - pthread_cond_t cond_asynch_rxtx; - /// mutex for parallel turbo-decoder thread - pthread_mutex_t mutex_td; - /// mutex for parallel turbo-encoder thread - pthread_mutex_t mutex_te; - /// mutex for PRACH thread - pthread_mutex_t mutex_prach; -#ifdef Rel14 - /// mutex for PRACH thread for BL/CE UEs - pthread_mutex_t mutex_prach_br; -#endif - /// mutex for asynch RX/TX thread - pthread_mutex_t mutex_asynch_rxtx; - /// mutex for RU access to eNB processing (PDSCH/PUSCH) - pthread_mutex_t mutex_RU; - /// mutex for RU access to eNB processing (PRACH) - pthread_mutex_t mutex_RU_PRACH; - /// mutex for RU access to eNB processing (PRACH BR) - pthread_mutex_t mutex_RU_PRACH_br; - /// mask for RUs serving eNB (PDSCH/PUSCH) - int RU_mask; - /// mask for RUs serving eNB (PRACH) - int RU_mask_prach; -#ifdef Rel14 - /// mask for RUs serving eNB (PRACH) - int RU_mask_prach_br; -#endif - /// parameters for turbo-decoding worker thread - td_params tdp; - /// parameters for turbo-encoding worker thread - te_params tep; - /// set of scheduling variables RXn-TXnp4 threads - eNB_rxtx_proc_t proc_rxtx[2]; -} eNB_proc_t; - - -/// Context data structure for RX/TX portion of subframe processing -typedef struct { - /// index of the current UE RX/TX proc - int proc_id; - /// Component Carrier index - uint8_t CC_id; - /// timestamp transmitted to HW - openair0_timestamp timestamp_tx; - /// subframe to act upon for transmission - int subframe_tx; - /// subframe to act upon for reception - int subframe_rx; - /// frame to act upon for transmission - int frame_tx; - /// frame to act upon for reception - int frame_rx; - /// \brief Instance count for RXn-TXnp4 processing thread. - /// \internal This variable is protected by \ref mutex_rxtx. - int instance_cnt_rxtx; - /// pthread structure for RXn-TXnp4 processing thread - pthread_t pthread_rxtx; - /// pthread attributes for RXn-TXnp4 processing thread - pthread_attr_t attr_rxtx; - /// condition variable for tx processing thread - pthread_cond_t cond_rxtx; - /// mutex for RXn-TXnp4 processing thread - pthread_mutex_t mutex_rxtx; - /// scheduling parameters for RXn-TXnp4 thread - struct sched_param sched_param_rxtx; - - /// internal This variable is protected by ref mutex_fep_slot1. - //int instance_cnt_slot0_dl_processing; - int instance_cnt_slot1_dl_processing; - /// pthread descriptor fep_slot1 thread - //pthread_t pthread_slot0_dl_processing; - pthread_t pthread_slot1_dl_processing; - /// pthread attributes for fep_slot1 processing thread - // pthread_attr_t attr_slot0_dl_processing; - pthread_attr_t attr_slot1_dl_processing; - /// condition variable for UE fep_slot1 thread; - //pthread_cond_t cond_slot0_dl_processing; - pthread_cond_t cond_slot1_dl_processing; - /// mutex for UE synch thread - //pthread_mutex_t mutex_slot0_dl_processing; - pthread_mutex_t mutex_slot1_dl_processing; - // - uint8_t chan_est_pilot0_slot1_available; - uint8_t chan_est_slot1_available; - uint8_t llr_slot1_available; - uint8_t dci_slot0_available; - uint8_t first_symbol_available; - //uint8_t channel_level; - /// scheduling parameters for fep_slot1 thread - struct sched_param sched_param_fep_slot1; - - int sub_frame_start; - int sub_frame_step; - unsigned long long gotIQs; -} UE_rxtx_proc_t; - -/// Context data structure for eNB subframe processing -typedef struct { - /// Component Carrier index - uint8_t CC_id; - /// Last RX timestamp - openair0_timestamp timestamp_rx; - /// pthread attributes for main UE thread - pthread_attr_t attr_ue; - /// scheduling parameters for main UE thread - struct sched_param sched_param_ue; - /// pthread descriptor main UE thread - pthread_t pthread_ue; - /// \brief Instance count for synch thread. - /// \internal This variable is protected by \ref mutex_synch. - int instance_cnt_synch; - /// pthread attributes for synch processing thread - pthread_attr_t attr_synch; - /// scheduling parameters for synch thread - struct sched_param sched_param_synch; - /// pthread descriptor synch thread - pthread_t pthread_synch; - /// condition variable for UE synch thread; - pthread_cond_t cond_synch; - /// mutex for UE synch thread - pthread_mutex_t mutex_synch; - /// instance count for eNBs - int instance_cnt_eNBs; - /// set of scheduling variables RXn-TXnp4 threads - UE_rxtx_proc_t proc_rxtx[RX_NB_TH]; -} UE_proc_t; - typedef enum { LOCAL_RF =0, REMOTE_IF5 =1, @@ -685,6 +269,7 @@ typedef enum { REMOTE_IF4p5 =3, REMOTE_IF1pp =4, MAX_RU_IF_TYPES =5 + //EMULATE_RF =6 } RU_if_south_t; typedef struct RU_t_s{ @@ -760,6 +345,8 @@ typedef struct RU_t_s{ void (*fh_south_asynch_in)(struct RU_t_s *ru,int *frame, int *subframe); /// function pointer to initialization function for radio interface int (*start_rf)(struct RU_t_s *ru); + /// function pointer to release function for radio interface + int (*stop_rf)(struct RU_t_s *ru); /// function pointer to initialization function for radio interface int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL) @@ -772,14 +359,24 @@ typedef struct RU_t_s{ int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru); /// function pointer to wakeup routine in lte-enb. void (*wakeup_prach_eNB)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe); +#ifdef Rel14 /// function pointer to wakeup routine in lte-enb. void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe); +#endif /// function pointer to eNB entry routine - void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string); + void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru); /// Timing statistics time_stats_t ofdm_demod_stats; /// Timing statistics (TX) time_stats_t ofdm_mod_stats; + /// Timing wait statistics + time_stats_t ofdm_demod_wait_stats; + /// Timing wakeup statistics + time_stats_t ofdm_demod_wakeup_stats; + /// Timing wait statistics (TX) + time_stats_t ofdm_mod_wait_stats; + /// Timing wakeup statistics (TX) + time_stats_t ofdm_mod_wakeup_stats; /// Timing statistics (RX Fronthaul + Compression) time_stats_t rx_fhaul; /// Timing statistics (TX Fronthaul + Compression) @@ -804,102 +401,437 @@ typedef struct RU_t_s{ /// process scheduling variables RU_proc_t proc; /// stats thread pthread descriptor - pthread_t ru_stats_thread; -} RU_t; + pthread_t ru_stats_thread; + +} RU_t; + + + +#define MAX_RRU_CONFIG_SIZE 1024 +typedef enum { + RAU_tick=0, + RRU_capabilities=1, + RRU_config=2, + RRU_MSG_max_num=3 +} rru_config_msg_type_t; + +typedef struct RRU_CONFIG_msg_s { + rru_config_msg_type_t type; + ssize_t len; + uint8_t msg[MAX_RRU_CONFIG_SIZE]; +} RRU_CONFIG_msg_t; + +typedef enum { + OAI_IF5_only =0, + OAI_IF4p5_only =1, + OAI_IF5_and_IF4p5 =2, + MBP_IF5 =3, + MAX_FH_FMTs =4 +} FH_fmt_options_t; + +#define MAX_BANDS_PER_RRU 4 + +typedef struct RRU_capabilities_s { + /// Fronthaul format + FH_fmt_options_t FH_fmt; + /// number of EUTRA bands (<=4) supported by RRU + uint8_t num_bands; + /// EUTRA band list supported by RRU + uint8_t band_list[MAX_BANDS_PER_RRU]; + /// Number of concurrent bands (component carriers) + uint8_t num_concurrent_bands; + /// Maximum TX EPRE of each band + int8_t max_pdschReferenceSignalPower[MAX_BANDS_PER_RRU]; + /// Maximum RX gain of each band + uint8_t max_rxgain[MAX_BANDS_PER_RRU]; + /// Number of RX ports of each band + uint8_t nb_rx[MAX_BANDS_PER_RRU]; + /// Number of TX ports of each band + uint8_t nb_tx[MAX_BANDS_PER_RRU]; + /// max DL bandwidth (1,6,15,25,50,75,100) + uint8_t N_RB_DL[MAX_BANDS_PER_RRU]; + /// max UL bandwidth (1,6,15,25,50,75,100) + uint8_t N_RB_UL[MAX_BANDS_PER_RRU]; +} RRU_capabilities_t; + +typedef struct RRU_config_s { + + /// Fronthaul format + RU_if_south_t FH_fmt; + /// number of EUTRA bands (<=4) configured in RRU + uint8_t num_bands; + /// EUTRA band list configured in RRU + uint8_t band_list[MAX_BANDS_PER_RRU]; + /// TDD configuration (0-6) + uint8_t tdd_config[MAX_BANDS_PER_RRU]; + /// TDD special subframe configuration (0-10) + uint8_t tdd_config_S[MAX_BANDS_PER_RRU]; + /// TX frequency + uint32_t tx_freq[MAX_BANDS_PER_RRU]; + /// RX frequency + uint32_t rx_freq[MAX_BANDS_PER_RRU]; + /// TX attenation w.r.t. max + uint8_t att_tx[MAX_BANDS_PER_RRU]; + /// RX attenuation w.r.t. max + uint8_t att_rx[MAX_BANDS_PER_RRU]; + /// DL bandwidth + uint8_t N_RB_DL[MAX_BANDS_PER_RRU]; + /// UL bandwidth + uint8_t N_RB_UL[MAX_BANDS_PER_RRU]; + /// 3/4 sampling rate + uint8_t threequarter_fs[MAX_BANDS_PER_RRU]; + /// prach_FreqOffset for IF4p5 + int prach_FreqOffset[MAX_BANDS_PER_RRU]; + /// prach_ConfigIndex for IF4p5 + int prach_ConfigIndex[MAX_BANDS_PER_RRU]; +#ifdef Rel14 + int emtc_prach_CElevel_enable[MAX_BANDS_PER_RRU][4]; + /// emtc_prach_FreqOffset for IF4p5 per CE Level + int emtc_prach_FreqOffset[MAX_BANDS_PER_RRU][4]; + /// emtc_prach_ConfigIndex for IF4p5 per CE Level + int emtc_prach_ConfigIndex[MAX_BANDS_PER_RRU][4]; +#endif +} RRU_config_t; + + +typedef struct { + /// \brief Pointers (dynamic) to the received data in the time domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdata; + /// \brief Pointers (dynamic) to the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdataF; + /// \brief holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? + /// - first index: eNB id [0..2] (hard coded) + /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. + /// - third index: sample [0..] + int32_t **txdataF; +} LTE_eNB_COMMON; + +typedef struct { + uint8_t num_dci; + uint8_t num_pdcch_symbols; + DCI_ALLOC_t dci_alloc[32]; +} LTE_eNB_PDCCH; + +typedef struct { + uint8_t hi; + uint8_t first_rb; + uint8_t n_DMRS; +} phich_config_t; + +typedef struct { + uint8_t num_hi; + phich_config_t config[32]; +} LTE_eNB_PHICH; + +typedef struct { + uint8_t num_dci; + eDCI_ALLOC_t edci_alloc[32]; +} LTE_eNB_EPDCCH; + +typedef struct { + /// number of active MPDCCH allocations + uint8_t num_dci; + /// MPDCCH DCI allocations from MAC + mDCI_ALLOC_t mdci_alloc[32]; + // MAX SIZE of an EPDCCH set is 16EREGs * 9REs/EREG * 8 PRB pairs = 2304 bits + uint8_t e[2304]; +} LTE_eNB_MPDCCH; + + +typedef struct { + /// \brief Hold the channel estimates in frequency domain based on SRS. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..ofdm_symbol_size[ + int32_t **srs_ch_estimates; + /// \brief Hold the channel estimates in time domain based on SRS. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size[ + int32_t **srs_ch_estimates_time; + /// \brief Holds the SRS for channel estimation at the RX. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..ofdm_symbol_size[ + int32_t *srs; +} LTE_eNB_SRS; + +typedef struct { + /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size[ + int32_t **rxdataF_ext; + /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_ext2; + /// \brief Hold the channel estimates in time domain based on DRS. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..4*ofdm_symbol_size[ + int32_t **drs_ch_estimates_time; + /// \brief Hold the channel estimates in frequency domain based on DRS. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates; + /// \brief Holds the compensated signal. + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp; + /// \brief Magnitude of the UL channel estimates. Used for 2nd-bit level thresholds in LLR computation + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag; + /// \brief Magnitude of the UL channel estimates scaled for 3rd bit level thresholds in LLR computation + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb; + /// measured RX power based on DRS + int ulsch_power[2]; + /// \brief llr values. + /// - first index: ? [0..1179743] (hard coded) + int16_t *llr; +} LTE_eNB_PUSCH; + +#define PBCH_A 24 +typedef struct { + uint8_t pbch_d[96+(3*(16+PBCH_A))]; + uint8_t pbch_w[3*3*(16+PBCH_A)]; + uint8_t pbch_e[1920]; +} LTE_eNB_PBCH; + +#define MAX_NUM_RX_PRACH_PREAMBLES 4 + +typedef struct { + /// \brief ?. + /// first index: ? [0..1023] (hard coded) + int16_t *prachF; + /// \brief ?. + /// first index: ce_level [0..3] + /// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// third index: frequency-domain sample [0..ofdm_symbol_size*12[ + int16_t **rxsigF[4]; + /// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs) + /// first index: ce_level [0..3] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// second index: ? [0..63] (hard coded) + /// third index: ? [0..63] (hard coded) + int32_t **prach_ifft[4]; + + /// repetition number +#ifdef Rel14 + /// indicator of first frame in a group of PRACH repetitions + int first_frame[4]; + /// current repetition for each CE level + int repetition_number[4]; +#endif +} LTE_eNB_PRACH; + +#include "PHY/TOOLS/time_meas.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/TOOLS/tools_defs.h" +#include "PHY/LTE_TRANSPORT/transport_eNB.h" + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// Component Carrier index + uint8_t CC_id; + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_rxtx; + /// scheduling parameters for RXn-TXnp4 thread + struct sched_param sched_param_rxtx; + /// pipeline ready state + int pipe_ready; +} eNB_rxtx_proc_t; + +typedef struct { + struct PHY_VARS_eNB_s *eNB; + int UE_id; + int harq_pid; + int llr8_flag; + int ret; +} td_params; + +typedef struct { + struct PHY_VARS_eNB_s *eNB; + LTE_eNB_DLSCH_t *dlsch; + int G; + int harq_pid; + int total_worker; + int current_worker; + /// \internal This variable is protected by \ref mutex_te. + int instance_cnt_te; + /// pthread attributes for parallel turbo-encoder thread + pthread_attr_t attr_te; + /// scheduling parameters for parallel turbo-encoder thread + struct sched_param sched_param_te; + /// pthread structure for parallel turbo-encoder thread + pthread_t pthread_te; + /// condition variable for parallel turbo-encoder thread + pthread_cond_t cond_te; + /// mutex for parallel turbo-encoder thread + pthread_mutex_t mutex_te; +} te_params; + +/// Context data structure for eNB subframe processing +typedef struct eNB_proc_t_s { + /// Component Carrier index + uint8_t CC_id; + /// thread index + int thread_index; + /// timestamp received from HW + openair0_timestamp timestamp_rx; + /// timestamp to send to "slave rru" + openair0_timestamp timestamp_tx; + /// subframe to act upon for reception + int subframe_rx; + /// subframe to act upon for PRACH + int subframe_prach; +#ifdef Rel14 + /// subframe to act upon for reception of prach BL/CE UEs + int subframe_prach_br; +#endif + /// frame to act upon for reception + int frame_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for PRACH + int frame_prach; +#ifdef Rel14 + /// frame to act upon for PRACH BL/CE UEs + int frame_prach_br; +#endif + /// \internal This variable is protected by \ref mutex_td. + int instance_cnt_td; + /// \internal This variable is protected by \ref mutex_te. + int instance_cnt_te; + /// \internal This variable is protected by \ref mutex_prach. + int instance_cnt_prach; +#ifdef Rel14 + /// \internal This variable is protected by \ref mutex_prach for BL/CE UEs. + int instance_cnt_prach_br; +#endif + // instance count for over-the-air eNB synchronization + int instance_cnt_synch; + /// \internal This variable is protected by \ref mutex_asynch_rxtx. + int instance_cnt_asynch_rxtx; + /// pthread structure for asychronous RX/TX processing thread + pthread_t pthread_asynch_rxtx; + /// flag to indicate first RX acquisition + int first_rx; + /// flag to indicate first TX transmission + int first_tx; + /// pthread attributes for parallel turbo-decoder thread + pthread_attr_t attr_td; + /// pthread attributes for parallel turbo-encoder thread + pthread_attr_t attr_te; + /// pthread attributes for single eNB processing thread + pthread_attr_t attr_single; + /// pthread attributes for prach processing thread + pthread_attr_t attr_prach; +#ifdef Rel14 + /// pthread attributes for prach processing thread BL/CE UEs + pthread_attr_t attr_prach_br; +#endif + /// pthread attributes for asynchronous RX thread + pthread_attr_t attr_asynch_rxtx; + /// scheduling parameters for parallel turbo-decoder thread + struct sched_param sched_param_td; + /// scheduling parameters for parallel turbo-encoder thread + struct sched_param sched_param_te; + /// scheduling parameters for single eNB thread + struct sched_param sched_param_single; + /// scheduling parameters for prach thread + struct sched_param sched_param_prach; +#ifdef Rel14 + /// scheduling parameters for prach thread + struct sched_param sched_param_prach_br; +#endif + /// scheduling parameters for asynch_rxtx thread + struct sched_param sched_param_asynch_rxtx; + /// pthread structure for parallel turbo-decoder thread + pthread_t pthread_td; + /// pthread structure for parallel turbo-encoder thread + pthread_t pthread_te; + /// pthread structure for PRACH thread + pthread_t pthread_prach; +#ifdef Rel14 + /// pthread structure for PRACH thread BL/CE UEs + pthread_t pthread_prach_br; +#endif + /// condition variable for parallel turbo-decoder thread + pthread_cond_t cond_td; + /// condition variable for parallel turbo-encoder thread + pthread_cond_t cond_te; + /// condition variable for PRACH processing thread; + pthread_cond_t cond_prach; +#ifdef Rel14 + /// condition variable for PRACH processing thread BL/CE UEs; + pthread_cond_t cond_prach_br; +#endif + /// condition variable for asynch RX/TX thread + pthread_cond_t cond_asynch_rxtx; + /// mutex for parallel turbo-decoder thread + pthread_mutex_t mutex_td; + /// mutex for parallel turbo-encoder thread + pthread_mutex_t mutex_te; + /// mutex for PRACH thread + pthread_mutex_t mutex_prach; +#ifdef Rel14 + /// mutex for PRACH thread for BL/CE UEs + pthread_mutex_t mutex_prach_br; +#endif + /// mutex for asynch RX/TX thread + pthread_mutex_t mutex_asynch_rxtx; + /// mutex for RU access to eNB processing (PDSCH/PUSCH) + pthread_mutex_t mutex_RU; + /// mutex for RU access to eNB processing (PRACH) + pthread_mutex_t mutex_RU_PRACH; + /// mutex for RU access to eNB processing (PRACH BR) + pthread_mutex_t mutex_RU_PRACH_br; + /// mask for RUs serving eNB (PDSCH/PUSCH) + int RU_mask; + /// mask for RUs serving eNB (PRACH) + int RU_mask_prach; +#ifdef Rel14 + /// mask for RUs serving eNB (PRACH) + int RU_mask_prach_br; +#endif + /// parameters for turbo-decoding worker thread + td_params tdp; + /// parameters for turbo-encoding worker thread + te_params tep[3]; + /// set of scheduling variables RXn-TXnp4 threads + eNB_rxtx_proc_t proc_rxtx[2]; + /// stats thread pthread descriptor + pthread_t process_stats_thread; + /// for waking up tx procedure + RU_proc_t *ru_proc; +} eNB_proc_t; -typedef struct { - //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) - //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) - //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) - // RRC measurements - uint32_t rssi; - int n_adj_cells; - unsigned int adj_cell_id[6]; - uint32_t rsrq[7]; - uint32_t rsrp[7]; - float rsrp_filtered[7]; // after layer 3 filtering - float rsrq_filtered[7]; - // common measurements - //! estimated noise power (linear) - unsigned int n0_power[NB_ANTENNAS_RX]; - //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; - //! total estimated noise power (linear) - unsigned int n0_power_tot; - //! total estimated noise power (dB) - unsigned short n0_power_tot_dB; - //! average estimated noise power (linear) - unsigned int n0_power_avg; - //! average estimated noise power (dB) - unsigned short n0_power_avg_dB; - //! total estimated noise power (dBm) - short n0_power_tot_dBm; - // UE measurements - //! estimated received spatial signal power (linear) - int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; - //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; - - /// estimated received signal power (sum over all TX antennas) - //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - /// estimated received signal power (sum over all TX antennas) - //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - - /// estimated received signal power (sum over all TX/RX antennas) - int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW - /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW - - //! estimated received signal power (sum of all TX/RX antennas, time average) - int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; - //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// SINR (sum of all TX/RX antennas, in dB) - int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; - /// SINR (sum of all TX/RX antennas, time average, in dB) - int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; - //! estimated rssi (dBm) - short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; - //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) - int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; - //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) - int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; - - /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) - int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; - /// Subband CQI per RX antenna (= SINR) - int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; - /// Total Subband CQI (= SINR) - int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Subband CQI in dB (= SINR dB) - int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; - /// Total Subband CQI - int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Wideband PMI for each RX antenna - int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - /// Wideband PMI for each RX antenna - int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - ///Subband PMI for each RX antenna - int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; - ///Subband PMI for each RX antenna - int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; - /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) - unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Wideband Rank indication - unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; - /// Number of RX Antennas - unsigned char nb_antennas_rx; - /// DLSCH error counter - // short dlsch_errors; - -} PHY_MEASUREMENTS; typedef struct { //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) @@ -973,7 +905,7 @@ typedef struct PHY_VARS_eNB_s { eth_params_t eth_params; int rx_total_gain_dB; int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag); - int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); + int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *); int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); uint8_t local_flag; LTE_DL_FRAME_PARMS frame_parms; @@ -995,14 +927,14 @@ typedef struct PHY_VARS_eNB_s { nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU]; /// NFAPI PRACH information nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// NFAPI PRACH information BL/CE UEs nfapi_preamble_pdu_t preamble_list_br[MAX_NUM_RX_PRACH_PREAMBLES]; #endif Sched_Rsp_t Sched_INFO; LTE_eNB_PDCCH pdcch_vars[2]; LTE_eNB_PHICH phich_vars[2]; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LTE_eNB_EPDCCH epdcch_vars[2]; LTE_eNB_MPDCCH mpdcch_vars[2]; LTE_eNB_PRACH prach_vars_br; @@ -1034,7 +966,7 @@ typedef struct PHY_VARS_eNB_s { uint32_t lte_gold_mbsfn_table[10][3][42]; uint32_t X_u[64][839]; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t X_u_br[4][64][839]; #endif uint8_t pbch_configured; @@ -1152,7 +1084,14 @@ typedef struct PHY_VARS_eNB_s { time_stats_t dlsch_modulation_stats; time_stats_t dlsch_scrambling_stats; time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_preperation_stats; + time_stats_t dlsch_turbo_encoding_segmentation_stats; time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_turbo_encoding_waiting_stats; + time_stats_t dlsch_turbo_encoding_signal_stats; + time_stats_t dlsch_turbo_encoding_main_stats; + time_stats_t dlsch_turbo_encoding_wakeup_stats0; + time_stats_t dlsch_turbo_encoding_wakeup_stats1; time_stats_t dlsch_interleaving_stats; time_stats_t rx_dft_stats; @@ -1173,11 +1112,6 @@ typedef struct PHY_VARS_eNB_s { time_stats_t ulsch_tc_intl1_stats; time_stats_t ulsch_tc_intl2_stats; -#ifdef LOCALIZATION - /// time state for localization - time_stats_t localization_stats; -#endif - int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX][10]; int32_t pucch1_stats[NUMBER_OF_UE_MAX][10*1024]; int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX][10*1024]; @@ -1190,465 +1124,4 @@ typedef struct PHY_VARS_eNB_s { int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240]; } PHY_VARS_eNB; -#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg - -/// Top-level PHY Data Structure for UE -typedef struct { - /// \brief Module ID indicator for this instance - uint8_t Mod_id; - /// \brief Component carrier ID for this PHY instance - uint8_t CC_id; - /// \brief Mapping of CC_id antennas to cards - openair0_rf_map rf_map; - //uint8_t local_flag; - /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach) - runmode_t mode; - /// \brief Indicator that UE should perform band scanning - int UE_scan; - /// \brief Indicator that UE should perform coarse scanning around carrier - int UE_scan_carrier; - /// \brief Indicator that UE is synchronized to an eNB - int is_synchronized; - /// Data structure for UE process scheduling - UE_proc_t proc; - /// Flag to indicate the UE shouldn't do timing correction at all - int no_timing_correction; - /// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna) - uint32_t tx_total_gain_dB; - /// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card. - uint32_t rx_total_gain_dB; - /// \brief Total gains with maximum RF gain stage (ExpressMIMO2/Lime) - uint32_t rx_gain_max[4]; - /// \brief Total gains with medium RF gain stage (ExpressMIMO2/Lime) - uint32_t rx_gain_med[4]; - /// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime) - uint32_t rx_gain_byp[4]; - /// \brief Current transmit power - int16_t tx_power_dBm[10]; - /// \brief Total number of REs in current transmission - int tx_total_RE[10]; - /// \brief Maximum transmit power - int8_t tx_power_max_dBm; - /// \brief Number of eNB seen by UE - uint8_t n_connected_eNB; - /// \brief indicator that Handover procedure has been initiated - uint8_t ho_initiated; - /// \brief indicator that Handover procedure has been triggered - uint8_t ho_triggered; - /// \brief Measurement variables. - PHY_MEASUREMENTS measurements; - LTE_DL_FRAME_PARMS frame_parms; - /// \brief Frame parame before ho used to recover if ho fails. - LTE_DL_FRAME_PARMS frame_parms_before_ho; - LTE_UE_COMMON common_vars; - - // point to the current rxTx thread index - uint8_t current_thread_id[10]; - - LTE_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads - LTE_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1]; - LTE_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1]; - LTE_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1]; - LTE_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1]; - LTE_UE_PDSCH *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads - LTE_UE_ULSCH_t *ulsch[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_DLSCH_t *dlsch_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; - // This is for SIC in the UE, to store the reencoded data - LTE_eNB_DLSCH_t *dlsch_eNB[NUMBER_OF_CONNECTED_eNB_MAX]; - - //Paging parameters - uint32_t IMSImod1024; - uint32_t PF; - uint32_t PO; - - // For abstraction-purposes only - uint8_t sr[10]; - uint8_t pucch_sel[10]; - uint8_t pucch_payload[22]; - - UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX]; - /// cell-specific reference symbols - uint32_t lte_gold_table[7][20][2][14]; - - /// UE-specific reference symbols (p=5), TM 7 - uint32_t lte_gold_uespec_port5_table[20][38]; - - /// ue-specific reference symbols - uint32_t lte_gold_uespec_table[2][20][2][21]; - - /// mbsfn reference symbols - uint32_t lte_gold_mbsfn_table[10][3][42]; - - uint32_t X_u[64][839]; - - uint32_t high_speed_flag; - uint32_t perfect_ce; - int16_t ch_est_alpha; - int generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX]; - - UE_SCAN_INFO_t scan_info[NB_BANDS_MAX]; - - char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX]; - - - - unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX]; - uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX]; - unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX]; - PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX]; - int turbo_iterations, turbo_cntl_iterations; - /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX]; - /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX]; - /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX]; - /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; - unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; - uint8_t generate_prach; - uint8_t prach_cnt; - uint8_t prach_PreambleIndex; - // uint8_t prach_timer; - uint8_t decode_SIB; - uint8_t decode_MIB; - int rx_offset; /// Timing offset - int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP - int time_sync_cell; - int timing_advance; ///timing advance signalled from eNB - int hw_timing_advance; - int N_TA_offset; ///timing offset used in TDD - /// Flag to tell if UE is secondary user (cognitive mode) - unsigned char is_secondary_ue; - /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from. - unsigned char has_valid_precoder; - /// hold the precoder for NULL beam to the primary eNB - int **ul_precoder_S_UE; - /// holds the maximum channel/precoder coefficient - char log2_maxp; - - /// if ==0 enables phy only test mode - int mac_enabled; - - /// Flag to initialize averaging of PHY measurements - int init_averaging; - - /// \brief sinr for all subcarriers of the current link (used only for abstraction). - /// - first index: ? [0..12*N_RB_DL[ - double *sinr_dB; - - /// \brief sinr for all subcarriers of first symbol for the CQI Calculation. - /// - first index: ? [0..12*N_RB_DL[ - double *sinr_CQI_dB; - - /// sinr_effective used for CQI calulcation - double sinr_eff; - - /// N0 (used for abstraction) - double N0; - - /// PDSCH Varaibles - PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// PUSCH Varaibles - PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// PUSCH contention-based access vars - PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola - - /// PUCCH variables - - PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; - - uint8_t ncs_cell[20][7]; - - /// UL-POWER-Control - UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// TPC - TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX]; - TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// CQI reporting - CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// SRS Variables - SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// Scheduling Request Config - SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX]; - - /// Transmission mode per eNB - uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX]; - - time_stats_t phy_proc[RX_NB_TH]; - time_stats_t phy_proc_tx; - time_stats_t phy_proc_rx[RX_NB_TH]; - - uint32_t use_ia_receiver; - - time_stats_t ofdm_mod_stats; - time_stats_t ulsch_encoding_stats; - time_stats_t ulsch_modulation_stats; - time_stats_t ulsch_segmentation_stats; - time_stats_t ulsch_rate_matching_stats; - time_stats_t ulsch_turbo_encoding_stats; - time_stats_t ulsch_interleaving_stats; - time_stats_t ulsch_multiplexing_stats; - - time_stats_t generic_stat; - time_stats_t generic_stat_bis[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; - time_stats_t ue_front_end_stat[RX_NB_TH]; - time_stats_t ue_front_end_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; - time_stats_t pdcch_procedures_stat[RX_NB_TH]; - time_stats_t pdsch_procedures_stat[RX_NB_TH]; - time_stats_t pdsch_procedures_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; - time_stats_t dlsch_procedures_stat[RX_NB_TH]; - - time_stats_t ofdm_demod_stats; - time_stats_t dlsch_rx_pdcch_stats; - time_stats_t rx_dft_stats; - time_stats_t dlsch_channel_estimation_stats; - time_stats_t dlsch_freq_offset_estimation_stats; - time_stats_t dlsch_decoding_stats[2]; - time_stats_t dlsch_demodulation_stats; - time_stats_t dlsch_rate_unmatching_stats; - time_stats_t dlsch_turbo_decoding_stats; - time_stats_t dlsch_deinterleaving_stats; - time_stats_t dlsch_llr_stats; - time_stats_t dlsch_llr_stats_parallelization[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; - time_stats_t dlsch_unscrambling_stats; - time_stats_t dlsch_rate_matching_stats; - time_stats_t dlsch_turbo_encoding_stats; - time_stats_t dlsch_interleaving_stats; - time_stats_t dlsch_tc_init_stats; - time_stats_t dlsch_tc_alpha_stats; - time_stats_t dlsch_tc_beta_stats; - time_stats_t dlsch_tc_gamma_stats; - time_stats_t dlsch_tc_ext_stats; - time_stats_t dlsch_tc_intl1_stats; - time_stats_t dlsch_tc_intl2_stats; - time_stats_t tx_prach; - - /// RF and Interface devices per CC - - openair0_device rfdevice; -} PHY_VARS_UE; - -/* this structure is used to pass both UE phy vars and - * proc to the function UE_thread_rxn_txnp4 - */ -struct rx_tx_thread_data { - PHY_VARS_UE *UE; - UE_rxtx_proc_t *proc; -}; - -void exit_fun(const char* s); - -#include "UTIL/LOG/log_extern.h" -extern pthread_cond_t sync_cond; -extern pthread_mutex_t sync_mutex; -extern int sync_var; - -#define MAX_RRU_CONFIG_SIZE 1024 -typedef enum { - RAU_tick=0, - RRU_capabilities=1, - RRU_config=2, - RRU_MSG_max_num=3 -} rru_config_msg_type_t; - -typedef struct RRU_CONFIG_msg_s { - rru_config_msg_type_t type; - ssize_t len; - uint8_t msg[MAX_RRU_CONFIG_SIZE]; -} RRU_CONFIG_msg_t; - -typedef enum { - OAI_IF5_only =0, - OAI_IF4p5_only =1, - OAI_IF5_and_IF4p5 =2, - MBP_IF5 =3, - MAX_FH_FMTs =4 -} FH_fmt_options_t; - -#define MAX_BANDS_PER_RRU 4 - -typedef struct RRU_capabilities_s { - /// Fronthaul format - FH_fmt_options_t FH_fmt; - /// number of EUTRA bands (<=4) supported by RRU - uint8_t num_bands; - /// EUTRA band list supported by RRU - uint8_t band_list[MAX_BANDS_PER_RRU]; - /// Number of concurrent bands (component carriers) - uint8_t num_concurrent_bands; - /// Maximum TX EPRE of each band - int8_t max_pdschReferenceSignalPower[MAX_BANDS_PER_RRU]; - /// Maximum RX gain of each band - uint8_t max_rxgain[MAX_BANDS_PER_RRU]; - /// Number of RX ports of each band - uint8_t nb_rx[MAX_BANDS_PER_RRU]; - /// Number of TX ports of each band - uint8_t nb_tx[MAX_BANDS_PER_RRU]; - /// max DL bandwidth (1,6,15,25,50,75,100) - uint8_t N_RB_DL[MAX_BANDS_PER_RRU]; - /// max UL bandwidth (1,6,15,25,50,75,100) - uint8_t N_RB_UL[MAX_BANDS_PER_RRU]; -} RRU_capabilities_t; - -typedef struct RRU_config_s { - - /// Fronthaul format - RU_if_south_t FH_fmt; - /// number of EUTRA bands (<=4) configured in RRU - uint8_t num_bands; - /// EUTRA band list configured in RRU - uint8_t band_list[MAX_BANDS_PER_RRU]; - /// TDD configuration (0-6) - uint8_t tdd_config[MAX_BANDS_PER_RRU]; - /// TDD special subframe configuration (0-10) - uint8_t tdd_config_S[MAX_BANDS_PER_RRU]; - /// TX frequency - uint32_t tx_freq[MAX_BANDS_PER_RRU]; - /// RX frequency - uint32_t rx_freq[MAX_BANDS_PER_RRU]; - /// TX attenation w.r.t. max - uint8_t att_tx[MAX_BANDS_PER_RRU]; - /// RX attenuation w.r.t. max - uint8_t att_rx[MAX_BANDS_PER_RRU]; - /// DL bandwidth - uint8_t N_RB_DL[MAX_BANDS_PER_RRU]; - /// UL bandwidth - uint8_t N_RB_UL[MAX_BANDS_PER_RRU]; - /// 3/4 sampling rate - uint8_t threequarter_fs[MAX_BANDS_PER_RRU]; - /// prach_FreqOffset for IF4p5 - int prach_FreqOffset[MAX_BANDS_PER_RRU]; - /// prach_ConfigIndex for IF4p5 - int prach_ConfigIndex[MAX_BANDS_PER_RRU]; -#ifdef Rel14 - int emtc_prach_CElevel_enable[MAX_BANDS_PER_RRU][4]; - /// emtc_prach_FreqOffset for IF4p5 per CE Level - int emtc_prach_FreqOffset[MAX_BANDS_PER_RRU][4]; - /// emtc_prach_ConfigIndex for IF4p5 per CE Level - int emtc_prach_ConfigIndex[MAX_BANDS_PER_RRU][4]; -#endif -} RRU_config_t; - - -static inline void wait_sync(char *thread_name) { - - printf( "waiting for sync (%s)\n",thread_name); - pthread_mutex_lock( &sync_mutex ); - - while (sync_var<0) - pthread_cond_wait( &sync_cond, &sync_mutex ); - - pthread_mutex_unlock(&sync_mutex); - - printf( "got sync (%s)\n", thread_name); - -} - -static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - - while (*instance_cnt < 0) { - // most of the time the thread is waiting here - // proc->instance_cnt_rxtx is -1 - pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again - } - - if (pthread_mutex_unlock(mutex) != 0) { - LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - return(0); -} - -static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - - while (*instance_cnt == 0) { - // most of the time the thread will skip this - // waits only if proc->instance_cnt_rxtx is 0 - pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again - } - - if (pthread_mutex_unlock(mutex) != 0) { - LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - return(0); -} - -static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - - *instance_cnt=*instance_cnt-1; - - if (pthread_mutex_unlock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - return(0); -} - - -#include "PHY/INIT/defs.h" -#include "PHY/LTE_REFSIG/defs.h" -#include "PHY/MODULATION/defs.h" -#include "PHY/LTE_TRANSPORT/proto.h" -#include "PHY/LTE_ESTIMATION/defs.h" - -#include "SIMULATION/ETH_TRANSPORT/defs.h" -#endif // __PHY_DEFS__H__ +#endif /* __PHY_DEFS_ENB__H__ */ diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index 31276c84b820ee90eabf4ca76a42f2d3343a36ab..d649dce100482c0fc70012c6b4cc64f51e8e8487 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -33,664 +33,6 @@ #ifndef __PHY_IMPLEMENTATION_DEFS_LTE_H__ #define __PHY_IMPLEMENTATION_DEFS_LTE_H__ - -#include "types.h" -#include "nfapi_interface.h" -//#include "defs.h" -#include "openair2/COMMON/platform_types.h" - -#define RX_NB_TH_MAX 2 -#define RX_NB_TH 2 - -#define LTE_SLOTS_PER_SUBFRAME 2 - -#define LTE_NUMBER_OF_SUBFRAMES_PER_FRAME 10 -#define LTE_SLOTS_PER_FRAME 20 -#define LTE_CE_FILTER_LENGTH 5 -#define LTE_CE_OFFSET LTE_CE_FILTER_LENGTH -#define TX_RX_SWITCH_SYMBOL (NUMBER_OF_SYMBOLS_PER_FRAME>>1) -#define PBCH_PDU_SIZE 3 //bytes - -#define PRACH_SYMBOL 3 //position of the UL PSS wrt 2nd slot of special subframe - -#define NUMBER_OF_FREQUENCY_GROUPS (lte_frame_parms->N_RB_DL) - -#define SSS_AMP 1148 - -#define MAX_NUM_PHICH_GROUPS 56 //110 RBs Ng=2, p.60 36-212, Sec. 6.9 - -#define MAX_MBSFN_AREA 8 - -#define NB_RX_ANTENNAS_MAX 64 - -#ifdef OCP_FRAMEWORK -#include "enums.h" -#else -typedef enum {TDD=1,FDD=0} lte_frame_type_t; - -typedef enum {EXTENDED=1,NORMAL=0} lte_prefix_type_t; - -typedef enum {LOCALIZED=0,DISTRIBUTED=1} vrb_t; - -/// Enumeration for parameter PHICH-Duration \ref PHICH_CONFIG_COMMON::phich_duration. -typedef enum { - normal=0, - extended=1 -} PHICH_DURATION_t; - -/// Enumeration for parameter Ng \ref PHICH_CONFIG_COMMON::phich_resource. -typedef enum { - oneSixth=1, - half=3, - one=6, - two=12 -} PHICH_RESOURCE_t; -#endif -/// PHICH-Config from 36.331 RRC spec -typedef struct { - /// Parameter: PHICH-Duration, see TS 36.211 (Table 6.9.3-1). - PHICH_DURATION_t phich_duration; - /// Parameter: Ng, see TS 36.211 (6.9). \details Value oneSixth corresponds to 1/6, half corresponds to 1/2 and so on. - PHICH_RESOURCE_t phich_resource; -} PHICH_CONFIG_COMMON; - -/// PRACH-ConfigInfo from 36.331 RRC spec -typedef struct { - /// Parameter: prach-ConfigurationIndex, see TS 36.211 (5.7.1). \vr{[0..63]} - uint8_t prach_ConfigIndex; - /// Parameter: High-speed-flag, see TS 36.211 (5.7.2). \vr{[0..1]} 1 corresponds to Restricted set and 0 to Unrestricted set. - uint8_t highSpeedFlag; - /// Parameter: \f$N_\text{CS}\f$, see TS 36.211 (5.7.2). \vr{[0..15]}\n Refer to table 5.7.2-2 for preamble format 0..3 and to table 5.7.2-3 for preamble format 4. - uint8_t zeroCorrelationZoneConfig; - /// Parameter: prach-FrequencyOffset, see TS 36.211 (5.7.1). \vr{[0..94]}\n For TDD the value range is dependent on the value of \ref prach_ConfigIndex. - uint8_t prach_FreqOffset; -} PRACH_CONFIG_INFO; - - - -/// PRACH-ConfigSIB or PRACH-Config from 36.331 RRC spec -typedef struct { - /// Parameter: RACH_ROOT_SEQUENCE, see TS 36.211 (5.7.1). \vr{[0..837]} - uint16_t rootSequenceIndex; - /// prach_Config_enabled=1 means enabled. \vr{[0..1]} - uint8_t prach_Config_enabled; - /// PRACH Configuration Information - PRACH_CONFIG_INFO prach_ConfigInfo; -} PRACH_CONFIG_COMMON; - -#ifdef Rel14 - -/// PRACH-eMTC-Config from 36.331 RRC spec -typedef struct { - /// Parameter: High-speed-flag, see TS 36.211 (5.7.2). \vr{[0..1]} 1 corresponds to Restricted set and 0 to Unrestricted set. - uint8_t highSpeedFlag; -/// Parameter: \f$N_\text{CS}\f$, see TS 36.211 (5.7.2). \vr{[0..15]}\n Refer to table 5.7.2-2 for preamble format 0..3 and to table 5.7.2-3 for preamble format 4. - uint8_t zeroCorrelationZoneConfig; - /// Parameter: prach-FrequencyOffset, see TS 36.211 (5.7.1). \vr{[0..94]}\n For TDD the value range is dependent on the value of \ref prach_ConfigIndex. - - /// PRACH starting subframe periodicity, expressed in number of subframes available for preamble transmission (PRACH opportunities), see TS 36.211. Value 2 corresponds to 2 subframes, 4 corresponds to 4 subframes and so on. EUTRAN configures the PRACH starting subframe periodicity larger than or equal to the Number of PRACH repetitions per attempt for each CE level (numRepetitionPerPreambleAttempt). - uint8_t prach_starting_subframe_periodicity[4]; - /// number of repetitions per preamble attempt per CE level - uint8_t prach_numRepetitionPerPreambleAttempt[4]; - /// prach configuration index for each CE level - uint8_t prach_ConfigIndex[4]; - /// indicator for CE level activation - uint8_t prach_CElevel_enable[4]; - /// prach frequency offset for each CE level - uint8_t prach_FreqOffset[4]; - /// indicator for CE level hopping activation - uint8_t prach_hopping_enable[4]; - /// indicator for CE level hopping activation - uint8_t prach_hopping_offset[4]; -} PRACH_eMTC_CONFIG_INFO; - -#endif - -/// PRACH-ConfigSIB or PRACH-Config from 36.331 RRC spec -typedef struct { - /// Parameter: RACH_ROOT_SEQUENCE, see TS 36.211 (5.7.1). \vr{[0..837]} - uint16_t rootSequenceIndex; - /// prach_Config_enabled=1 means enabled. \vr{[0..1]} - uint8_t prach_Config_enabled; - /// PRACH Configuration Information -#ifdef Rel14 - PRACH_eMTC_CONFIG_INFO prach_ConfigInfo; -#endif -} PRACH_eMTC_CONFIG_COMMON; - -/// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor. -typedef enum { - n2=0, - n4, - n6 -} ACKNAKREP_t; - -/// Enumeration for \ref PUCCH_CONFIG_DEDICATED::tdd_AckNackFeedbackMode. -typedef enum { - bundling=0, - multiplexing -} ANFBmode_t; - -/// PUCCH-ConfigDedicated from 36.331 RRC spec -typedef struct { - /// Flag to indicate ACK NAK repetition activation, see TS 36.213 (10.1). \vr{[0..1]} - uint8_t ackNackRepetition; - /// Parameter: \f$N_\text{ANRep}\f$, see TS 36.213 (10.1). - ACKNAKREP_t repetitionFactor; - /// Parameter: \f$n^{(1)}_\text{PUCCH,ANRep}\f$, see TS 36.213 (10.1). \vr{[0..2047]} - uint16_t n1PUCCH_AN_Rep; - /// Feedback mode, see TS 36.213 (7.3). \details Applied to both PUCCH and PUSCH feedback. For TDD, should always be set to bundling. - ANFBmode_t tdd_AckNackFeedbackMode; -} PUCCH_CONFIG_DEDICATED; - -/// PUCCH-ConfigCommon from 36.331 RRC spec -typedef struct { - /// Parameter: \f$\Delta^\text{PUCCH}_\text{shift}\f$, see TS 36.211 (5.4.1). \vr{[1..3]} \note the specification sais it is an enumerated value. - uint8_t deltaPUCCH_Shift; - /// Parameter: \f$N^{(2)}_\text{RB}\f$, see TS 36.211 (5.4). \vr{[0..98]} - uint8_t nRB_CQI; - /// Parameter: \f$N^{(1)}_\text{CS}\f$, see TS 36.211 (5.4). \vr{[0..7]} - uint8_t nCS_AN; - /// Parameter: \f$N^{(1)}_\text{PUCCH}\f$ see TS 36.213 (10.1). \vr{[0..2047]} - uint16_t n1PUCCH_AN; - - /// group hopping sequence for DRS \note not part of offical UL-PUCCH_CONFIG_COMMON ASN1 specification. - uint8_t grouphop[20]; - /// sequence hopping sequence for DRS \note not part of offical UL-PUCCH_CONFIG_COMMON ASN1 specification. - uint8_t seqhop[20]; -} PUCCH_CONFIG_COMMON; - -/// UL-ReferenceSignalsPUSCH from 36.331 RRC spec -typedef struct { - /// Parameter: Group-hopping-enabled, see TS 36.211 (5.5.1.3). \vr{[0..1]} - uint8_t groupHoppingEnabled; - /// Parameter: \f$\Delta SS\f$, see TS 36.211 (5.5.1.3). \vr{[0..29]} - uint8_t groupAssignmentPUSCH; - /// Parameter: Sequence-hopping-enabled, see TS 36.211 (5.5.1.4). \vr{[0..1]} - uint8_t sequenceHoppingEnabled; - /// Parameter: cyclicShift, see TS 36.211 (Table 5.5.2.1.1-2). \vr{[0..7]} - uint8_t cyclicShift; - /// nPRS for cyclic shift of DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. - uint8_t nPRS[20]; - /// group hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. - uint8_t grouphop[20]; - /// sequence hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. - uint8_t seqhop[20]; -} UL_REFERENCE_SIGNALS_PUSCH_t; - -/// Enumeration for parameter Hopping-mode \ref PUSCH_CONFIG_COMMON::hoppingMode. -#ifndef OCP_FRAMEWORK -typedef enum { - interSubFrame=0, - intraAndInterSubFrame=1 -} PUSCH_HOPPING_t; -#endif - -/// PUSCH-ConfigCommon from 36.331 RRC spec. -typedef struct { - /// Parameter: \f$N_{sb}\f$, see TS 36.211 (5.3.4). \vr{[1..4]} - uint8_t n_SB; - /// Parameter: Hopping-mode, see TS 36.211 (5.3.4). - PUSCH_HOPPING_t hoppingMode; - /// Parameter: \f$N^{HO}_{RB}\f$, see TS 36.211 (5.3.4). \vr{[0..98]} - uint8_t pusch_HoppingOffset; - /// See TS 36.213 (8.6.1). \vr{[0..1]} 1 indicates 64QAM is allowed, 0 not allowed. - uint8_t enable64QAM; - /// Ref signals configuration - UL_REFERENCE_SIGNALS_PUSCH_t ul_ReferenceSignalsPUSCH; -} PUSCH_CONFIG_COMMON; - -/// UE specific PUSCH configuration. -typedef struct { - /// Parameter: \f$I^\text{HARQ-ACK}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-1). \vr{[0..15]} - uint16_t betaOffset_ACK_Index; - /// Parameter: \f$I^{RI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-2). \vr{[0..15]} - uint16_t betaOffset_RI_Index; - /// Parameter: \f$I^{CQI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-3). \vr{[0..15]} - uint16_t betaOffset_CQI_Index; -} PUSCH_CONFIG_DEDICATED; - -/// lola CBA information -typedef struct { - /// - uint16_t betaOffset_CA_Index; - /// - uint16_t cShift; -} PUSCH_CA_CONFIG_DEDICATED; - -/// PDSCH-ConfigCommon from 36.331 RRC spec -typedef struct { - /// Parameter: Reference-signal power, see TS 36.213 (5.2). \vr{[-60..50]}\n Provides the downlink reference-signal EPRE. The actual value in dBm. - int8_t referenceSignalPower; - /// Parameter: \f$P_B\f$, see TS 36.213 (Table 5.2-1). \vr{[0..3]} - uint8_t p_b; -} PDSCH_CONFIG_COMMON; - -/// Enumeration for Parameter \f$P_A\f$ \ref PDSCH_CONFIG_DEDICATED::p_a. -typedef enum { - dBm6=0, ///< (dB-6) corresponds to -6 dB - dBm477, ///< (dB-4dot77) corresponds to -4.77 dB - dBm3, ///< (dB-3) corresponds to -3 dB - dBm177, ///< (dB-1dot77) corresponds to -1.77 dB - dB0, ///< corresponds to 0 dB - dB1, ///< corresponds to 1 dB - dB2, ///< corresponds to 2 dB - dB3 ///< corresponds to 3 dB -} PA_t; - -/// PDSCH-ConfigDedicated from 36.331 RRC spec -typedef struct { - /// Parameter: \f$P_A\f$, see TS 36.213 (5.2). - PA_t p_a; -} PDSCH_CONFIG_DEDICATED; - -/// SoundingRS-UL-ConfigCommon Information Element from 36.331 RRC spec -typedef struct { - /// enabled flag=1 means SRS is enabled. \vr{[0..1]} - uint8_t enabled_flag; - /// Parameter: SRS Bandwidth Configuration, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..7]}\n Actual configuration depends on UL bandwidth. \note the specification sais it is an enumerated value. - uint8_t srs_BandwidthConfig; - /// Parameter: SRS SubframeConfiguration, see TS 36.211 (table 5.5.3.3-1 for FDD, table 5.5.3.3-2 for TDD). \vr{[0..15]} \note the specification sais it is an enumerated value. - uint8_t srs_SubframeConfig; - /// Parameter: Simultaneous-AN-and-SRS, see TS 36.213 (8.2). \vr{[0..1]} - uint8_t ackNackSRS_SimultaneousTransmission; - /// Parameter: srsMaxUpPts, see TS 36.211 (5.5.3.2). \details If this field is present, reconfiguration of \f$m^\text{max}_\text{SRS,0}\f$ applies for UpPts, otherwise reconfiguration does not apply. - uint8_t srs_MaxUpPts; -} SOUNDINGRS_UL_CONFIG_COMMON; - -/// \note UNUSED -typedef enum { - ulpc_al0=0, - ulpc_al04=1, - ulpc_al05=2, - ulpc_al06=3, - ulpc_al07=4, - ulpc_al08=5, - ulpc_al09=6, - ulpc_al11=7 -} UL_POWER_CONTROL_COMMON_alpha_t; - -/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format1. -typedef enum { - deltaF_PUCCH_Format1_deltaF_2 = 0, - deltaF_PUCCH_Format1_deltaF0 = 1, - deltaF_PUCCH_Format1_deltaF2 = 2 -} deltaF_PUCCH_Format1_t; - -/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format1b. -typedef enum { - deltaF_PUCCH_Format1b_deltaF1 = 0, - deltaF_PUCCH_Format1b_deltaF3 = 1, - deltaF_PUCCH_Format1b_deltaF5 = 2 -} deltaF_PUCCH_Format1b_t; - -/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format2. -typedef enum { - deltaF_PUCCH_Format2_deltaF_2 = 0, - deltaF_PUCCH_Format2_deltaF0 = 1, - deltaF_PUCCH_Format2_deltaF1 = 2, - deltaF_PUCCH_Format2_deltaF2 = 3 -} deltaF_PUCCH_Format2_t; - -/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format2a. -typedef enum { - deltaF_PUCCH_Format2a_deltaF_2 = 0, - deltaF_PUCCH_Format2a_deltaF0 = 1, - deltaF_PUCCH_Format2a_deltaF2 = 2 -} deltaF_PUCCH_Format2a_t; - -/// Enumeration for \ref deltaFList_PUCCH_t::deltaF_PUCCH_Format2b. -typedef enum { - deltaF_PUCCH_Format2b_deltaF_2 = 0, - deltaF_PUCCH_Format2b_deltaF0 = 1, - deltaF_PUCCH_Format2b_deltaF2 = 2 -} deltaF_PUCCH_Format2b_t; - -/// DeltaFList-PUCCH from 36.331 RRC spec -typedef struct { - deltaF_PUCCH_Format1_t deltaF_PUCCH_Format1; - deltaF_PUCCH_Format1b_t deltaF_PUCCH_Format1b; - deltaF_PUCCH_Format2_t deltaF_PUCCH_Format2; - deltaF_PUCCH_Format2a_t deltaF_PUCCH_Format2a; - deltaF_PUCCH_Format2b_t deltaF_PUCCH_Format2b; -} deltaFList_PUCCH_t; - -/// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec -typedef struct { - /// This descriptor is active - uint8_t active; - /// This descriptor's frame - uint16_t frame; - /// This descriptor's subframe - uint8_t subframe; - /// rnti - uint16_t rnti; - /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value. - uint8_t srs_Bandwidth; - /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value. - uint8_t srs_HoppingBandwidth; - /// Parameter: \f$n_\text{RRC}\f$, see TS 36.211 (5.5.3.2). \vr{[0..23]} - uint8_t freqDomainPosition; - /// Parameter: Duration, see TS 36.213 (8.2). \vr{[0..1]} 0 corresponds to "single" and 1 to "indefinite". - uint8_t duration; - /// Parameter: \f$k_\text{TC}\in\{0,1\}\f$, see TS 36.211 (5.5.3.2). \vr{[0..1]} - uint8_t transmissionComb; - /// Parameter: \f$I_\text{SRS}\f$, see TS 36.213 (table 8.2-1). \vr{[0..1023]} - uint16_t srs_ConfigIndex; - /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value. - uint8_t cyclicShift; - // Parameter: internal implementation: UE SRS configured - uint8_t srsConfigDedicatedSetup; - // Parameter: cell srs subframe for internal implementation - uint8_t srsCellSubframe; - // Parameter: ue srs subframe for internal implementation - uint8_t srsUeSubframe; -} SOUNDINGRS_UL_CONFIG_DEDICATED; - -/// UplinkPowerControlDedicated Information Element from 36.331 RRC spec -typedef struct { - /// Parameter: \f$P_\text{0\_UE\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dB. \vr{[-8..7]}\n This field is applicable for non-persistent scheduling, only. - int8_t p0_UE_PUSCH; - /// Parameter: Ks, see TS 36.213 (5.1.1.1). \vr{[0..1]}\n en0 corresponds to value 0 corresponding to state “disabledâ€. en1 corresponds to value 1.25 corresponding to “enabledâ€. \note the specification sais it is an enumerated value. \warning the enumeration values do not correspond to the given values in the specification (en1 should be 1.25). - uint8_t deltaMCS_Enabled; - /// Parameter: Accumulation-enabled, see TS 36.213 (5.1.1.1). \vr{[0..1]} 1 corresponds to "enabled" whereas 0 corresponds to "disabled". - uint8_t accumulationEnabled; - /// Parameter: \f$P_\text{0\_UE\_PUCCH}(1)\f$, see TS 36.213 (5.1.2.1), unit dB. \vr{[-8..7]} - int8_t p0_UE_PUCCH; - /// Parameter: \f$P_\text{SRS\_OFFSET}\f$, see TS 36.213 (5.1.3.1). \vr{[0..15]}\n For Ks=1.25 (\ref deltaMCS_Enabled), the actual parameter value is pSRS_Offset value - 3. For Ks=0, the actual parameter value is -10.5 + 1.5*pSRS_Offset value. - int8_t pSRS_Offset; - /// Specifies the filtering coefficient for RSRP measurements used to calculate path loss, as specified in TS 36.213 (5.1.1.1).\details The same filtering mechanism applies as for quantityConfig described in 5.5.3.2. \note the specification sais it is an enumerated value. - uint8_t filterCoefficient; -} UL_POWER_CONTROL_DEDICATED; - -#ifndef OCP_FRAMEWORK -/// Enumeration for parameter \f$\alpha\f$ \ref UL_POWER_CONTROL_CONFIG_COMMON::alpha. -typedef enum { - al0=0, - al04=1, - al05=2, - al06=3, - al07=4, - al08=5, - al09=6, - al1=7 -} PUSCH_alpha_t; -#endif - -/// \note UNUSED -typedef enum { - deltaFm2=0, - deltaF0, - deltaF1, - deltaF2, - deltaF3, - deltaF5 -} deltaF_PUCCH_t; - -/// UplinkPowerControlCommon Information Element from 36.331 RRC spec \note this structure does not currently make use of \ref deltaFList_PUCCH_t. -typedef struct { - /// Parameter: \f$P_\text{0\_NOMINAL\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dBm. \vr{[-126..24]}\n This field is applicable for non-persistent scheduling, only. - int8_t p0_NominalPUSCH; - /// Parameter: \f$\alpha\f$, see TS 36.213 (5.1.1.1) \warning the enumeration values do not correspond to the given values in the specification (al04 should be 0.4, ...)! - PUSCH_alpha_t alpha; - /// Parameter: \f$P_\text{0\_NOMINAL\_PUCCH}\f$ See TS 36.213 (5.1.2.1), unit dBm. \vr{[-127..-96]} - int8_t p0_NominalPUCCH; - /// Parameter: \f$\Delta_\text{PREAMBLE\_Msg3}\f$ see TS 36.213 (5.1.1.1). \vr{[-1..6]}\n Actual value = IE value * 2 [dB]. - int8_t deltaPreambleMsg3; - /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 1, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. - long deltaF_PUCCH_Format1; - /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 1a, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. - long deltaF_PUCCH_Format1a; - /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 1b, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. - long deltaF_PUCCH_Format1b; - /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 2, see TS 36.213 (5.1.2). \vr{[0..3]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. - long deltaF_PUCCH_Format2; - /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 2a, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. - long deltaF_PUCCH_Format2a; - /// Parameter: \f$\Delta_\text{F\_PUCCH}(F)\f$ for the PUCCH format 2b, see TS 36.213 (5.1.2). \vr{[0..2]} \warning check value range, why is this a long? \note the specification sais it is an enumerated value. - long deltaF_PUCCH_Format2b; -} UL_POWER_CONTROL_CONFIG_COMMON; - -/// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. -typedef union { - /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} - uint8_t indexOfFormat3; - /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} - uint8_t indexOfFormat3A; -} TPC_INDEX_t; - -/// TPC-PDCCH-Config Information Element from 36.331 RRC spec -typedef struct { - /// RNTI for power control using DCI format 3/3A, see TS 36.212. \vr{[0..65535]} - uint16_t rnti; - /// Index of N or M, see TS 36.212 (5.3.3.1.6 and 5.3.3.1.7), where N or M is dependent on the used DCI format (i.e. format 3 or 3a). - TPC_INDEX_t tpc_Index; -} TPC_PDCCH_CONFIG; - -/// Enumeration for parameter SR transmission \ref SCHEDULING_REQUEST_CONFIG::dsr_TransMax. -typedef enum { - sr_n4=0, - sr_n8=1, - sr_n16=2, - sr_n32=3, - sr_n64=4 -} DSR_TRANSMAX_t; - -/// SchedulingRequestConfig Information Element from 36.331 RRC spec -typedef struct { - /// Parameter: \f$n^{(1)}_\text{PUCCH,SRI}\f$, see TS 36.213 (10.1). \vr{[0..2047]} - uint16_t sr_PUCCH_ResourceIndex; - /// Parameter: \f$I_\text{SR}\f$, see TS 36.213 (10.1). \vr{[0..155]} - uint8_t sr_ConfigIndex; - /// Parameter for SR transmission in TS 36.321 (5.4.4). \details The value n4 corresponds to 4 transmissions, n8 corresponds to 8 transmissions and so on. - DSR_TRANSMAX_t dsr_TransMax; -} SCHEDULING_REQUEST_CONFIG; - -/// CQI-ReportPeriodic -typedef struct { - /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}, -1 indicates inactivity - int16_t cqi_PUCCH_ResourceIndex; - /// Parameter: CQI/PMI Periodicity and Offset Configuration Index \f$I_\text{CQI/PMI}\f$, see TS 36.213 (tables 7.2.2-1A and 7.2.2-1C). \vr{[0..1023]} - int16_t cqi_PMI_ConfigIndex; - /// Parameter: K, see 36.213 (4.2.2). \vr{[1..4]} - uint8_t K; - /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}, -1 indicates inactivity - int16_t ri_ConfigIndex; - /// Parameter: Simultaneous-AN-and-CQI, see TS 36.213 (10.1). \vr{[0..1]} 1 indicates that simultaneous transmission of ACK/NACK and CQI is allowed. - uint8_t simultaneousAckNackAndCQI; - /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C - uint16_t Npd; - /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C - uint16_t N_OFFSET_CQI; -} CQI_REPORTPERIODIC; - -/// Enumeration for parameter reporting mode \ref CQI_REPORT_CONFIG::cqi_ReportModeAperiodic. -typedef enum { - rm12=0, - rm20=1, - rm22=2, - rm30=3, - rm31=4 -} CQI_REPORTMODEAPERIODIC; - -/// CQI-ReportConfig Information Element from 36.331 RRC spec -typedef struct { - /// Parameter: reporting mode. Value rm12 corresponds to Mode 1-2, rm20 corresponds to Mode 2-0, rm22 corresponds to Mode 2-2 etc. PUSCH reporting modes are described in TS 36.213 [23, 7.2.1]. - CQI_REPORTMODEAPERIODIC cqi_ReportModeAperiodic; - /// Parameter: \f$\Delta_\text{offset}\f$, see TS 36.213 (7.2.3). \vr{[-1..6]}\n Actual value = IE value * 2 [dB]. - int8_t nomPDSCH_RS_EPRE_Offset; - CQI_REPORTPERIODIC CQI_ReportPeriodic; -} CQI_REPORT_CONFIG; - -/// MBSFN-SubframeConfig Information Element from 36.331 RRC spec \note deviates from specification. -typedef struct { - /// MBSFN subframe occurance. \details Radio-frames that contain MBSFN subframes occur when equation SFN mod radioFrameAllocationPeriod = radioFrameAllocationOffset is satisfied. When fourFrames is used for subframeAllocation, the equation defines the first radio frame referred to in the description below. Values n1 and n2 are not applicable when fourFrames is used. \note the specification sais it is an enumerated value {n1, n2, n4, n8, n16, n32}. - int radioframeAllocationPeriod; - /// MBSFN subframe occurance. \vr{[0..7]}\n Radio-frames that contain MBSFN subframes occur when equation SFN mod radioFrameAllocationPeriod = radioFrameAllocationOffset is satisfied. When fourFrames is used for subframeAllocation, the equation defines the first radio frame referred to in the description below. Values n1 and n2 are not applicable when fourFrames is used. - int radioframeAllocationOffset; - /// oneFrame or fourFrames. \vr{[0..1]} - int fourFrames_flag; - /// Subframe configuration. \vr{[0..63]} (\ref fourFrames_flag == 0) or \vr{[0..16777215]} (\ref fourFrames_flag == 1) - /// \par fourFrames_flag == 0 - /// "1" denotes that the corresponding subframe is allocated for MBSFN. The following mapping applies:\n FDD: The first/leftmost bit defines the MBSFN allocation for subframe #1, the second bit for #2, third bit for #3 , fourth bit for #6, fifth bit for #7, sixth bit for #8.\n TDD: The first/leftmost bit defines the allocation for subframe #3, the second bit for #4, third bit for #7, fourth bit for #8, fifth bit for #9. Uplink subframes are not allocated. The last bit is not used. - /// \par fourFrames_flag == 1 - /// A bit-map indicating MBSFN subframe allocation in four consecutive radio frames, "1" denotes that the corresponding subframe is allocated for MBSFN. The bitmap is interpreted as follows:\n FDD: Starting from the first radioframe and from the first/leftmost bit in the bitmap, the allocation applies to subframes #1, #2, #3 , #6, #7, and #8 in the sequence of the four radio-frames.\n TDD: Starting from the first radioframe and from the first/leftmost bit in the bitmap, the allocation applies to subframes #3, #4, #7, #8, and #9 in the sequence of the four radio-frames. The last four bits are not used. Uplink subframes are not allocated. - int mbsfn_SubframeConfig; -} MBSFN_config_t; - -typedef struct { - /// Number of resource blocks (RB) in DL - uint8_t N_RB_DL; - /// Number of resource blocks (RB) in UL - uint8_t N_RB_UL; - /// EUTRA Band - uint8_t eutra_band; - /// DL carrier frequency - uint32_t dl_CarrierFreq; - /// UL carrier frequency - uint32_t ul_CarrierFreq; - /// TX attenuation - uint32_t att_tx; - /// RX attenuation - uint32_t att_rx; - /// total Number of Resource Block Groups: this is ceil(N_PRB/P) - uint8_t N_RBG; - /// Total Number of Resource Block Groups SubSets: this is P - uint8_t N_RBGS; - /// Cell ID - uint16_t Nid_cell; - /// MBSFN Area ID - uint16_t Nid_cell_mbsfn; - /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP) - lte_prefix_type_t Ncp; - /// Cyclic Prefix for UL (0=Normal CP, 1=Extended CP) - lte_prefix_type_t Ncp_UL; - /// shift of pilot position in one RB - uint8_t nushift; - /// Frame type (0 FDD, 1 TDD) - lte_frame_type_t frame_type; - /// TDD subframe assignment (0-7) (default = 3) (254=RX only, 255=TX only) - uint8_t tdd_config; - /// TDD S-subframe configuration (0-9) - uint8_t tdd_config_S; - /// srs extra symbol flag for TDD - uint8_t srsX; - /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0). - uint8_t node_id; - /// Indicator that 20 MHz channel uses 3/4 sampling frequency - uint8_t threequarter_fs; - /// Size of FFT - uint16_t ofdm_symbol_size; - /// Number of prefix samples in all but first symbol of slot - uint16_t nb_prefix_samples; - /// Number of prefix samples in first symbol of slot - uint16_t nb_prefix_samples0; - /// Carrier offset in FFT buffer for first RE in PRB0 - uint16_t first_carrier_offset; - /// Number of samples in a subframe - uint32_t samples_per_tti; - /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) - uint16_t symbols_per_tti; - /// Number of OFDM symbols in DL portion of S-subframe - uint16_t dl_symbols_in_S_subframe; - /// Number of SC-FDMA symbols in UL portion of S-subframe - uint16_t ul_symbols_in_S_subframe; - /// Number of Physical transmit antennas in node - uint8_t nb_antennas_tx; - /// Number of Receive antennas in node - uint8_t nb_antennas_rx; - /// Number of common transmit antenna ports in eNodeB (1 or 2) - uint8_t nb_antenna_ports_eNB; - /// PRACH_CONFIG - PRACH_CONFIG_COMMON prach_config_common; -#ifdef Rel14 - /// PRACH_eMTC_CONFIG - PRACH_eMTC_CONFIG_COMMON prach_emtc_config_common; -#endif - /// PUCCH Config Common (from 36-331 RRC spec) - PUCCH_CONFIG_COMMON pucch_config_common; - /// PDSCH Config Common (from 36-331 RRC spec) - PDSCH_CONFIG_COMMON pdsch_config_common; - /// PUSCH Config Common (from 36-331 RRC spec) - PUSCH_CONFIG_COMMON pusch_config_common; - /// PHICH Config (from 36-331 RRC spec) - PHICH_CONFIG_COMMON phich_config_common; - /// SRS Config (from 36-331 RRC spec) - SOUNDINGRS_UL_CONFIG_COMMON soundingrs_ul_config_common; - /// UL Power Control (from 36-331 RRC spec) - UL_POWER_CONTROL_CONFIG_COMMON ul_power_control_config_common; - /// Number of MBSFN Configurations - int num_MBSFN_config; - /// Array of MBSFN Configurations (max 8 (maxMBSFN-Allocations) elements as per 36.331) - MBSFN_config_t MBSFN_config[8]; - /// Maximum Number of Retransmissions of RRCConnectionRequest (from 36-331 RRC Spec) - uint8_t maxHARQ_Msg3Tx; - /// Size of SI windows used for repetition of one SI message (in frames) - uint8_t SIwindowsize; - /// Period of SI windows used for repetition of one SI message (in frames) - uint16_t SIPeriod; - /// REGs assigned to PCFICH - uint16_t pcfich_reg[4]; - /// Index of first REG assigned to PCFICH - uint8_t pcfich_first_reg_idx; - /// REGs assigned to PHICH - uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; - - struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[MAX_MBSFN_AREA]; - /// for fair RR scheduler - uint32_t ue_multiple_max; -} LTE_DL_FRAME_PARMS; - -typedef enum { - /// TM1 - SISO=0, - /// TM2 - ALAMOUTI=1, - /// TM3 - LARGE_CDD=2, - /// the next 6 entries are for TM5 - UNIFORM_PRECODING11=3, - UNIFORM_PRECODING1m1=4, - UNIFORM_PRECODING1j=5, - UNIFORM_PRECODING1mj=6, - PUSCH_PRECODING0=7, - PUSCH_PRECODING1=8, - /// the next 3 entries are for TM4 - DUALSTREAM_UNIFORM_PRECODING1=9, - DUALSTREAM_UNIFORM_PRECODINGj=10, - DUALSTREAM_PUSCH_PRECODING=11, - TM7=12, - TM8=13, - TM9_10=14 -} MIMO_mode_t; - - -typedef enum { - /// MRT - MRT=0, - /// ZF - ZF=1, - /// MMSE - MMSE=2 -} PRECODE_TYPE_t; - -typedef struct { - /// \brief Pointers (dynamic) to the received data in the time domain. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ - int32_t **rxdata; - /// \brief Pointers (dynamic) to the received data in the frequency domain. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ - int32_t **rxdataF; - /// \brief holds the transmit data in the frequency domain. - /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? - /// - first index: eNB id [0..2] (hard coded) - /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. - /// - third index: sample [0..] - int32_t **txdataF; -} LTE_eNB_COMMON; - typedef struct { /// \brief Holds the transmit data in the frequency domain. /// - first index: rx antenna [0..nb_antennas_rx[ @@ -726,567 +68,4 @@ typedef struct { int32_t **tdd_calib_coeffs; } RU_COMMON; -typedef enum {format0, - format1, - format1A, - format1B, - format1C, - format1D, - format1E_2A_M10PRB, - format2, - format2A, - format2B, - format2C, - format2D, - format3, - format3A, - format4, - format5, - format6_0A, - format6_0B, - format6_1A, - format6_1B, - format6_2 - } DCI_format_t; - -typedef struct { - /// Length of DCI in bits - uint8_t dci_length; - /// Aggregation level - uint8_t L; - /// Position of first CCE of the dci - int firstCCE; - /// flag to indicate that this is a RA response - boolean_t ra_flag; - /// rnti - rnti_t rnti; - /// harq_pid - rnti_t harq_pid; - /// Format - DCI_format_t format; - /// DCI pdu - uint8_t dci_pdu[8]; -} DCI_ALLOC_t; - -#define MAX_EPDCCH_PRB 8 - -typedef struct { - /// Length of DCI in bits - uint8_t dci_length; - /// Aggregation level - uint8_t L; - /// Position of first CCE of the dci - int firstCCE; - /// flag to indicate that this is a RA response - boolean_t ra_flag; - /// rnti - rnti_t rnti; - /// Format - DCI_format_t format; - /// epdcch resource assignment (0=localized,1=distributed) - uint8_t epdcch_resource_assignment_flag; - /// epdcch index - uint16_t epdcch_id; - /// epdcch start symbol - uint8_t epdcch_start_symbol; - /// epdcch number of PRBs in set - uint8_t epdcch_num_prb; - /// vector of prb ids for set - uint8_t epdcch_prb_index[MAX_EPDCCH_PRB]; - /// LBT parameter for frame configuration - uint8_t dwpts_symbols; - /// LBT parameter for frame configuration - uint8_t initial_lbt_sf; - /// DCI pdu - uint8_t dci_pdu[8]; -} eDCI_ALLOC_t; - -typedef struct { - /// Length of DCI in bits - uint8_t dci_length; - /// Aggregation level - uint8_t L; - /// Position of first CCE of the dci - int firstCCE; - /// flag to indicate that this is a RA response - boolean_t ra_flag; - /// rnti - rnti_t rnti; - /// Format - DCI_format_t format; - /// harq process index - uint8_t harq_pid; - /// Narrowband index - uint8_t narrowband; - /// number of PRB pairs for MPDCCH - uint8_t number_of_prb_pairs; - /// mpdcch resource assignment (combinatorial index r) - uint8_t resource_block_assignment; - /// transmission type (0=localized,1=distributed) - uint8_t transmission_type; - /// mpdcch start symbol - uint8_t start_symbol; - /// CE mode (1=ModeA,2=ModeB) - uint8_t ce_mode; - /// 0-503 n_EPDCCHid_i - uint16_t dmrs_scrambling_init; - /// Absolute subframe of the initial transmission (0-10239) - uint16_t i0; - /// number of mdpcch repetitions - uint16_t reps; - /// current absolute subframe number - uint16_t absSF; - /// DCI pdu - uint8_t dci_pdu[8]; -} mDCI_ALLOC_t; - - -typedef struct { - uint8_t num_dci; - uint8_t num_pdcch_symbols; - DCI_ALLOC_t dci_alloc[32]; -} LTE_eNB_PDCCH; - -typedef struct { - uint8_t hi; - uint8_t first_rb; - uint8_t n_DMRS; -} phich_config_t; - -typedef struct { - uint8_t num_hi; - phich_config_t config[32]; -} LTE_eNB_PHICH; - -typedef struct { - uint8_t num_dci; - eDCI_ALLOC_t edci_alloc[32]; -} LTE_eNB_EPDCCH; - -typedef struct { - /// number of active MPDCCH allocations - uint8_t num_dci; - /// MPDCCH DCI allocations from MAC - mDCI_ALLOC_t mdci_alloc[32]; - // MAX SIZE of an EPDCCH set is 16EREGs * 9REs/EREG * 8 PRB pairs = 2304 bits - uint8_t e[2304]; -} LTE_eNB_MPDCCH; - - -typedef struct { - /// \brief Hold the channel estimates in frequency domain based on SRS. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..ofdm_symbol_size[ - int32_t **srs_ch_estimates; - /// \brief Hold the channel estimates in time domain based on SRS. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..2*ofdm_symbol_size[ - int32_t **srs_ch_estimates_time; - /// \brief Holds the SRS for channel estimation at the RX. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..ofdm_symbol_size[ - int32_t *srs; -} LTE_eNB_SRS; - -typedef struct { - /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..2*ofdm_symbol_size[ - int32_t **rxdataF_ext; - /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_ext2; - /// \brief Hold the channel estimates in time domain based on DRS. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..4*ofdm_symbol_size[ - int32_t **drs_ch_estimates_time; - /// \brief Hold the channel estimates in frequency domain based on DRS. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **drs_ch_estimates; - /// \brief Holds the compensated signal. - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_comp; - /// \brief Magnitude of the UL channel estimates. Used for 2nd-bit level thresholds in LLR computation - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_mag; - /// \brief Magnitude of the UL channel estimates scaled for 3rd bit level thresholds in LLR computation - /// - first index: rx antenna id [0..nb_antennas_rx[ - /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_magb; - /// measured RX power based on DRS - int ulsch_power[2]; - /// \brief llr values. - /// - first index: ? [0..1179743] (hard coded) - int16_t *llr; -} LTE_eNB_PUSCH; - -typedef struct { - - /// \brief Holds the received data in the frequency domain. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: symbol [0..28*ofdm_symbol_size[ - int32_t **rxdataF; - - /// \brief Hold the channel estimates in frequency domain. - /// - first index: eNB id [0..6] (hard coded) - /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ - int32_t **dl_ch_estimates[7]; - - /// \brief Hold the channel estimates in time domain (used for tracking). - /// - first index: eNB id [0..6] (hard coded) - /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - third index: samples? [0..2*ofdm_symbol_size[ - int32_t **dl_ch_estimates_time[7]; -}LTE_UE_COMMON_PER_THREAD; - -typedef struct { - /// \brief Holds the transmit data in time domain. - /// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER. - /// - first index: tx antenna [0..nb_antennas_tx[ - /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES[ - int32_t **txdata; - /// \brief Holds the transmit data in the frequency domain. - /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. - /// - first index: tx antenna [0..nb_antennas_tx[ - /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX[ - int32_t **txdataF; - - /// \brief Holds the received data in time domain. - /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ - int32_t **rxdata; - - LTE_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX]; - - /// holds output of the sync correlator - int32_t *sync_corr; - /// estimated frequency offset (in radians) for all subcarriers - int32_t freq_offset; - /// eNb_id user is synched to - int32_t eNb_id; -} LTE_UE_COMMON; - -typedef struct { - /// \brief Received frequency-domain signal after extraction. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **rxdataF_ext; - /// \brief Received frequency-domain ue specific pilots. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..12*N_RB_DL[ - int32_t **rxdataF_uespec_pilots; - /// \brief Received frequency-domain signal after extraction and channel compensation. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **rxdataF_comp0; - /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round - /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid - /// - second index: ? [0..7] (hard coded) accessed via \c round - /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - fourth index: ? [0..168*N_RB_DL[ - int32_t **rxdataF_comp1[8][8]; - /// \brief Downlink channel estimates extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_estimates_ext; - /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round - /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid - /// - second index: ? [0..7] (hard coded) accessed via \c round - /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - fourth index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_rho_ext[8][8]; - /// \brief Downlink beamforming channel estimates in frequency domain. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ - int32_t **dl_bf_ch_estimates; - /// \brief Downlink beamforming channel estimates. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_bf_ch_estimates_ext; - /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_rho2_ext; - /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. - /// - first index: ressource block [0..N_RB_DL[ - uint8_t *pmi_ext; - /// \brief Magnitude of Downlink Channel first layer (16QAM level/First 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_mag0; - /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_mag1[8][8]; - /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_magb0; - /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_magb1[8][8]; - /// \brief Cross-correlation of two eNB signals. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: symbol [0..] - int32_t **rho; - /// never used... always send dl_ch_rho_ext instead... - int32_t **rho_i; - /// \brief Pointers to llr vectors (2 TBs). - /// - first index: ? [0..1] (hard coded) - /// - second index: ? [0..1179743] (hard coded) - int16_t *llr[2]; - /// \f$\log_2(\max|H_i|^2)\f$ - int16_t log2_maxh; - /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation - int16_t log2_maxh0; - /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation - int16_t log2_maxh1; - /// \brief LLR shifts for subband scaling. - /// - first index: ? [0..168*N_RB_DL[ - uint8_t *llr_shifts; - /// \brief Pointer to LLR shifts. - /// - first index: ? [0..168*N_RB_DL[ - uint8_t *llr_shifts_p; - /// \brief Pointers to llr vectors (128-bit alignment). - /// - first index: ? [0..0] (hard coded) - /// - second index: ? [0..] - int16_t **llr128; - /// \brief Pointers to llr vectors (128-bit alignment). - /// - first index: ? [0..0] (hard coded) - /// - second index: ? [0..] - int16_t **llr128_2ndstream; - //uint32_t *rb_alloc; - //uint8_t Qm[2]; - //MIMO_mode_t mimo_mode; - // llr offset per ofdm symbol - uint32_t llr_offset[14]; - // llr length per ofdm symbol - uint32_t llr_length[14]; -} LTE_UE_PDSCH; - -typedef struct { - /// \brief Received frequency-domain signal after extraction. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - int32_t **rxdataF_ext; - /// \brief Received frequency-domain signal after extraction and channel compensation. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **rxdataF_comp; - /// \brief Downlink channel estimates extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - int32_t **dl_ch_estimates_ext; - /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_rho_ext; - /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. - /// - first index: ressource block [0..N_RB_DL[ - uint8_t *pmi_ext; - /// \brief Magnitude of Downlink Channel (16QAM level/First 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_mag; - /// \brief Magnitude of Downlink Channel (2nd 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_magb; - /// \brief Cross-correlation of two eNB signals. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..] - double **rho; - /// never used... always send dl_ch_rho_ext instead... - double **rho_i; - /// \brief Pointers to llr vectors (2 TBs). - /// - first index: ? [0..1] (hard coded) - /// - second index: ? [0..1179743] (hard coded) - int16_t *llr[2]; - /// \f$\log_2(\max|H_i|^2)\f$ - uint8_t log2_maxh; - /// \brief Pointers to llr vectors (128-bit alignment). - /// - first index: ? [0..0] (hard coded) - /// - second index: ? [0..] - int16_t **llr128; - //uint32_t *rb_alloc; - //uint8_t Qm[2]; - //MIMO_mode_t mimo_mode; -} LTE_UE_PDSCH_FLP; - -typedef struct { - /// \brief Pointers to extracted PDCCH symbols in frequency-domain. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **rxdataF_ext; - /// \brief Pointers to extracted and compensated PDCCH symbols in frequency-domain. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **rxdataF_comp; - /// \brief Pointers to extracted channel estimates of PDCCH symbols. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_estimates_ext; - /// \brief Pointers to channel cross-correlation vectors for multi-eNB detection. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_rho_ext; - /// \brief Pointers to channel cross-correlation vectors for multi-eNB detection. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..] - int32_t **rho; - /// \brief Pointer to llrs, 4-bit resolution. - /// - first index: ? [0..48*N_RB_DL[ - uint16_t *llr; - /// \brief Pointer to llrs, 16-bit resolution. - /// - first index: ? [0..96*N_RB_DL[ - uint16_t *llr16; - /// \brief \f$\overline{w}\f$ from 36-211. - /// - first index: ? [0..48*N_RB_DL[ - uint16_t *wbar; - /// \brief PDCCH/DCI e-sequence (input to rate matching). - /// - first index: ? [0..96*N_RB_DL[ - int8_t *e_rx; - /// number of PDCCH symbols in current subframe - uint8_t num_pdcch_symbols; - /// Allocated CRNTI for UE - uint16_t crnti; - /// 1: the allocated crnti is Temporary C-RNTI / 0: otherwise - uint8_t crnti_is_temporary; - /// Total number of PDU errors (diagnostic mode) - uint32_t dci_errors; - /// Total number of PDU received - uint32_t dci_received; - /// Total number of DCI False detection (diagnostic mode) - uint32_t dci_false; - /// Total number of DCI missed (diagnostic mode) - uint32_t dci_missed; - /// nCCE for PUCCH per subframe - uint8_t nCCE[10]; - //Check for specific DCIFormat and AgregationLevel - uint8_t dciFormat; - uint8_t agregationLevel; -} LTE_UE_PDCCH; - -#define PBCH_A 24 -typedef struct { - uint8_t pbch_d[96+(3*(16+PBCH_A))]; - uint8_t pbch_w[3*3*(16+PBCH_A)]; - uint8_t pbch_e[1920]; -} LTE_eNB_PBCH; - -typedef struct { - /// \brief Pointers to extracted PBCH symbols in frequency-domain. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..287] (hard coded) - int32_t **rxdataF_ext; - /// \brief Pointers to extracted and compensated PBCH symbols in frequency-domain. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..287] (hard coded) - int32_t **rxdataF_comp; - /// \brief Pointers to downlink channel estimates in frequency-domain extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..287] (hard coded) - int32_t **dl_ch_estimates_ext; - /// \brief Pointer to PBCH llrs. - /// - first index: ? [0..1919] (hard coded) - int8_t *llr; - /// \brief Pointer to PBCH decoded output. - /// - first index: ? [0..63] (hard coded) - uint8_t *decoded_output; - /// \brief Total number of PDU errors. - uint32_t pdu_errors; - /// \brief Total number of PDU errors 128 frames ago. - uint32_t pdu_errors_last; - /// \brief Total number of consecutive PDU errors. - uint32_t pdu_errors_conseq; - /// \brief FER (in percent) . - uint32_t pdu_fer; -} LTE_UE_PBCH; - -typedef struct { - int16_t amp; - int16_t *prachF; - int16_t *prach; -} LTE_UE_PRACH; - -#define MAX_NUM_RX_PRACH_PREAMBLES 4 - -typedef struct { - /// \brief ?. - /// first index: ? [0..1023] (hard coded) - int16_t *prachF; - /// \brief ?. - /// first index: ce_level [0..3] - /// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. - /// third index: frequency-domain sample [0..ofdm_symbol_size*12[ - int16_t **rxsigF[4]; - /// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs) - /// first index: ce_level [0..3] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. - /// second index: ? [0..63] (hard coded) - /// third index: ? [0..63] (hard coded) - int32_t **prach_ifft[4]; - - /// repetition number -#ifdef Rel14 - /// indicator of first frame in a group of PRACH repetitions - int first_frame[4]; - /// current repetition for each CE level - int repetition_number[4]; -#endif -} LTE_eNB_PRACH; - -typedef struct { - /// Preamble index for PRACH (0-63) - uint8_t ra_PreambleIndex; - /// RACH MaskIndex - uint8_t ra_RACH_MaskIndex; - /// Target received power at eNB (-120 ... -82 dBm) - int8_t ra_PREAMBLE_RECEIVED_TARGET_POWER; - /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex - uint8_t ra_TDD_map_index; - /// Corresponding RA-RNTI for UL-grant - uint16_t ra_RNTI; - /// Pointer to Msg3 payload for UL-grant - uint8_t *Msg3; -} PRACH_RESOURCES_t; - - -typedef struct { - /// Downlink Power offset field - uint8_t dl_pow_off; - ///Subband resource allocation field - uint8_t rballoc_sub[50]; - ///Total number of PRBs indicator - uint8_t pre_nb_available_rbs; -} MU_MIMO_mode; - -typedef enum { - NOT_SYNCHED=0, - PRACH=1, - RA_RESPONSE=2, - PUSCH=3, - RESYNCH=4 -} UE_MODE_t; - - - -typedef enum {SF_DL, SF_UL, SF_S} lte_subframe_t; - -typedef enum { - /// do not detect any DCIs in the current subframe - NO_DCI = 0x0, - /// detect only downlink DCIs in the current subframe - UL_DCI = 0x1, - /// detect only uplink DCIs in the current subframe - DL_DCI = 0x2, - /// detect both uplink and downlink DCIs in the current subframe - UL_DL_DCI = 0x3} dci_detect_mode_t; - #endif diff --git a/openair1/PHY/impl_defs_lte_NB_IoT.h b/openair1/PHY/impl_defs_lte_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..1167323174e1a3048df10768afd2ca481841c97a --- /dev/null +++ b/openair1/PHY/impl_defs_lte_NB_IoT.h @@ -0,0 +1,813 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/impl_defs_lte.h +* \brief LTE Physical channel configuration and variable structure definitions +* \author R. Knopp, F. Kaltenberger +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +#ifndef __PHY_IMPL_DEFS_NB_IOT__H__ +#define __PHY_IMPL_DEFS_NB_IOT__H__ + +#include "types_NB_IoT.h" +//#include "defs.h" + +typedef enum {TDD_NB_IoT=1,FDD_NB_IoT=0} NB_IoT_frame_type_t; +typedef enum {EXTENDED_NB_IoT=1,NORMAL_NB_IoT=0} NB_IoT_prefix_type_t; +typedef enum {SF_DL_NB_IoT, SF_UL_NB_IoT, SF_S_NB_IoT} NB_IoT_subframe_t; + +#define A_SEQUENCE_OF(type) A_SET_OF(type) + +#define A_SET_OF(type) \ + struct { \ + type **array; \ + int count; /* Meaningful size */ \ + int size; /* Allocated size */ \ + void (*free)(type *); \ + } + + +///////////////////////// + /// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. +typedef union { + /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} + uint8_t indexOfFormat3; + /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} + uint8_t indexOfFormat3A; +} TPC_INDEX_NB_IoT_t; + +/// TPC-PDCCH-Config Information Element from 36.331 RRC spec +typedef struct { + /// RNTI for power control using DCI format 3/3A, see TS 36.212. \vr{[0..65535]} + uint16_t rnti; + /// Index of N or M, see TS 36.212 (5.3.3.1.6 and 5.3.3.1.7), where N or M is dependent on the used DCI format (i.e. format 3 or 3a). + TPC_INDEX_NB_IoT_t tpc_Index; +} TPC_PDCCH_CONFIG_NB_IoT; + /// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor. +typedef enum { + //n2=0, + n4_n, + n6_n +} ACKNAKREP_NB_IoT_t; + +/// Enumeration for \ref PUCCH_CONFIG_DEDICATED::tdd_AckNackFeedbackMode. +typedef enum { + bundling_N=0, + multiplexing_N +} ANFBmode_NB_IoT_t; + +/// PUCCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Flag to indicate ACK NAK repetition activation, see TS 36.213 (10.1). \vr{[0..1]} + uint8_t ackNackRepetition; + /// Parameter: \f$N_\text{ANRep}\f$, see TS 36.213 (10.1). + ACKNAKREP_NB_IoT_t repetitionFactor; + /// Parameter: \f$n^{(1)}_\text{PUCCH,ANRep}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t n1PUCCH_AN_Rep; + /// Feedback mode, see TS 36.213 (7.3). \details Applied to both PUCCH and PUSCH feedback. For TDD, should always be set to bundling. + ANFBmode_NB_IoT_t tdd_AckNackFeedbackMode; +} PUCCH_CONFIG_DEDICATED_NB_IoT; + // UE specific PUSCH configuration. +typedef struct { + /// Parameter: \f$I^\text{HARQ-ACK}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-1). \vr{[0..15]} + uint16_t betaOffset_ACK_Index; + /// Parameter: \f$I^{RI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-2). \vr{[0..15]} + uint16_t betaOffset_RI_Index; + /// Parameter: \f$I^{CQI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-3). \vr{[0..15]} + uint16_t betaOffset_CQI_Index; +} PUSCH_CONFIG_DEDICATED_NB_IoT; +/// Enumeration for Parameter \f$P_A\f$ \ref PDSCH_CONFIG_DEDICATED::p_a. +typedef enum { + //dBm6=0, ///< (dB-6) corresponds to -6 dB + // dBm477, ///< (dB-4dot77) corresponds to -4.77 dB + // dBm3, ///< (dB-3) corresponds to -3 dB + //dBm177, ///< (dB-1dot77) corresponds to -1.77 dB + //dB0, ///< corresponds to 0 dB + // dB1, ///< corresponds to 1 dB + dB2_NB, ///< corresponds to 2 dB + dB3_NB ///< corresponds to 3 dB +} PA_NB_IoT_t; + +/// PDSCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_A\f$, see TS 36.213 (5.2). + PA_NB_IoT_t p_a; +} PDSCH_CONFIG_DEDICATED_NB_IoT; + +/// UplinkPowerControlDedicated Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_\text{0\_UE\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dB. \vr{[-8..7]}\n This field is applicable for non-persistent scheduling, only. + int8_t p0_UE_PUSCH; + /// Parameter: Ks, see TS 36.213 (5.1.1.1). \vr{[0..1]}\n en0 corresponds to value 0 corresponding to state “disabledâ€. en1 corresponds to value 1.25 corresponding to “enabledâ€. \note the specification sais it is an enumerated value. \warning the enumeration values do not correspond to the given values in the specification (en1 should be 1.25). + uint8_t deltaMCS_Enabled; + /// Parameter: Accumulation-enabled, see TS 36.213 (5.1.1.1). \vr{[0..1]} 1 corresponds to "enabled" whereas 0 corresponds to "disabled". + uint8_t accumulationEnabled; + /// Parameter: \f$P_\text{0\_UE\_PUCCH}(1)\f$, see TS 36.213 (5.1.2.1), unit dB. \vr{[-8..7]} + int8_t p0_UE_PUCCH; + /// Parameter: \f$P_\text{SRS\_OFFSET}\f$, see TS 36.213 (5.1.3.1). \vr{[0..15]}\n For Ks=1.25 (\ref deltaMCS_Enabled), the actual parameter value is pSRS_Offset value - 3. For Ks=0, the actual parameter value is -10.5 + 1.5*pSRS_Offset value. + int8_t pSRS_Offset; + /// Specifies the filtering coefficient for RSRP measurements used to calculate path loss, as specified in TS 36.213 (5.1.1.1).\details The same filtering mechanism applies as for quantityConfig described in 5.5.3.2. \note the specification sais it is an enumerated value. + uint8_t filterCoefficient; +} UL_POWER_CONTROL_DEDICATED_NB_IoT; + +/// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. +//typedef union { + /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} + // uint8_t indexOfFormat3; + /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} + // uint8_t indexOfFormat3A; +//} TPC_INDEX_NB_IoT_t; + +/// CQI-ReportPeriodic +typedef struct { + /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}, -1 indicates inactivity + int16_t cqi_PUCCH_ResourceIndex; + /// Parameter: CQI/PMI Periodicity and Offset Configuration Index \f$I_\text{CQI/PMI}\f$, see TS 36.213 (tables 7.2.2-1A and 7.2.2-1C). \vr{[0..1023]} + int16_t cqi_PMI_ConfigIndex; + /// Parameter: K, see 36.213 (4.2.2). \vr{[1..4]} + uint8_t K; + /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}, -1 indicates inactivity + int16_t ri_ConfigIndex; + /// Parameter: Simultaneous-AN-and-CQI, see TS 36.213 (10.1). \vr{[0..1]} 1 indicates that simultaneous transmission of ACK/NACK and CQI is allowed. + uint8_t simultaneousAckNackAndCQI; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t Npd; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t N_OFFSET_CQI; +} CQI_REPORTPERIODIC_NB_IoT; + +/// Enumeration for parameter reporting mode \ref CQI_REPORT_CONFIG::cqi_ReportModeAperiodic. +typedef enum { + //rm12=0, + //rm20=1, + //rm22=2, + rm30_N=3, + rm31_N=4 +} CQI_REPORTMODEAPERIODIC_NB_IoT; + +/// CQI-ReportConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: reporting mode. Value rm12 corresponds to Mode 1-2, rm20 corresponds to Mode 2-0, rm22 corresponds to Mode 2-2 etc. PUSCH reporting modes are described in TS 36.213 [23, 7.2.1]. + CQI_REPORTMODEAPERIODIC_NB_IoT cqi_ReportModeAperiodic; + /// Parameter: \f$\Delta_\text{offset}\f$, see TS 36.213 (7.2.3). \vr{[-1..6]}\n Actual value = IE value * 2 [dB]. + int8_t nomPDSCH_RS_EPRE_Offset; + CQI_REPORTPERIODIC_NB_IoT CQI_ReportPeriodic; +} CQI_REPORT_CONFIG_NB_IoT; + +/// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_Bandwidth; + /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_HoppingBandwidth; + /// Parameter: \f$n_\text{RRC}\f$, see TS 36.211 (5.5.3.2). \vr{[0..23]} + uint8_t freqDomainPosition; + /// Parameter: Duration, see TS 36.213 (8.2). \vr{[0..1]} 0 corresponds to "single" and 1 to "indefinite". + uint8_t duration; + /// Parameter: \f$k_\text{TC}\in\{0,1\}\f$, see TS 36.211 (5.5.3.2). \vr{[0..1]} + uint8_t transmissionComb; + /// Parameter: \f$I_\text{SRS}\f$, see TS 36.213 (table 8.2-1). \vr{[0..1023]} + uint16_t srs_ConfigIndex; + /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value. + uint8_t cyclicShift; + // Parameter: internal implementation: UE SRS configured + uint8_t srsConfigDedicatedSetup; + // Parameter: cell srs subframe for internal implementation + uint8_t srsCellSubframe; + // Parameter: ue srs subframe for internal implementation + uint8_t srsUeSubframe; +} SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT; + + +/// Enumeration for parameter SR transmission \ref SCHEDULING_REQUEST_CONFIG::dsr_TransMax. +typedef enum { + //sr_n4=0, + // sr_n8=1, + // sr_n16=2, + sr_n32_N=3, + sr_n64_N=4 +} DSR_TRANSMAX_NB_IoT_t; + +/// SchedulingRequestConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$n^{(1)}_\text{PUCCH,SRI}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t sr_PUCCH_ResourceIndex; + /// Parameter: \f$I_\text{SR}\f$, see TS 36.213 (10.1). \vr{[0..155]} + uint8_t sr_ConfigIndex; + /// Parameter for SR transmission in TS 36.321 (5.4.4). \details The value n4 corresponds to 4 transmissions, n8 corresponds to 8 transmissions and so on. + DSR_TRANSMAX_NB_IoT_t dsr_TransMax; +} SCHEDULING_REQUEST_CONFIG_NB_IoT; + +typedef struct { + /// Downlink Power offset field + uint8_t dl_pow_off; + ///Subband resource allocation field + uint8_t rballoc_sub[50]; + ///Total number of PRBs indicator + uint8_t pre_nb_available_rbs; +} MU_MIMO_mode_NB_IoT; +//////////////////////// + +typedef struct { + + /// \brief Holds the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..28*ofdm_symbol_size[ + int32_t **rxdataF; + + /// \brief Hold the channel estimates in frequency domain. + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_ch_estimates[7]; + + /// \brief Hold the channel estimates in time domain (used for tracking). + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..2*ofdm_symbol_size[ + int32_t **dl_ch_estimates_time[7]; +}NB_IoT_UE_COMMON_PER_THREAD; + +typedef struct { + /// \brief Holds the transmit data in time domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES[ + int32_t **txdata; + /// \brief Holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX[ + int32_t **txdataF; + + /// \brief Holds the received data in time domain. + /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ + int32_t **rxdata; + + NB_IoT_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[2]; + + /// holds output of the sync correlator + int32_t *sync_corr; + /// estimated frequency offset (in radians) for all subcarriers + int32_t freq_offset; + /// eNb_id user is synched to + int32_t eNb_id; +} NB_IoT_UE_COMMON; + +typedef struct { + /// \brief Received frequency-domain signal after extraction. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_ext; + /// \brief Received frequency-domain ue specific pilots. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..12*N_RB_DL[ + int32_t **rxdataF_uespec_pilots; + /// \brief Received frequency-domain signal after extraction and channel compensation. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp0; + /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp1[8][8]; + /// \brief Downlink channel estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho_ext[8][8]; + /// \brief Downlink beamforming channel estimates in frequency domain. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_bf_ch_estimates; + /// \brief Downlink beamforming channel estimates. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_bf_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho2_ext; + /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. + /// - first index: ressource block [0..N_RB_DL[ + uint8_t *pmi_ext; + /// \brief Magnitude of Downlink Channel first layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag0; + /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag1[8][8]; + /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb0; + /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb1[8][8]; + /// \brief Cross-correlation of two eNB signals. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..] + int32_t **rho; + /// never used... always send dl_ch_rho_ext instead... + int32_t **rho_i; + /// \brief Pointers to llr vectors (2 TBs). + /// - first index: ? [0..1] (hard coded) + /// - second index: ? [0..1179743] (hard coded) + int16_t *llr[2]; + /// \f$\log_2(\max|H_i|^2)\f$ + int16_t log2_maxh; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation + int16_t log2_maxh0; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation + int16_t log2_maxh1; + /// \brief LLR shifts for subband scaling. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts; + /// \brief Pointer to LLR shifts. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts_p; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128_2ndstream; + //uint32_t *rb_alloc; + //uint8_t Qm[2]; + //MIMO_mode_t mimo_mode; +} NB_IoT_UE_PDSCH; + +/// NPRACH-ParametersList-NB-r13 from 36.331 RRC spec +typedef struct NPRACH_Parameters_NB_IoT{ + /// the period time for nprach + uint16_t nprach_Periodicity; + /// for the start time for the NPRACH resource from 40ms-2560ms + uint16_t nprach_StartTime; + /// for the subcarrier of set to the NPRACH preamble from n0 - n34 + uint16_t nprach_SubcarrierOffset; + ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) + uint16_t nprach_NumSubcarriers; + /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 + uint16_t nprach_SubcarrierMSG3_RangeStart; + /// The max preamble transmission attempt for the CE level from 1 - 128 + uint16_t maxNumPreambleAttemptCE; + /// Number of NPRACH repetitions per attempt for each NPRACH resource + uint16_t numRepetitionsPerPreambleAttempt; + /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) + uint16_t npdcch_NumRepetitions_RA; + /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) + uint16_t npdcch_StartSF_CSS_RA; + /// Fractional period offset of starting subframe for NPDCCH common search space + uint16_t npdcch_Offset_RA; +} nprach_parameters_NB_IoT_t; + +typedef struct{ + nprach_parameters_NB_IoT_t list[3]; +}NPRACH_List_NB_IoT_t; + +typedef long RSRP_Range_t; + +typedef struct { + A_SEQUENCE_OF(RSRP_Range_t) list; +}rsrp_ThresholdsNPrachInfoList; + + +/// NPRACH_ConfigSIB-NB from 36.331 RRC spec +typedef struct { + /// nprach_CP_Length_r13, for the CP length(unit us) only 66.7 and 266.7 is implemented + uint16_t nprach_CP_Length; + /// The criterion for UEs to select a NPRACH resource. Up to 2 RSRP threshold values can be signalled. \vr{[1..2]} + struct rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList; + /// NPRACH Parameters List + NPRACH_List_NB_IoT_t nprach_ParametersList; + +} NPRACH_CONFIG_COMMON; + +/// NPDSCH-ConfigCommon from 36.331 RRC spec +typedef struct { + ///see TS 36.213 (16.2). \vr{[-60..50]}\n Provides the downlink reference-signal EPRE. The actual value in dBm. + uint16_t nrs_Power; +} NPDSCH_CONFIG_COMMON; + +typedef struct{ + /// The base sequence of DMRS sequence in a cell for 3 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 12. Value 12 is not used. + uint16_t threeTone_BaseSequence; + /// Define 3 cyclic shifts for the 3-tone case, see TS 36.211 [21, 10.1.4.1.2]. + uint16_t threeTone_CyclicShift; + /// The base sequence of DMRS sequence in a cell for 6 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 14. Value 14 is not used. + uint16_t sixTone_BaseSequence; + /// Define 4 cyclic shifts for the 6-tone case, see TS 36.211 [21, 10.1.4.1.2]. + uint16_t sixTone_CyclicShift; + /// The base sequence of DMRS sequence in a cell for 12 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 30. Value 30 is not used. + uint16_t twelveTone_BaseSequence; + +}DMRS_CONFIG_t; + +/// UL-ReferenceSignalsNPUSCH from 36.331 RRC spec +typedef struct { + /// Parameter: Group-hopping-enabled, see TS 36.211 (5.5.1.3). \vr{[0..1]} + uint8_t groupHoppingEnabled; + /// , see TS 36.211 (5.5.1.3). \vr{[0..29]} + uint8_t groupAssignmentNPUSCH; + /// Parameter: cyclicShift, see TS 36.211 (Table 5.5.2.1.1-2). \vr{[0..7]} + uint8_t cyclicShift; + /// nPRS for cyclic shift of DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t nPRS[20]; + /// group hopping sequence for DMRS, 36.211, Section 10.1.4.1.3. Second index corresponds to the four possible subcarrier configurations + uint8_t grouphop[20][4]; + /// sequence hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t seqhop[20]; +} UL_REFERENCE_SIGNALS_NPUSCH_t; + + +/// PUSCH-ConfigCommon from 36.331 RRC spec. +typedef struct { + /// Number of repetitions for ACK/NACK HARQ response to NPDSCH containing Msg4 per NPRACH resource, see TS 36.213 [23, 16.4.2]. + uint8_t ack_NACK_NumRepetitions_Msg4[3]; + /// SRS SubframeConfiguration. See TS 36.211 [21, table 5.5.3.3-1]. Value sc0 corresponds to value 0, sc1 to value 1 and so on. + uint8_t srs_SubframeConfig; + /// Parameter: \f$N^{HO}_{RB}\f$, see TS 36.211 (5.3.4). \vr{[0..98]} + DMRS_CONFIG_t dmrs_Config; + /// Ref signals configuration + UL_REFERENCE_SIGNALS_NPUSCH_t ul_ReferenceSignalsNPUSCH; + +} NPUSCH_CONFIG_COMMON; + + +typedef struct{ + /// See TS 36.213 [23, 16.2.1.1], unit dBm. + uint8_t p0_NominalNPUSCH; + /// See TS 36.213 [23, 16.2.1.1] where al0 corresponds to 0, al04 corresponds to value 0.4, al05 to 0.5, al06 to 0.6, al07 to 0.7, al08 to 0.8, al09 to 0.9 and al1 corresponds to 1. + uint8_t alpha; + /// See TS 36.213 [23, 16.2.1.1]. Actual value = IE value * 2 [dB]. + uint8_t deltaPreambleMsg3; +}UplinkPowerControlCommon_NB_IoT; + + +/* DL-GapConfig-NB-r13 */ +typedef struct { + uint16_t dl_GapThreshold; + uint16_t dl_GapPeriodicity; + uint16_t dl_GapDurationCoeff; +} DL_GapConfig_NB_IoT; + +#define NBIOT_INBAND_LTEPCI 0 +#define NBIOT_INBAND_IOTPCI 1 +#define NBIOT_INGUARD 2 +#define NBIOT_STANDALONE 3 + + +typedef struct { + /// for inband, lte bandwidth + uint8_t LTE_N_RB_DL; + uint8_t LTE_N_RB_UL; + /// Cell ID + uint16_t Nid_cell; + /// shift of pilot position in one RB + uint8_t nushift; + /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0). + uint8_t node_id; + /// Frequency index of CBMIMO1 card + uint8_t freq_idx; + /// RX Frequency for ExpressMIMO/LIME + uint32_t carrier_freq[4]; + /// TX Frequency for ExpressMIMO/LIME + uint32_t carrier_freqtx[4]; + /// RX gain for ExpressMIMO/LIME + uint32_t rxgain[4]; + /// TX gain for ExpressMIMO/LIME + uint32_t txgain[4]; + /// RF mode for ExpressMIMO/LIME + uint32_t rfmode[4]; + /// RF RX DC Calibration for ExpressMIMO/LIME + uint32_t rxdc[4]; + /// RF TX DC Calibration for ExpressMIMO/LIME + uint32_t rflocal[4]; + /// RF VCO calibration for ExpressMIMO/LIME + uint32_t rfvcolocal[4]; + /// Turns on second TX of CBMIMO1 card + uint8_t dual_tx; + /// flag to indicate SISO transmission + uint8_t mode1_flag; + /// Indicator that 20 MHz channel uses 3/4 sampling frequency + //uint8_t threequarter_fs; + /// Size of FFT + uint16_t ofdm_symbol_size; + /// Number of prefix samples in all but first symbol of slot + uint16_t nb_prefix_samples; + /// Number of prefix samples in first symbol of slot + uint16_t nb_prefix_samples0; + /// Carrier offset in FFT buffer for first RE in PRB0 + uint16_t first_carrier_offset; + /// Number of samples in a subframe + uint32_t samples_per_tti; + /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) + uint16_t symbols_per_tti; + /// Number of Physical transmit antennas in node + uint8_t nb_antennas_tx; + /// Number of Receive antennas in node + uint8_t nb_antennas_rx; + /// Number of common transmit antenna ports in eNodeB (1 or 2) + uint8_t nb_antenna_ports_eNB; + /// Number of common receiving antenna ports in eNodeB (1 or 2) + uint8_t nb_antenna_ports_rx_eNB; + /// NPRACH Config Common (from 36-331 RRC spec) + NPRACH_CONFIG_COMMON nprach_config_common; + /// NPDSCH Config Common (from 36-331 RRC spec) + NPDSCH_CONFIG_COMMON npdsch_config_common; + /// PUSCH Config Common (from 36-331 RRC spec) + NPUSCH_CONFIG_COMMON npusch_config_common; + /// UL Power Control (from 36-331 RRC spec) + UplinkPowerControlCommon_NB_IoT ul_power_control_config_common; + /// DL Gap + DL_GapConfig_NB_IoT DL_gap_config; + /// Size of SI windows used for repetition of one SI message (in frames) + uint8_t SIwindowsize; + /// Period of SI windows used for repetition of one SI message (in frames) + uint16_t SIPeriod; + int eutra_band; + uint32_t dl_CarrierFreq; + uint32_t ul_CarrierFreq; + // CE level to determine the NPRACH Configuration (one CE for each NPRACH config.) + uint8_t CE; + + /* + * index of the PRB assigned to NB-IoT carrier in in-band/guard-band operating mode + */ + unsigned short NB_IoT_RB_ID; + + + /*Following FAPI approach: + * 0 = in-band with same PCI + * 1 = in-band with diff PCI + * 2 = guard band + * 3 =stand alone + */ + uint16_t operating_mode; + /* + * Only for In-band operating mode with same PCI + * its measured in number of OFDM symbols + * allowed values: + * 1, 2, 3, 4(this value is written in FAPI specs but not exist in TS 36.331 v14.2.1 pag 587) + * -1 (we put this value when is not defined - other operating mode) + */ + uint16_t control_region_size; + + /*Number of EUTRA CRS antenna ports (AP) + * valid only for in-band different PCI mode + * value 0 = indicates the same number of AP as NRS APs + * value 1 = four CRS APs + */ + uint16_t eutra_NumCRS_ports; + + /* Subcarrier bandwidth + 0 -> 3.75 kHz + 1 -> 15 kHz + */ + uint8_t subcarrier_spacing; + +} NB_IoT_DL_FRAME_PARMS; + +typedef struct { + /// \brief Pointers (dynamic) to the received data in the time domain. + /// - first index: rx antenna [0..nb_antennas_rx] + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti] + int32_t **rxdata; + /// \brief Pointers (dynamic) to the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti] + int32_t **rxdataF; + /// \brief holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? + /// - first index: eNB id [0..2] (hard coded) + /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. + /// - third index: sample [0..] + int32_t **txdataF; +} NB_IoT_eNB_COMMON; + +typedef struct { + /// \brief Holds the transmit data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **txdata; + /// \brief Holds the receive data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdata[3]; + /// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..samples_per_tti[ + int32_t **rxdata_7_5kHz[3]; + /// \brief Holds the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdataF[3]; + /// \brief Holds output of the sync correlator. + /// - first index: sample [0..samples_per_tti*10[ + uint32_t *sync_corr[3]; +} NB_IoT_RU_COMMON; + +typedef struct { + /// \brief Hold the channel estimates in frequency domain based on SRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..ofdm_symbol_size[ + int32_t **srs_ch_estimates[3]; + /// \brief Hold the channel estimates in time domain based on SRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..2*ofdm_symbol_size[ + int32_t **srs_ch_estimates_time[3]; + /// \brief Holds the SRS for channel estimation at the RX. + /// - first index: ? [0..ofdm_symbol_size[ + int32_t *srs; +} NB_IoT_eNB_SRS; + +typedef struct { + /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..2*ofdm_symbol_size[ + /// - third index (definition from phy_init_lte_eNB()): ? [0..24*N_RB_UL*frame_parms->symbols_per_tti[ + /// \warning inconsistent third index definition + int32_t **rxdataF_ext[3]; + /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_ext2[3]; + /// \brief Hold the channel estimates in time domain based on DRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..4*ofdm_symbol_size[ + int32_t **drs_ch_estimates_time[3]; + /// \brief Hold the channel estimates in frequency domain based on DRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates[3]; + /// \brief Hold the channel estimates for UE0 in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates_0[3]; + /// \brief Hold the channel estimates for UE1 in case of Distributed Almouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates_1[3]; + /// \brief Holds the compensated signal. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp[3]; + /// \brief Hold the compensated data (y)*(h0*) in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp_0[3]; + /// \brief Hold the compensated data (y*)*(h1) in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp_1[3]; + /// \brief ?. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag[3]; + /// \brief ?. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb[3]; + /// \brief Hold the channel mag for UE0 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag_0[3]; + /// \brief Hold the channel magb for UE0 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb_0[3]; + /// \brief Hold the channel mag for UE1 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag_1[3]; + /// \brief Hold the channel magb for UE1 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb_1[3]; + /// measured RX power based on DRS + int ulsch_power[2]; + /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme + int ulsch_power_0[2]; + /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme + int ulsch_power_1[2]; + /// \brief llr values. + /// - first index: ? [0..1179743] (hard coded) + int16_t *llr; +#ifdef LOCALIZATION + /// number of active subcarrier for a specific UE + int32_t active_subcarrier; + /// subcarrier power in dBm + int32_t *subcarrier_power; +#endif +} NB_IoT_eNB_PUSCH; + +#define PBCH_A_NB_IoT 24 +typedef struct { + uint8_t pbch_d[96+(3*(16+PBCH_A_NB_IoT))]; + uint8_t pbch_w[3*3*(16+PBCH_A_NB_IoT)]; + uint8_t pbch_e[1920]; +} NB_IoT_eNB_PBCH; + + +typedef enum { + /// TM1 + SISO_NB_IoT=0, + /// TM2 + ALAMOUTI_NB_IoT=1, + /// TM3 + LARGE_CDD_NB_IoT=2, + /// the next 6 entries are for TM5 + UNIFORM_PRECODING11_NB_IoT=3, + UNIFORM_PRECODING1m1_NB_IoT=4, + UNIFORM_PRECODING1j_NB_IoT=5, + UNIFORM_PRECODING1mj_NB_IoT=6, + PUSCH_PRECODING0_NB_IoT=7, + PUSCH_PRECODING1_NB_IoT=8, + /// the next 3 entries are for TM4 + DUALSTREAM_UNIFORM_PRECODING1_NB_IoT=9, + DUALSTREAM_UNIFORM_PRECODINGj_NB_IoT=10, + DUALSTREAM_PUSCH_PRECODING_NB_IoT=11, + TM7_NB_IoT=12, + TM8_NB_IoT=13, + TM9_10_NB_IoT=14 +} MIMO_mode_NB_IoT_t; + +typedef struct { + /// \brief ?. + /// first index: ? [0..1023] (hard coded) + int16_t *prachF; + /// \brief ?. + /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// second index: ? [0..ofdm_symbol_size*12[ + int16_t *rxsigF[64]; + /// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs) + /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// second index: ? [0..2047] (hard coded) + int16_t *prach_ifft[64]; +} NB_IoT_eNB_PRACH; + +typedef enum { + NOT_SYNCHED_NB_IoT=0, + PRACH_NB_IoT=1, + RA_RESPONSE_NB_IoT=2, + PUSCH_NB_IoT=3, + RESYNCH_NB_IoT=4 +} UE_MODE_NB_IoT_t; + + +#endif diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 60d3fec5f4da660076ae16cc68fdf8e2c145aff3..8b31b601621d59e7121ad6f9805b1efe402255c7 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -107,7 +107,7 @@ * @} */ -#include "defs.h" +#include "defs_eNB.h" #include "types.h" @@ -203,6 +203,9 @@ // QAM amplitude definitions +/// Amplitude for QPSK (\f$ 2^15 \times 1/\sqrt{2}\f$) +#define QPSK 23170 + /// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$) #define QAM16_n1 20724 /// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$) @@ -269,13 +272,48 @@ typedef struct { /// Measurement Variables -#define NUMBER_OF_SUBBANDS_MAX 13 +//#define NUMBER_OF_SUBBANDS_MAX 13 #define NUMBER_OF_HARQ_PID_MAX 8 #define MAX_FRAME_NUMBER 0x400 #include "openairinterface5g_limits.h" - - +#include "assertions.h" + +#define cmax(a,b) ((a>b) ? (a) : (b)) +#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) +#define cmin(a,b) ((a<b) ? (a) : (b)) +#define max(a,b) cmax(a,b) +#define min(a,b) cmin(a,b) + +#ifndef malloc16 +# ifdef __AVX2__ +# define malloc16(x) memalign(32,x) +# else +# define malloc16(x) memalign(16,x) +# endif +#endif +#define free16(y,x) free(y) +#define bigmalloc malloc +#define bigmalloc16 malloc16 +#define openair_free(y,x) free((y)) +#define PAGE_SIZE 4096 +#define free_and_zero(PtR) do { \ + if (PtR) { \ + free(PtR); \ + PtR = NULL; \ + } \ + } while (0) +static inline void* malloc16_clear( size_t size ) +{ +#ifdef __AVX2__ + void* ptr = memalign(32, size); +#else + void* ptr = memalign(16, size); +#endif + DevAssert(ptr); + memset( ptr, 0, size ); + return ptr; +} #endif //__PHY_IMPLEMENTATION_DEFS_H__ /**@} diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..f7e0c7ff7fceff153f24d5e82e39eb4aeca3d1f8 --- /dev/null +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -0,0 +1,541 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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/impl_defs_top.h +* \brief More defines and structure definitions +* \author R. Knopp, F. Kaltenberger +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +#ifndef __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ +#define __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ + + +#include "openairinterface5g_limits.h" +/** @defgroup _ref_implementation_ OpenAirInterface LTE Implementation + * @{ + + * @defgroup _PHY_RF_INTERFACE_ PHY - RF Interface + * @ingroup _PHY_RF_INTERFACE_ + * @{ + * @defgroup _GENERIC_PHY_RF_INTERFACE_ Generic PHY - RF Interface + * @defgroup _USRP_PHY_RF_INTERFACE_ PHY - USRP RF Interface + * @defgroup _BLADERF_PHY_RF_INTERFACE_ PHY - BLADERF RF Interface + * @defgroup _LMSSDR_PHY_RF_INTERFACE_ PHY - LMSSDR RF Interface + * @} + * + * @ingroup _ref_implementation_ + * @{ + * This module is responsible for defining the generic interface between PHY and RF Target + * @} + + * @defgroup _openair1_ openair1 Reference Implementation + * @ingroup _ref_implementation_ + * @{ + + + * @defgroup _physical_layer_ref_implementation_ Physical Layer Reference Implementation + * @ingroup _openair1_ + * @{ + + + * @defgroup _PHY_STRUCTURES_ Basic Structures and Memory Initialization + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and initializing the PHY variables during static configuration of OpenAirInterface. + * @} + + * @defgroup _PHY_DSP_TOOLS_ DSP Tools + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for basic signal processing related to inner-MODEM processing. + * @} + + * @defgroup _PHY_MODULATION_ Modulation and Demodulation + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to OFDMA modulation and demodulation. + * @} + + * @defgroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ Parameter Estimation + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to OFDMA frequency-domain channel estimation for LTE Downlink Channels. + * @} + + * @defgroup _PHY_CODING_BLOCKS_ Channel Coding/Decoding Functions + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to channel coding/decoding, rate-matching, segementation and interleaving. + * @} + + * @defgroup _PHY_TRANSPORT_ Transport/Physical Channel Processing + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels. + * @} + + * @defgroup _PHY_PROCEDURES_ Physical Layer Procedures + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels. + * @} + + * @} + * @} + * @} + */ + +//#include "types.h" + +/* + + +#define NUMBER_OF_OFDM_CARRIERS (frame_parms->ofdm_symbol_size) +#define NUMBER_OF_SYMBOLS_PER_FRAME (frame_parms->symbols_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) +#define NUMBER_OF_USEFUL_CARRIERS (12*frame_parms->N_RB_DL) +#define NUMBER_OF_ZERO_CARRIERS (NUMBER_OF_OFDM_CARRIERS-NUMBER_OF_USEFUL_CARRIERS) +#define NUMBER_OF_USEFUL_CARRIERS_BYTES (NUMBER_OF_USEFUL_CARRIERS>>2) +#define HALF_NUMBER_OF_USEFUL_CARRIERS (NUMBER_OF_USEFUL_CARRIERS>>1) +#define HALF_NUMBER_OF_USEFUL_CARRIERS_BYTES (HALF_NUMBER_OF_USEFUL_CARRIERS>>2) +#define FIRST_CARRIER_OFFSET (HALF_NUMBER_OF_USEFUL_CARRIERS+NUMBER_OF_ZERO_CARRIERS) +#define NUMBER_OF_OFDM_SYMBOLS_PER_SLOT (NUMBER_OF_SYMBOLS_PER_FRAME/LTE_SLOTS_PER_FRAME) + +#ifdef EMOS +#define EMOS_SCH_INDEX 1 +#endif //EMOS + +#define EXTENSION_TYPE (PHY_config->PHY_framing.Extension_type) + +#define NUMBER_OF_OFDM_CARRIERS_BYTES NUMBER_OF_OFDM_CARRIERS*4 +//#define NUMBER_OF_USEFUL_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS*4 +#define HALF_NUMBER_OF_USER_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS/2 + +#define CYCLIC_PREFIX_LENGTH (frame_parms->nb_prefix_samples) +#define CYCLIC_PREFIX_LENGTH_SAMPLES (CYCLIC_PREFIX_LENGTH*2) +#define CYCLIC_PREFIX_LENGTH_BYTES (CYCLIC_PREFIX_LENGTH*4) +#define CYCLIC_PREFIX_LENGTH0 (frame_parms->nb_prefix_samples0) +#define CYCLIC_PREFIX_LENGTH_SAMPLES0 (CYCLIC_PREFIX_LENGTH0*2) +#define CYCLIC_PREFIX_LENGTH_BYTES0 (CYCLIC_PREFIX_LENGTH0*4) + +#define OFDM_SYMBOL_SIZE_SAMPLES ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH)*2) // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_SAMPLES0 ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH0)*2) // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_SAMPLES_MAX 4096 // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES (OFDM_SYMBOL_SIZE_SAMPLES/2) // 32-bit units (i.e. complex samples) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0 (OFDM_SYMBOL_SIZE_SAMPLES0/2) // 32-bit units (i.e. complex samples) +#define OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX ((NUMBER_OF_OFDM_CARRIERS)*2) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX/2) +#define OFDM_SYMBOL_SIZE_BYTES (OFDM_SYMBOL_SIZE_SAMPLES*2) +#define OFDM_SYMBOL_SIZE_BYTES0 (OFDM_SYMBOL_SIZE_SAMPLES0*2) +#define OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX*2) + +#define SLOT_LENGTH_BYTES (frame_parms->samples_per_tti<<1) // 4 bytes * samples_per_tti/2 +#define SLOT_LENGTH_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX * NUMBER_OF_OFDM_SYMBOLS_PER_SLOT) + +#define FRAME_LENGTH_COMPLEX_SAMPLES (frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) +#define FRAME_LENGTH_SAMPLES (FRAME_LENGTH_COMPLEX_SAMPLES*2) +#define FRAME_LENGTH_SAMPLES_NO_PREFIX (NUMBER_OF_SYMBOLS_PER_FRAME*OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX) +#define FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX (FRAME_LENGTH_SAMPLES_NO_PREFIX/2) + +#define NUMBER_OF_CARRIERS_PER_GROUP (NUMBER_OF_USEFUL_CARRIERS/NUMBER_OF_FREQUENCY_GROUPS) + +#define RX_PRECISION (16) +#define LOG2_RX_PRECISION (4) +#define RX_OUTPUT_SHIFT (4) + + +#define SAMPLE_SIZE_BYTES 2 // 2 bytes/real sample + +#define FRAME_LENGTH_BYTES (FRAME_LENGTH_SAMPLES * SAMPLE_SIZE_BYTES) // frame size in bytes +#define FRAME_LENGTH_BYTES_NO_PREFIX (FRAME_LENGTH_SAMPLES_NO_PREFIX * SAMPLE_SIZE_BYTES) // frame size in bytes + + +#define FFT_SCALE_FACTOR 8 // Internal Scaling for FFT +#define DMA_BLKS_PER_SLOT (SLOT_LENGTH_BYTES/2048) // Number of DMA blocks per slot +#define SLOT_TIME_NS (SLOT_LENGTH_SAMPLES*(1e3)/7.68) // slot time in ns + +#define NB_ANTENNA_PORTS_ENB 6 // total number of eNB antenna ports + +#ifdef EXMIMO +#define TARGET_RX_POWER 55 // Target digital power for the AGC +#define TARGET_RX_POWER_MAX 55 // Maximum digital power, such that signal does not saturate (value found by simulation) +#define TARGET_RX_POWER_MIN 50 // Minimum digital power, anything below will be discarded (value found by simulation) +#else +#define TARGET_RX_POWER 50 // Target digital power for the AGC +#define TARGET_RX_POWER_MAX 65 // Maximum digital power, such that signal does not saturate (value found by simulation) +#define TARGET_RX_POWER_MIN 35 // Minimum digital power, anything below will be discarded (value found by simulation) +#endif + +//the min and max gains have to match the calibrated gain table +//#define MAX_RF_GAIN 160 +//#define MIN_RF_GAIN 96 +#define MAX_RF_GAIN 200 +#define MIN_RF_GAIN 80 + +#define PHY_SYNCH_OFFSET ((OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)-1) // OFFSET of BEACON SYNCH +#define PHY_SYNCH_MIN_POWER 1000 +#define PHY_SYNCH_THRESHOLD 100 + +*/ + +#define ONE_OVER_SQRT2_Q15_NB_IoT 23170 + +/* +#define ONE_OVER_2_Q15 16384 + +// QAM amplitude definitions + +/// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$) +#define QAM16_n1 20724 +/// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$) +#define QAM16_n2 10362 + +///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{42}\f$) +#define QAM64_n1 20225 +///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{42}\f$) +#define QAM64_n2 10112 +///Third Amplitude for QAM64 (\f$ 2^{15} \times 1/\sqrt{42}\f$) +#define QAM64_n3 5056 + +/// First Amplitude for QAM16 for TM5 (\f$ 2^{15} \times 2/sqrt(20)\f$) +#define QAM16_TM5_n1 14654 +/// Second Amplitude for QAM16 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{20}\f$) +#define QAM16_TM5_n2 7327 + +///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{84}\f$) +#define QAM64_TM5_n1 14301 +///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{84}\f$) +#define QAM64_TM5_n2 7150 +///Third Amplitude for QAM64 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{84}\f$) +#define QAM64_TM5_n3 3575 + + +#ifdef BIT8_RXMUX +#define PERROR_SHIFT 0 +#else +#define PERROR_SHIFT 10 +#endif + +#define BIT8_TX_SHIFT 2 +#define BIT8_TX_SHIFT_DB 12 + +//#define CHBCH_RSSI_MIN -75 + +#ifdef BIT8_TX +#define AMP 128 +#else +#define AMP 512//1024 //4096 +#endif + +#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15) +#define AMP_OVER_2 (AMP>>1) + +/// Threshold for PUCCH Format 1 detection +#define PUCCH1_THRES 0 +/// Threshold for PUCCH Format 1a/1b detection +#define PUCCH1a_THRES 4 + +/// Data structure for transmission. +typedef struct { + /// RAW TX sample buffer + char *TX_DMA_BUFFER[2]; +} TX_VARS ; + +/// Data structure for reception. +typedef struct { + /// RAW TX sample buffer + char *TX_DMA_BUFFER[2]; + /// RAW RX sample buffer + int *RX_DMA_BUFFER[2]; +} TX_RX_VARS; + +//! \brief Extension Type / +typedef enum { + CYCLIC_PREFIX, + CYCLIC_SUFFIX, + ZEROS, + NONE +} Extension_t; + +/// Measurement Variables +*/ +#define NUMBER_OF_SUBBANDS_MAX_NB_IoT 13 +/* +#define NUMBER_OF_HARQ_PID_MAX 8 + +#define MAX_FRAME_NUMBER 0x400 +#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; + +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // RRC measurements + uint32_t rssi; + int n_adj_cells; + unsigned int adj_cell_id[6]; + uint32_t rsrq[7]; + uint32_t rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! total estimated noise power (dB) + unsigned short n0_power_tot_dB; + //! average estimated noise power (linear) + unsigned int n0_power_avg; + //! average estimated noise power (dB) + unsigned short n0_power_avg_dB; + //! total estimated noise power (dBm) + short n0_power_tot_dBm; + + // UE measurements + //! estimated received spatial signal power (linear) + int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + + /// estimated received signal power (sum over all TX/RX antennas) + int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + /// estimated received signal power (sum over all TX/RX antennas) + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + + //! estimated received signal power (sum of all TX/RX antennas, time average) + int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SINR (sum of all TX/RX antennas, in dB) + int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + /// SINR (sum of all TX/RX antennas, time average, in dB) + int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + + /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) + int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + /// Subband CQI per RX antenna (= SINR) + int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI (= SINR) + int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Subband CQI in dB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband Rank indication + unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Number of RX Antennas + unsigned char nb_antennas_rx; + /// DLSCH error counter + // short dlsch_errors; + +} PHY_MEASUREMENTS; +*/ +typedef enum {no_relay_NB_IoT=1,unicast_relay_type1_NB_IoT,unicast_relay_type2_NB_IoT, multicast_relay_NB_IoT} relaying_type_t_NB_IoT; +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // RRC measurements + uint32_t rssi; + int n_adj_cells; + unsigned int adj_cell_id[6]; + uint32_t rsrq[7]; + uint32_t rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! total estimated noise power (dB) + unsigned short n0_power_tot_dB; + //! average estimated noise power (linear) + unsigned int n0_power_avg; + //! average estimated noise power (dB) + unsigned short n0_power_avg_dB; + //! total estimated noise power (dBm) + short n0_power_tot_dBm; + + // UE measurements + //! estimated received spatial signal power (linear) + int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + + /// estimated received signal power (sum over all TX/RX antennas) + int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + /// estimated received signal power (sum over all TX/RX antennas) + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + + //! estimated received signal power (sum of all TX/RX antennas, time average) + int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SINR (sum of all TX/RX antennas, in dB) + int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + /// SINR (sum of all TX/RX antennas, time average, in dB) + int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + + /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) + int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + /// Subband CQI per RX antenna (= SINR) + int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Total Subband CQI (= SINR) + int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Subband CQI in dB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Total Subband CQI + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Wideband PMI for each RX antenna + int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Wideband Rank indication + unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Number of RX Antennas + unsigned char nb_antennas_rx; + /// DLSCH error counter + // short dlsch_errors; + +} PHY_MEASUREMENTS_NB_IoT; + + +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! estimated avg noise power (dB) + unsigned short n0_power_tot_dB; + //! estimated avg noise power (dB) + short n0_power_tot_dBm; + //! estimated avg noise power per RB per RX ant (lin) + unsigned short n0_subband_power[NB_ANTENNAS_RX][100]; + //! estimated avg noise power per RB per RX ant (dB) + unsigned short n0_subband_power_dB[NB_ANTENNAS_RX][100]; + //! estimated avg noise power per RB (dB) + short n0_subband_power_tot_dB[100]; + //! estimated avg noise power per RB (dBm) + short n0_subband_power_tot_dBm[100]; + // eNB measurements (per user) + //! estimated received spatial signal power (linear) + unsigned int rx_spatial_power[NUMBER_OF_UE_MAX_NB_IoT][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX_NB_IoT][2][2]; + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_UE_MAX_NB_IoT]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_UE_MAX_NB_IoT][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_UE_MAX_NB_IoT][2]; + + /// Wideband CQI (= SINR) + int wideband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// Wideband CQI in dB (= SINR dB) + int wideband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// Wideband CQI (sum of all RX antennas, in dB) + char wideband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT]; + /// Subband CQI per RX antenna and RB (= SINR) + int subband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100]; + /// Total Subband CQI and RB (= SINR) + int subband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT][100]; + /// Subband CQI in dB and RB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100]; + /// Total Subband CQI and RB + int subband_cqi_tot_dB[NUMBER_OF_UE_MAX_NB_IoT][100]; + +} PHY_MEASUREMENTS_eNB_NB_IoT; +/* +#define MCS_COUNT 28 +#define MCS_TABLE_LENGTH_MAX 64 +*/ +#endif //__PHY_IMPLEMENTATION_DEFS_H__ +/**@} +*/ diff --git a/openair1/PHY/extern.h b/openair1/PHY/phy_extern.h similarity index 93% rename from openair1/PHY/extern.h rename to openair1/PHY/phy_extern.h index 3ff2d64da05cfd8ed124e217020e340ba0ffdf59..4cb3cc538f91a06f55cd7705fefbb4c35dac9c81 100644 --- a/openair1/PHY/extern.h +++ b/openair1/PHY/phy_extern.h @@ -22,7 +22,7 @@ #ifndef __PHY_EXTERN_H__ #define __PHY_EXTERN_H__ -#include "PHY/defs.h" +#include "PHY/defs_common.h" #include "common/ran_context.h" extern char* namepointer_chMag ; @@ -32,23 +32,21 @@ extern char fmageren_name2[512]; extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX]; extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX]; -#include "PHY/LTE_TRANSPORT/extern.h" -#include "SIMULATION/ETH_TRANSPORT/extern.h" +#include "PHY/LTE_TRANSPORT/transport_extern.h" +//#include "SIMULATION/ETH_TRANSPORT/extern.h" extern unsigned int DAQ_MBOX; extern int number_of_cards; #ifndef OCP_FRAMEWORK -extern PHY_VARS_UE ***PHY_vars_UE_g; //extern PHY_VARS_eNB ***PHY_vars_eNB_g; extern RAN_CONTEXT_t RC; -extern PHY_VARS_RN **PHY_vars_RN_g; extern LTE_DL_FRAME_PARMS *lte_frame_parms_g; #else #define MAX_UE 10 #define MAX_eNB 20 -extern PHY_VARS_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]; + extern PHY_VARS_eNB * PHY_vars_eNB_g[MAX_eNB][MAX_NUM_CCs]; #endif @@ -70,7 +68,7 @@ extern int flagMag; extern char mode_string[4][20]; -#include "PHY/LTE_TRANSPORT/extern.h" + extern unsigned char NB_RU; @@ -126,6 +124,6 @@ extern unsigned short Nb_81_110[8][4]; extern uint16_t hundred_times_log10_NPRB[100]; extern uint8_t alpha_lut[8]; - +extern uint8_t max_turbo_iterations; #endif /*__PHY_EXTERN_H__ */ diff --git a/openair1/PHY/phy_extern_ue.h b/openair1/PHY/phy_extern_ue.h new file mode 100644 index 0000000000000000000000000000000000000000..98dbfb886e858da98de2d418d7afb7a84dd6b859 --- /dev/null +++ b/openair1/PHY/phy_extern_ue.h @@ -0,0 +1,124 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __PHY_EXTERN_UE__H__ +#define __PHY_EXTERN_UE__H__ + +#include "PHY/defs_UE.h" +#include "common/ran_context.h" + +extern char* namepointer_chMag ; +extern char* namepointer_log2; +extern char fmageren_name2[512]; + +extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX]; +extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX]; + +#include "PHY/LTE_TRANSPORT/transport_extern.h" + +extern int number_of_cards; + + +#ifndef OCP_FRAMEWORK +extern PHY_VARS_UE ***PHY_vars_UE_g; +extern LTE_DL_FRAME_PARMS *lte_frame_parms_g; +#else +#define MAX_UE 10 +#define MAX_eNB 20 + +extern PHY_VARS_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]; +#endif + +extern short primary_synch0[144]; +extern short primary_synch1[144]; +extern short primary_synch2[144]; +extern unsigned char primary_synch0_tab[72]; +extern unsigned char primary_synch1_tab[72]; +extern unsigned char primary_synch2_tab[72]; +extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[ +extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[ +extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[ +extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[ +extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[ +extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[ + +extern int flagMag; +//extern short **txdataF_rep_tmp; + +extern char mode_string[4][20]; + +extern unsigned char NB_RU; + +#ifndef OPENAIR2 +extern unsigned char NB_eNB_INST; +extern unsigned char NB_UE_INST; +extern unsigned char NB_RN_INST; +#endif + +extern unsigned int ULSCH_max_consecutive_errors; +extern int flag_LA; +extern double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX]; +extern double sinr_bler_map_up[MCS_COUNT][2][16]; +extern int table_length[MCS_COUNT]; +extern double sinr_to_cqi[4][16]; +extern int cqi_to_mcs[16]; + +//for MU-MIMO abstraction using MIESM +//this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively +extern double MI_map_4qam[3][162]; +extern double MI_map_16qam[3][197]; +extern double MI_map_64qam[3][227]; + +extern double beta1_dlsch_MI[6][MCS_COUNT]; +extern double beta2_dlsch_MI[6][MCS_COUNT]; + +extern double q_qpsk[8]; +extern double q_qam16[8]; +extern double q_qam64[8]; + +extern double p_qpsk[8]; +extern double p_qam16[8]; +extern double p_qam64[8]; + +extern double beta1_dlsch[6][MCS_COUNT]; +extern double beta2_dlsch[6][MCS_COUNT]; + +extern char eNB_functions[6][20]; +extern char eNB_timing[2][20]; +extern char ru_if_types[MAX_RU_IF_TYPES][20]; + +extern int16_t unscrambling_lut[65536*16]; +extern uint8_t scrambling_lut[65536*16]; + +extern unsigned short msrsb_6_40[8][4]; +extern unsigned short msrsb_41_60[8][4]; +extern unsigned short msrsb_61_80[8][4]; +extern unsigned short msrsb_81_110[8][4]; +extern unsigned short Nb_6_40[8][4]; +extern unsigned short Nb_41_60[8][4]; +extern unsigned short Nb_61_80[8][4]; +extern unsigned short Nb_81_110[8][4]; + +extern uint16_t hundred_times_log10_NPRB[100]; +extern uint8_t alpha_lut[8]; +extern uint8_t max_turbo_iterations; +#endif /*__PHY_EXTERN_H__ */ + diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h new file mode 100644 index 0000000000000000000000000000000000000000..783a151046871bb85ecd1ee129e43a1eedfb131d --- /dev/null +++ b/openair1/PHY/phy_vars.h @@ -0,0 +1,156 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __PHY_VARS_H__ +#define __PHY_VARS_H__ + +#include "PHY/types.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "common/ran_context.h" + +char* namepointer_chMag ; +char fmageren_name2[512]; +char* namepointer_log2; + + +#include "PHY/LTE_REFSIG/primary_synch.h" +int16_t *primary_synch0_time; +int16_t *primary_synch1_time; +int16_t *primary_synch2_time; + + +#include "PHY/CODING/coding_vars.h" +#include "PHY/LTE_TRANSPORT/transport_vars.h" +#include "PHY/MODULATION/modulation_vars.h" + +//PHY_VARS *PHY_vars; +#ifndef OCP_FRAMEWORK +PHY_VARS_UE ***PHY_vars_UE_g; +RAN_CONTEXT_t RC; + +//PHY_VARS_eNB ***PHY_vars_eNB_g; +//PHY_VARS_RN **PHY_vars_RN_g; +LTE_DL_FRAME_PARMS *lte_frame_parms_g; +#else +PHY_VARS_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]={NULL}; +PHY_VARS_eNB * PHY_vars_eNB_g[MAX_eNB][MAX_NUM_CCs]={NULL}; +#endif + + +unsigned short rev[2048],rev_times4[8192],rev_half[1024]; +unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192]; + + +char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; + + + + +#include "SIMULATION/ETH_TRANSPORT/vars.h" + +unsigned char NB_RU=0; + +#ifndef OPENAIR2 +unsigned char NB_eNB_INST=0; +unsigned char NB_UE_INST=0; +unsigned char NB_RN_INST=0; +unsigned char NB_INST=0; +#endif + +unsigned int ULSCH_max_consecutive_errors = 20; + +int number_of_cards; + + +int flag_LA=0; +int flagMag; +//extern channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; +//extern double ABS_SINR_eff_BLER_table[MCS_COUNT][9][9]; +//extern double ABS_beta[MCS_COUNT];odi +double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX]; +int table_length[MCS_COUNT]; +//double sinr_bler_map_up[MCS_COUNT][2][16]; + +//for MU-MIMO abstraction using MIESM +//this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively +double MI_map_4qam[3][162]; +double MI_map_16qam[3][197]; +double MI_map_64qam[3][227]; + +// here the first index is for transmission mode 1, 2, 5 and 6 whereas the second index is for the 16 sinr vaues corresponding to 16 CQIs +double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281, 17.2424, 17.2424, 17.2424}, + {-2.2360, -2.2360, -1.3919, -0.0218, 1.5319, 2.9574, 4.3234, 6.3387, 8.9879, 9.5096, 12.6609, 14.0116, 16.4984, 18.1572, 18.1572, 18.1572}, + {-1, -1.0000, -0.4198, -0.0140, 1.0362, 2.3520, 3.5793, 6.1136, 8.4836, 9.0858, 12.4723, 13.9128, 16.2054, 17.7392, 17.7392, 17.7392}, + { -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545} +}; + +//int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27}; +int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28}; + +//for SNR to MI conversion 7 th order Polynomial coeff +double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639}; +double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425}; +double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898}; + +//for MI to SNR conversion 7 th order Polynomial coeff +double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965}; +double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089}; +double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343}; + +// ideal CE MIESM + +double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}}; +double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}}; + +//real CE MIESM +/* +double beta1_dlsch_MI[6][MCS_COUNT] = { {1.32955, 0.59522, 0.54024, 0.98698, 0.81305, 0.76976, 0.69258, 0.69713, 0.70546, 0.69111, 0.81904, 0.72664, 0.79491, 0.72562, 0.53980, 0.33134, 0.50550, 0.40602,0.40281,0.47012,0.50510,0.23540,0.32045,1}, {0.59632, 1.08475, 1.02431, 1.07020, 0.90170, 0.97719, 0.95464, 0.92764, 0.86721, 0.85986, 0.64558, 0.80631, 0.82673, 0.82888, 0.87122, 0.77245, 0.29771, 0.43477, 0.55321, 0.61027, 0.56111, 0.57292, 0.39737,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.77532, 1.07544, 1.10571, 1.04099, 0.91638, 0.88644, 0.96405, 0.86709, 0.94066, 0.84430, 1.24478, 1.09665, 1.42604, 0.79541, 0.71847, 0.71604, 0.74561, 0.36431, 0.41536, 0.52175, 0.47096, 0.49977, 0.59728,1}}; +double beta2_dlsch_MI[6][MCS_COUNT] = { {1.36875, 0.59304, 0.53870, 0.98239, 0.81637, 0.76847, 0.69842, 0.69885, 0.69967, 0.69826, 0.82660, 0.70559, 0.78404, 0.70670, 0.55393, 0.36893, 0.52225, 0.39752, 0.40494, 0.46239, 0.49247,0.26900,0.34504,1}, {0.43775, 0.78208, 0.72875, 0.77458, 0.64485, 0.69174, 0.66097, 0.63289, 0.59652, 0.61175, 0.44551, 0.56047, 0.57314, 0.57553, 0.58849, 0.52159, 0.21241, 0.30139, 0.37373, 0.32029, 0.37067, 0.36706, 0.27118,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.54448, 0.73731, 0.79165, 0.74407, 0.68042, 0.64906, 0.71349, 0.62109, 0.65815, 0.60940, 0.90549, 0.78708, 1.03176, 0.58431, 0.53379, 0.51224, 0.52767, 0.26848, 0.29642, 0.36879, 0.34148, 0.35279,0.40633,1}}; +*/ +//ideal channel estimation values +//double beta1_dlsch[6][MCS_COUNT] = { {2.3814, 0.4956, 0.5273, 1.1708, 0.8014, 0.7889, 0.8111, 0.8139, 0.8124, 0.8479, 1.9280, 1.9664, 2.3857, 2.5147, 2.4511, 3.0158, 2.8643, 5.3013, 5.8594, 6.5372, 7.8073, 7.8030, 7.5295, 7.1320}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}}; +//double beta2_dlsch[6][MCS_COUNT] = { {2.3639, 0.4952, 0.5207, 1.1572, 0.8026, 0.7864, 0.7996, 0.8034, 0.8200, 0.8367, 1.8701, 1.9212, 2.2947, 2.4472, 2.4091, 2.9479, 2.8973, 5.0591, 5.5134, 6.1483, 7.2166, 7.5177, 7.5704, 7.2248}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}}; +double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}}; +double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}}; + +//real channel estimation valus +/* +double beta1_dlsch[6][MCS_COUNT] = { {2.50200, 0.84047, 0.78195, 1.37929, 1.16871, 1.11906, 1.06303, 1.07447, 1.11403, 1.09223, 2.82502, 2.87556, 3.51254, 3.62920, 3.53638, 2.35980, 3.74126, 8.66532, 7.31772, 9.86882, 10.64939, 6.75208, 9.50664, 13.63057}, {0.92257, 1, 1.80445, 1.43175, 1.42093, 1.37381, 1.45392, 1.47255, 1.47451, 1.41235, 3.9079, 3.38557, 4.13059, 4.93355, 4.97277, 6.04951, 5.88896, 8.68076, 10.23746, 12.37069, 5.50538, 17.29612, 17.95050, 13.27095}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79255, 1.88213, 4.44226, 2.25150, 1.93710, 2.18504, 2.57389, 1.94322, 1.78515, 2.09265, 2.37459, 1.74442, 1.74346, 1.19705, 1.56149, 1.59604, 1.6, 1,1,1,1,1,1,1}, {0.93374, 1.40389, 1.36670, 1.38679, 1.35707, 1.26353, 1.32360, 1.40164, 1.51843, 1.34863, 3.45839, 3.13726, 3.94768, 4.21966, 4.60750, 4.97894, 5.40755, 8.12814, 10.59221, 12.96427, 13.37323, 14.27206, 16.61779, 17.19656}}; +double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.16829, 1.11186, 1.06287, 1.07292, 1.09946, 1.10650, 2.79174, 2.75655, 3.36651, 3.49011, 3.60903, 2.73517, 3.84009, 8.20312, 7.41739, 9.64081, 10.40911, 8.11765, 10.41923, 9.34300}, {0.67252, 0.8600, 1.28633, 1.01624, 1.03066, 0.97590, 1.02560, 1.01840, 1.00547, 0.97093, 2.72573, 2.33283, 2.86181, 3.40452, 3.47957, 4.08916, 3.97628, 6.14541, 7.11017, 8.42369, 4.04812, 11.42082, 11.57171, 9.28462}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.85784, 0.90361, 2.09766, 1.08385, 0.96300, 1.04432, 1.22763, 0.99249, 0.95544, 1.12333, 1.37924, 1.12913, 1.30644, 1.19253, 1.75488, 2.13813, 2.10636, 1,1,1,1,1,1,1}, {0.66288, 0.96402, 0.98545, 0.99386, 0.99981, 0.92678, 0.98978, 0.99600, 1.05538, 0.97777, 2.52504, 2.29338, 2.89631, 3.10812, 3.41916, 3.58671, 3.84166, 6.05254, 7.45821, 9.15812, 9.66330, 10.17852, 11.50519, 11.16299}}; + +*/ + +#ifdef OCP_FRAMEWORK +#include <enums.h> +#else +char eNB_functions[6][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",}; +char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"}; +char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"}; +#endif + +/// lookup table for unscrambling in RX +int16_t unscrambling_lut[65536*16] __attribute__((aligned(32))); +/// lookup table for scrambling in TX +uint8_t scrambling_lut[65536*16] __attribute__((aligned(32))); + +uint8_t max_turbo_iterations=4; +#endif /*__PHY_VARS_H__ */ diff --git a/openair1/PHY/vars.h b/openair1/PHY/phy_vars_ue.h similarity index 98% rename from openair1/PHY/vars.h rename to openair1/PHY/phy_vars_ue.h index f78cb92bcd394bd57394ed73fcba6819375c4169..c323d1eade612f6a3173ba5848322fefa2f5d117 100644 --- a/openair1/PHY/vars.h +++ b/openair1/PHY/phy_vars_ue.h @@ -23,7 +23,10 @@ #define __PHY_VARS_H__ #include "PHY/types.h" -#include "PHY/defs.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_vars_ue.h" + +#include "common/ran_context.h" char* namepointer_chMag ; char fmageren_name2[512]; @@ -36,19 +39,15 @@ int16_t *primary_synch1_time; int16_t *primary_synch2_time; -#include "PHY/CODING/vars.h" +#include "PHY/CODING/coding_vars.h" //PHY_VARS *PHY_vars; #ifndef OCP_FRAMEWORK PHY_VARS_UE ***PHY_vars_UE_g; -RAN_CONTEXT_t RC; - -//PHY_VARS_eNB ***PHY_vars_eNB_g; -//PHY_VARS_RN **PHY_vars_RN_g; LTE_DL_FRAME_PARMS *lte_frame_parms_g; #else PHY_VARS_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]={NULL}; -PHY_VARS_eNB * PHY_vars_eNB_g[MAX_eNB][MAX_NUM_CCs]={NULL}; + #endif @@ -57,7 +56,6 @@ unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048] char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; -#include "PHY/LTE_TRANSPORT/vars.h" @@ -148,5 +146,5 @@ int16_t unscrambling_lut[65536*16] __attribute__((aligned(32))); /// lookup table for scrambling in TX uint8_t scrambling_lut[65536*16] __attribute__((aligned(32))); - +uint8_t max_turbo_iterations=4; #endif /*__PHY_VARS_H__ */ diff --git a/openair1/SCHED/vars.h b/openair1/PHY/types_NB_IoT.h similarity index 85% rename from openair1/SCHED/vars.h rename to openair1/PHY/types_NB_IoT.h index 4dac375f18d0973167228192c7371f75b89d5eea..6735092583ce8916ac19ea4966e9dd6a55a30b38 100644 --- a/openair1/SCHED/vars.h +++ b/openair1/PHY/types_NB_IoT.h @@ -19,8 +19,14 @@ * contact@openairinterface.org */ -#include "defs.h" - +#ifndef __openair_TYPES_NB_IOT_H__ +#define __openair_TYPES_NB_IOT_H__ +#ifdef USER_MODE +#include <stdint.h> +#else +#include <linux/types.h> +#endif +#endif /*__openair_TYPES_NB_IOT_H__ */ diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 63e4d9248ebd79179569c2d7efddfce0728fe5f8..0849c1d364e03ca6e831701241cb24ecddd794e8 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -30,11 +30,12 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "SCHED/sched_eNB.h" + #include "nfapi_interface.h" +#include "nfapi_pnf_interface.h" #include "fapi_l1.h" int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req); @@ -62,7 +63,8 @@ void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) @@ -76,6 +78,7 @@ void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, // copy dci configuration into eNB structure fill_mdci_and_dlsch(eNB,proc,&mpdcch_vars->mdci_alloc[mpdcch_vars->num_dci],pdu); } + #endif void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, @@ -125,7 +128,7 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, // adjust transmit amplitude here based on NFAPI info } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) extern uint32_t localRIV2alloc_LUT6[32]; extern uint32_t localRIV2alloc_LUT25[512]; extern uint32_t localRIV2alloc_LUT50_0[1600]; @@ -142,10 +145,10 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr uint8_t *sdu) { nfapi_dl_config_dlsch_pdu_rel8_t *rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8; -#ifndef Rel8 +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) nfapi_dl_config_dlsch_pdu_rel10_t *rel10 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10; #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) nfapi_dl_config_dlsch_pdu_rel13_t *rel13 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13; #endif LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; @@ -164,7 +167,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr dlsch0 = eNB->dlsch[UE_id][0]; dlsch1 = eNB->dlsch[UE_id][1]; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[frame%2][subframe] = 0; #endif @@ -196,31 +199,34 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr # else if (dlsch0->active){ #endif - computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); - computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); + computeRhoA_eNB(rel8->pa, dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); + computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); } #ifdef PHY_TX_THREAD if (dlsch1->active[proc->subframe_tx]){ #else if (dlsch1->active){ #endif - computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); - computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); + computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); + computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); } dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols; if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU if(sdu == NULL) { - LOG_E(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d\n", - proc->frame_tx, proc->subframe_tx, rel8->rnti, UE_id, harq_pid, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index); + LOG_E(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", + frame,subframe, + proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start); return; } - //AssertFatal(sdu!=NULL,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d\n", + //AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", + // frame,subframe, // proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index); - if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n", - proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start); + if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n", + frame,subframe,proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); if (codeword_index == 0) dlsch0_harq->pdu = sdu; else dlsch1_harq->pdu = sdu; } @@ -230,7 +236,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr rel8->rnti,UE_id,harq_pid); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) #ifdef PHY_TX_THREAD dlsch0_harq->sib1_br_flag=0; #else @@ -293,20 +299,15 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr dlsch0_harq->codeword = 0; dlsch0_harq->pdsch_start = rel10->pdsch_start; } - else { #ifdef PHY_TX_THREAD - dlsch0_harq->i0 = 0xFFFF; + dlsch0_harq->i0 = rel13->initial_transmission_sf_io; #else - dlsch0->i0 = 0xFFFF; + dlsch0->i0 = rel13->initial_transmission_sf_io; #endif - } -#endif -#ifdef PHY_TX_THREAD - dlsch0_harq->i0 = rel13->initial_transmission_sf_io; -#else - dlsch0->i0 = rel13->initial_transmission_sf_io; + #endif +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", #ifdef PHY_TX_THREAD dlsch0_harq->i0, @@ -316,6 +317,12 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], rel8->length ); +#else + LOG_D(PHY,"dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", + dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], + rel8->length + ); +#endif } uint16_t to_beta_offset_harqack[16]={16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8}; @@ -573,7 +580,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, "No existing UE ULSCH for rnti %x\n",rel8->rnti); - //LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d\n", UE_id,rel8->rnti,frame,subframe); + LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d, modulation %d, rvidx %d\n", UE_id,rel8->rnti,frame,subframe,rel8->modulation_type,rel8->redundancy_version); fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_pdu,frame,subframe); @@ -659,9 +666,15 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) AssertFatal(RC.eNB[Mod_id]!=NULL,"RC.eNB[%d] is null\n",Mod_id); AssertFatal(RC.eNB[Mod_id][CC_id]!=NULL,"RC.eNB[%d][%d] is null\n",Mod_id,CC_id); + + eNB = RC.eNB[Mod_id][CC_id]; fp = &eNB->frame_parms; proc = &eNB->proc.proc_rxtx[0]; + + /* TODO: check that following line is correct - in the meantime it is disabled */ + //if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return; + ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); @@ -701,9 +714,12 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) int do_oai =0; int dont_send =0; - + /* TODO: check the following test - in the meantime it is put back as it was before */ + //if ((ul_subframe<10)&& + // (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is an ul_subframe that can be configured here if (ul_subframe<10) { // This means that there is an ul_subframe that can be configured here - LOG_D(PHY,"NFAPI: Clearing dci allocations for potential UL\n"); + LOG_D(PHY,"NFAPI: Clearing dci allocations for potential UL subframe %d\n",ul_subframe); + harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); // clear DCI allocation maps for new subframe @@ -807,7 +823,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: // handle_nfapi_epdcch_pdu(eNB,dl_config_pdu); break; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); eNB->mpdcch_vars[subframe&1].num_dci++; @@ -875,3 +891,25 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) } } } + +/*Dummy functions*/ + +int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) +{ + return 0; +} + +int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) +{ + return 0; +} + +int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) +{ + return 0; +} + +int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) +{ + return 0; +} diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index 725bb31c455fdf6e11c4b917ac0801bfb9d1faa1..efb028f46444b73cbed6df710faf6db75bcc4080 100644 --- a/openair1/SCHED/fapi_l1.h +++ b/openair1/SCHED/fapi_l1.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -30,10 +30,11 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "SCHED/sched_eNB.h" +#include "SCHED/sched_common.h" #include "nfapi_interface.h" void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask); diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index 1981f53ee2dde06461a25e854deee02952fae652..26a518e8ef5474ae8b194696fab446c2641af1d0 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -29,10 +29,10 @@ * \note * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "SCHED/sched_common_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms, unsigned char current_subframe, @@ -854,12 +854,7 @@ dci_detect_mode_t dci_detect_mode_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t return ret; } -lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subframe) -{ - - return(subframe_select(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe)); -} uint8_t phich_subframe_to_harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe) { @@ -1089,3 +1084,73 @@ void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeri } } + +// uint8_t eNB_id,uint8_t harq_pid, uint8_t UE_id, +int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs) +{ + + /// The payload + CRC size in bits, "B" + uint32_t B; + /// Number of code segments + uint32_t C; + /// Number of "small" code segments + uint32_t Cminus; + /// Number of "large" code segments + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) + uint32_t Kplus; + /// Total number of bits across all segments + uint32_t sumKr; + /// Number of "Filler" bits + uint32_t F; + // num resource elements + uint32_t num_re=0.0; + // num symbols + uint32_t num_symb=0.0; + /// effective spectral efficiency of the PUSCH + uint32_t MPR_x100=0; + /// beta_offset + uint16_t beta_offset_pusch_x8=8; + /// delta mcs + float delta_mcs=0.0; + /// bandwidth factor + float bw_factor=0.0; + + B= tbs+24; + lte_segmentation(NULL, + NULL, + B, + &C, + &Cplus, + &Cminus, + &Kplus, + &Kminus, + &F); + + + sumKr = Cminus*Kminus + Cplus*Kplus; + num_symb = 12-(ncp<<1)-(use_srs==0?0:1); + num_re = num_symb * nb_rb * 12; + + if (num_re == 0) + return(0); + + MPR_x100 = 100*sumKr/num_re; + + if (control_only == 1 ) + beta_offset_pusch_x8=8; // fixme + + //(beta_offset_pusch_x8=ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; + + // if deltamcs_enabledm + delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch_x8)>>3))/100.0); + bw_factor = (hundred_times_log10_NPRB[nb_rb-1]/100.0); +#ifdef DEBUG_SEGMENTATION + printf("estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n", + (int16_t)ceil(delta_mcs + bw_factor), num_re, sumKr, MPR_x100, delta_mcs, bw_factor); +#endif + return (int16_t)ceil(delta_mcs + bw_factor); + +} diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index d320a566c6d0d5977c1234aeb37762ff9060ccc8..b66dd504f8859461985b1389d48885db5a448627 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -30,10 +30,11 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" +#include "SCHED/sched_common_extern.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "nfapi_interface.h" #include "fapi_l1.h" #include "UTIL/LOG/log.h" @@ -51,16 +52,94 @@ #endif extern uint8_t nfapi_mode; + + + +int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) +{ + + uint32_t Nre,sumKr,MPR_x100,Kr,r; + uint16_t beta_offset_pusch; + + DevAssert( UE_id < NUMBER_OF_UE_MAX+1 ); + DevAssert( harq_pid < 8 ); + + Nre = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_initial * + eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12; + + sumKr = 0; + + for (r=0; r<eNB->ulsch[UE_id]->harq_processes[harq_pid]->C; r++) { + if (r<eNB->ulsch[UE_id]->harq_processes[harq_pid]->Cminus) + Kr = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kminus; + else + Kr = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus; + + sumKr += Kr; + } + + if (Nre==0) + return(0); + + MPR_x100 = 100*sumKr/Nre; + // Note: MPR=is the effective spectral efficiency of the PUSCH + // FK 20140908 sumKr is only set after the ulsch_encoding + + beta_offset_pusch = 8; + //(eNB->ulsch[UE_id]->harq_processes[harq_pid]->control_only == 1) ? eNB->ulsch[UE_id]->beta_offset_cqi_times8:8; + + DevAssert( UE_id < NUMBER_OF_UE_MAX ); +//#warning "This condition happens sometimes. Need more investigation" // navid + //DevAssert( MPR_x100/6 < 100 ); + + if (1==1) { //eNB->ul_power_control_dedicated[UE_id].deltaMCS_Enabled == 1) { + // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch) + if (bw_factor == 1) { + uint8_t nb_rb = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb; + return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)) + hundred_times_log10_NPRB[nb_rb-1]; + } else + return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)); + } else { + return(0); + } +} + + +int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid) +{ + + int8_t UE_id; + + if ((RC.eNB == NULL) || (module_idP > RC.nb_inst) || (CC_id > RC.nb_CC[module_idP])) { + LOG_E(PHY,"get_UE_stats: No eNB found (or not allocated) for Mod_id %d,CC_id %d\n",module_idP,CC_id); + return -1; + } + + UE_id = find_ulsch( rnti, RC.eNB[module_idP][CC_id],SEARCH_EXIST); + + if (UE_id == -1) { + // not found + return 0; + } + + return get_hundred_times_delta_IF_eNB( RC.eNB[module_idP][CC_id], UE_id, harq_pid, 0 ); +} + int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); +lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subframe) +{ + + return(subframe_select(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe)); + +} -void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,relaying_type_t r_type) { +void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) MCH_PDU *mch_pduP=NULL; - MCH_PDU mch_pdu; // uint8_t sync_area=255; #endif @@ -75,7 +154,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,rel subframe<<1,1); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // if mcch is active, send regardless of the node type: eNB or RN // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing /* @@ -84,50 +163,17 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,rel proc->frame_tx, subframe); */ - switch (r_type) { - case no_relay: - if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0 - LOG_D(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n", - eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs, - eNB->dlsch_MCH->harq_processes[0]->TBS>>3); - else { - LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n", - eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area, - (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment"); - mch_pduP = NULL; - } - - break; - - case multicast_relay: - if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) { - LOG_D(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n", - rn->Mod_id,rn->frame, subframe, - mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size); - } else if (rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8 - mch_pduP= &mch_pdu; - memcpy(&mch_pduP->payload, // could be a simple copy - rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b, - rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3); - mch_pduP->Pdu_size = (uint16_t) (rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3); - mch_pduP->mcs = rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs; - LOG_D(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n", - rn->Mod_id,rn->frame, subframe,subframe%5, - rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size); - } else { - mch_pduP=NULL; - } - - rn->mch_avtive[subframe]=0; - break; + if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0 + LOG_D(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n", + eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs, + eNB->dlsch_MCH->harq_processes[0]->TBS>>3); + else { + LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n", + eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area, + (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment"); + mch_pduP = NULL; + } - default: - LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n", - eNB->Mod_id,proc->frame_tx,subframe,r_type); - mch_pduP=NULL; - break; - }// switch - if (mch_pduP) { fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0); // Generate PMCH @@ -356,14 +402,24 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, start_meas(&eNB->dlsch_encoding_stats); eNB->te(eNB, - dlsch_harq->pdu, - dlsch_harq->pdsch_start, - dlsch, - frame,subframe, - &eNB->dlsch_rate_matching_stats, - &eNB->dlsch_turbo_encoding_stats, - &eNB->dlsch_interleaving_stats); + dlsch_harq->pdu, + dlsch_harq->pdsch_start, + dlsch, + frame, + subframe, + &eNB->dlsch_rate_matching_stats, + &eNB->dlsch_turbo_encoding_stats, + &eNB->dlsch_turbo_encoding_waiting_stats, + &eNB->dlsch_turbo_encoding_main_stats, + &eNB->dlsch_turbo_encoding_wakeup_stats0, + &eNB->dlsch_turbo_encoding_wakeup_stats1, + &eNB->dlsch_interleaving_stats); stop_meas(&eNB->dlsch_encoding_stats); + //////////////////////////////////////////////////******************************************* + if(eNB->dlsch_encoding_stats.diff_now>500*3000 && opp_enabled == 1) + { + print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr); + } // 36-211 start_meas(&eNB->dlsch_scrambling_stats); dlsch_scrambling(fp, @@ -409,13 +465,11 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, + void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, - relaying_type_t r_type, - PHY_VARS_RN *rn, int do_meas) { - UNUSED(rn); int frame=proc->frame_tx; int subframe=proc->subframe_tx; uint32_t i,aa; @@ -430,6 +484,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, int offset = eNB->CC_id;//proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1); @@ -442,9 +497,10 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } + if (nfapi_mode == 0 || nfapi_mode == 1) { if (is_pmch_subframe(frame,subframe,fp)) { - pmch_procedures(eNB,proc,rn,r_type); + pmch_procedures(eNB,proc); } else { // this is not a pmch subframe, so generate PSS/SSS/PBCH @@ -452,6 +508,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } } + // clear existing ulsch dci allocations before applying info from MAC (this is table ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); @@ -465,6 +522,9 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } /* save old HARQ information needed for PHICH generation */ + /* TODO: check the following test - in the meantime it is put back as it was before */ + //if ((ul_subframe < 10)&& + // (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is a potential UL subframe that will be scheduled here if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here for (i=0; i<NUMBER_OF_UE_MAX; i++) { harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); @@ -557,6 +617,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, else { // generate pdsch + pdsch_procedures(eNB, proc, harq_pid, @@ -598,181 +659,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } -#ifdef Rel14 -void prach_procedures(PHY_VARS_eNB *eNB, - int br_flag) { -#else -void prach_procedures(PHY_VARS_eNB *eNB) { -#endif - uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4]; - uint16_t i; - int frame,subframe; - -#ifdef Rel14 - if (br_flag==1) { - subframe = eNB->proc.subframe_prach_br; - frame = eNB->proc.frame_prach_br; - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles=0; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - } - else -#endif - { - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - subframe = eNB->proc.subframe_prach; - frame = eNB->proc.frame_prach; - } - RU_t *ru; - int aa=0; - int ru_aa; - - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); - - - - for (i=0;i<eNB->num_RU;i++) { - ru=eNB->RU_list[i]; - for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) { - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; -#ifdef Rel14 - int ce_level; - - if (br_flag==1) - for (ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; -#endif - } - } - - rx_prach(eNB, - eNB->RU_list[0], - &max_preamble[0], - &max_preamble_energy[0], - &max_preamble_delay[0], - frame, - 0 -#ifdef Rel14 - ,br_flag -#endif - ); - - //#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d\n", - frame,subframe, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_delay[0]); - //q#endif - -#ifdef Rel14 - if (br_flag==1) { - - int prach_mask; - - prach_mask = is_prach_subframe(&eNB->frame_parms,eNB->proc.frame_prach_br,eNB->proc.subframe_prach_br); - - eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br; - int ind=0; - int ce_level=0; - /* Save for later, it doesn't work - for (int ind=0,ce_level=0;ce_level<4;ce_level++) { - - if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[ce_level]==1)&& - (prach_mask&(1<<(1+ce_level)) > 0) && // prach is active and CE level has finished its repetitions - (eNB->prach_vars_br.repetition_number[ce_level]== - eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) { - */ - if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]==1){ - if ((eNB->prach_energy_counter == 100) && - (max_preamble_energy[0] > eNB->measurements.prach_I0 + 100)) { - eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles++; - - eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind];// - eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind]; - // note: fid is implicitly 0 here, this is the rule for eMTC RA-RNTI from 36.321, Section 5.1.4 - eNB->preamble_list_br[ind].preamble_rel8.rnti = 1+subframe+(eNB->prach_vars_br.first_frame[ce_level]%40); - eNB->preamble_list_br[ind].instance_length = 0; //don't know exactly what this is - eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type = 1+ce_level; // CE Level - LOG_D(PHY,"Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - ind, - ce_level, - prach_mask, - eNB->preamble_list_br[ind].preamble_rel8.timing_advance, - eNB->preamble_list_br[ind].preamble_rel8.preamble, - eNB->preamble_list_br[ind].preamble_rel8.rnti, - eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type); - } - /* - ind++; - } - } */// ce_level - } - } - else -#endif - - { - if ((eNB->prach_energy_counter == 100) && - (max_preamble_energy[0] > eNB->measurements.prach_I0+100)) { - - LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", - eNB->Mod_id, - eNB->CC_id, - frame, - subframe, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_energy[0]%10, - max_preamble_delay[0]); - - T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), - T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); - - pthread_mutex_lock(&eNB->UL_INFO_mutex); - - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; - eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; - eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; - eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; - eNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; - - eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; - eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; - eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; - eNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here - eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; - eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is - - if (nfapi_mode == 1) { // If NFAPI PNF then we need to send the message to the VNF - - LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), - eNB->preamble_list[0].preamble_rel8.timing_advance, - eNB->preamble_list[0].preamble_rel8.preamble, - eNB->preamble_list[0].preamble_rel8.rnti, - eNB->preamble_list[0].preamble_rel13.rach_resource_type); - - oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind); - - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; - } - - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - - } // max_preamble_energy > prach_I0 + 100 - else { - eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); - if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",eNB->measurements.prach_I0/10,eNB->measurements.prach_I0%10); - if (eNB->prach_energy_counter < 100) eNB->prach_energy_counter++; - } - } // else br_flag - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); -} - void srs_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; @@ -840,7 +726,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0}; - int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric; + int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric=0; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; int i; @@ -1117,7 +1003,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) harq_ack[0] = 4; // DTX harq_ack[1] = 6; // NACK/DTX harq_ack[2] = 6; // NACK/DTX - + max_metric = 0; } else { @@ -1200,7 +1086,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) harq_ack[1] = 6; // NACK/DTX harq_ack[2] = 6; // NACK/DTX harq_ack[3] = 6; // NACK/DTX - + max_metric = 0; } else { max_metric = max(metric[0],max(metric[1],max(metric[2],metric[3]))); @@ -1428,7 +1314,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) start_meas(&eNB->ulsch_demodulation_stats); - rx_ulsch(eNB,proc, i); + rx_ulsch(eNB,proc, i); stop_meas(&eNB->ulsch_demodulation_stats); @@ -1488,10 +1374,11 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", eNB->Mod_id,harq_pid, frame,subframe, i, - ulsch_harq->round-1, + ulsch_harq->round, ulsch->Mlimit, ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1]); + if (ulsch_harq->round >= 3) { ulsch_harq->status = SCH_IDLE; ulsch_harq->handled = 0; @@ -1584,37 +1471,63 @@ extern int oai_exit; extern void *td_thread(void*); -void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) { +void init_td_thread(PHY_VARS_eNB *eNB) { eNB_proc_t *proc = &eNB->proc; proc->tdp.eNB = eNB; proc->instance_cnt_td = -1; - + + pthread_attr_init( &proc->attr_td); pthread_mutex_init( &proc->mutex_td, NULL); pthread_cond_init( &proc->cond_td, NULL); + + pthread_create(&proc->pthread_td, &proc->attr_td, td_thread, (void*)&proc->tdp); - pthread_create(&proc->pthread_td, attr_td, td_thread, (void*)&proc->tdp); +} +void kill_td_thread(PHY_VARS_eNB *eNB) { + eNB_proc_t *proc = &eNB->proc; + proc->instance_cnt_td = 0; + pthread_cond_signal(&proc->cond_td); + + pthread_join(proc->pthread_td, NULL); + pthread_mutex_destroy( &proc->mutex_td ); + pthread_cond_destroy( &proc->cond_td ); } extern void *te_thread(void*); -void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) { +void init_te_thread(PHY_VARS_eNB *eNB) { eNB_proc_t *proc = &eNB->proc; - proc->tep.eNB = eNB; - proc->instance_cnt_te = -1; + for(int i=0; i<3 ;i++){ + proc->tep[i].eNB = eNB; + proc->tep[i].instance_cnt_te = -1; + + pthread_mutex_init( &proc->tep[i].mutex_te, NULL); + pthread_cond_init( &proc->tep[i].cond_te, NULL); + pthread_attr_init( &proc->tep[i].attr_te); - pthread_mutex_init( &proc->mutex_te, NULL); - pthread_cond_init( &proc->cond_te, NULL); + printf("Creating te_thread 0\n"); + pthread_create(&proc->tep[i].pthread_te, &proc->tep[i].attr_te, te_thread, (void*)&proc->tep[i]); + } +} +void kill_te_thread(PHY_VARS_eNB *eNB) { - printf("Creating te_thread\n"); - pthread_create(&proc->pthread_te, attr_te, te_thread, (void*)&proc->tep); + eNB_proc_t *proc = &eNB->proc; + for(int i=0; i<3 ;i++){ + proc->tep[i].instance_cnt_te = 0; + pthread_cond_signal(&proc->tep[i].cond_te); + pthread_join(proc->tep[i].pthread_te, NULL); + pthread_mutex_destroy( &proc->tep[i].mutex_te); + pthread_cond_destroy( &proc->tep[i].cond_te); + } } + void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) { nfapi_rx_indication_pdu_t *pdu; @@ -1676,7 +1589,9 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask) { +/* release the harq if its round is >= 'after_rounds' */ +static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int after_rounds) +{ LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; @@ -1699,11 +1614,13 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); - dlsch0_harq->status = SCH_IDLE; - /*if ((dlsch1_harq == NULL)|| - ((dlsch1_harq!=NULL)&& - (dlsch1_harq->status == SCH_IDLE)))*/ - dlsch0->harq_mask &= ~(1<<harq_pid); + if (dlsch0_harq->round >= after_rounds) { + dlsch0_harq->status = SCH_IDLE; + /*if ((dlsch1_harq == NULL)|| + ((dlsch1_harq!=NULL)&& + (dlsch1_harq->status == SCH_IDLE)))*/ + dlsch0->harq_mask &= ~(1<<harq_pid); + } LOG_D(PHY,"Frame %d, subframe %d: Releasing harq %d for UE %x\n",frame,subframe,harq_pid,dlsch0->rnti); } @@ -1724,17 +1641,28 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); - dlsch0_harq->status = SCH_IDLE; - if ((dlsch1_harq == NULL)|| - ((dlsch1_harq!=NULL)&& - (dlsch1_harq->status == SCH_IDLE))) - dlsch0->harq_mask &= ~(1<<harq_pid); + if (dlsch0_harq->round >= after_rounds) { + dlsch0_harq->status = SCH_IDLE; + if ((dlsch1_harq == NULL)|| + ((dlsch1_harq!=NULL)&& + (dlsch1_harq->status == SCH_IDLE))) + dlsch0->harq_mask &= ~(1<<harq_pid); + } } } } } } +static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack) +{ + /* Maximum number of DL transmissions = 4. + * TODO: get the value from configuration. + * If is_ack is true then we release immediately. The value -1 can be used for that. + */ + do_release_harq(eNB, UE_id, tb, frame, subframe, mask, is_ack ? -1 : 4); +} + int getM(PHY_VARS_eNB *eNB,int frame,int subframe) { int M,Mtx=0; @@ -1834,16 +1762,21 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i]; // release DLSCH if needed - if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); + release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); + #if T_TRACER /* TODO: get correct harq pid */ - if (ulsch_harq->o_ACK[i] != 1) - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10])); - else - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10])); + { + int subframe_tx = (subframe+6)%10; + int frame_tx = subframe_tx >= 6 ? (frame+1023)%1024 : frame; + if (ulsch_harq->o_ACK[i] != 1) + T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx][subframe_tx])); + else + T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx][subframe_tx])); + } #endif } } @@ -1860,13 +1793,17 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 2-ulsch_harq->o_ACK[i]; // release DLSCH if needed - if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); - if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); - else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); + /* TODO: review this code, it's most certainly wrong. + * We have to release the proper HARQ in case of ACK or NACK if max retransmission reached. + * Basically, call release_harq with 1 as last argument when ACK and 0 when NACK. + */ + release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); + if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); + else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); else if (M>1 && ulsch_harq->o_ACK[i] == 1) { // spatial bundling - release_harq(eNB,UE_id,0,frame,subframe,1<<i); - release_harq(eNB,UE_id,1,frame,subframe,1<<i); + release_harq(eNB,UE_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1); + release_harq(eNB,UE_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1); } } } @@ -1928,15 +1865,20 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; // release DLSCH if needed - if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + #if T_TRACER - if (harq_ack[0] != 1) - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10])); - else - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10])); + { + int subframe_tx = (subframe+6)%10; + int frame_tx = subframe_tx >= 6 ? (frame+1023)%1024 : frame; + if (harq_ack[0] != 1) + T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx%2][subframe_tx])); + else + T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx%2][subframe_tx])); + } #endif } else if (uci->pucch_fmt == pucch_format1b) { @@ -1948,8 +1890,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; pdu->harq_indication_fdd_rel13.harq_tb_n[1] = harq_ack[1]; // release DLSCH if needed - if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); - if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); } else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); } @@ -1970,7 +1912,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; // release all bundled DLSCH if needed - if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); } else if (uci->pucch_fmt == pucch_format1b) { pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; @@ -1980,8 +1922,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; // release all DLSCH if needed - if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); - if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); } break; case 1: // multiplexing @@ -1993,7 +1935,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; // release all DLSCH if needed - if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); } else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) { pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; @@ -2003,8 +1945,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; // release all DLSCH if needed - if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); - if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); } else { // num_pucch_resources (M) > 1 pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; @@ -2015,8 +1957,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, if (uci->num_pucch_resources == 3) pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2]; if (uci->num_pucch_resources == 4) pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3]; // spatial-bundling in this case so release both HARQ if necessary - release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask); - release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask); + release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */); + release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */); } break; case 2: // special bundling (SR collision) @@ -2030,13 +1972,14 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, case 0: case 4: pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; + /* TODO: release_harq here? this whole code looks suspicious */ break; case 1: // check if M=1,4,7 if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 || tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) { pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - release_harq(eNB,UE_id,0,frame,subframe,0xffff); - release_harq(eNB,UE_id,1,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); }else{ pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; } @@ -2045,8 +1988,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) { pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - release_harq(eNB,UE_id,0,frame,subframe,0xffff); - release_harq(eNB,UE_id,1,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); }else{ pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; } @@ -2055,8 +1998,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) { pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - release_harq(eNB,UE_id,0,frame,subframe,0xffff); - release_harq(eNB,UE_id,1,frame,subframe,0xffff); + release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); }else{ pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; } @@ -2098,7 +2041,7 @@ void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type) +void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { //RX processing for ue-specific resources (i LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; @@ -2145,7 +2088,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->first_run_I0_measurements); int min_I0=1000,max_I0=0; - if ((frame==0) && (subframe==6)) { + if ((frame==0) && (subframe==4)) { for (int i=0;i<eNB->frame_parms.N_RB_UL;i++) { if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2; diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c new file mode 100644 index 0000000000000000000000000000000000000000..0bdbb6060d5c978a936394ad7143eee523692873 --- /dev/null +++ b/openair1/SCHED/prach_procedures.c @@ -0,0 +1,229 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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_procedures_lte_eNB.c + * \brief Implementation of eNB procedures from 36.213 LTE specifications + * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk + * \note + * \warning + */ + +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" +#include "nfapi_interface.h" +#include "fapi_l1.h" +#include "nfapi_pnf.h" +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" + +#include "T.h" + +#include "assertions.h" +#include "msc.h" + +#include <time.h> + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +extern uint32_t nfapi_mode; + +extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); + +void prach_procedures(PHY_VARS_eNB *eNB +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + int br_flag +#endif + ) { + uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4]; + uint16_t i; + int frame,subframe; + +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (br_flag==1) { + subframe = eNB->proc.subframe_prach_br; + frame = eNB->proc.frame_prach_br; + pthread_mutex_lock(&eNB->UL_INFO_mutex); + eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles=0; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + } + else +#endif + { + pthread_mutex_lock(&eNB->UL_INFO_mutex); + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + subframe = eNB->proc.subframe_prach; + frame = eNB->proc.frame_prach; + } + RU_t *ru; + int aa=0; + int ru_aa; + + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); + + + + for (i=0;i<eNB->num_RU;i++) { + ru=eNB->RU_list[i]; + for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) { + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + int ce_level; + + if (br_flag==1) + for (ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; +#endif + } + } + + rx_prach(eNB, + eNB->RU_list[0], + &max_preamble[0], + &max_preamble_energy[0], + &max_preamble_delay[0], + frame, + 0 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,br_flag +#endif + ); + + LOG_D(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", + frame,subframe, + max_preamble[0], + max_preamble_energy[0]/10, + max_preamble_delay[0], + eNB->prach_energy_counter); + +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (br_flag==1) { + + int prach_mask; + + prach_mask = is_prach_subframe(&eNB->frame_parms,eNB->proc.frame_prach_br,eNB->proc.subframe_prach_br); + + eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br; + int ind=0; + int ce_level=0; + /* Save for later, it doesn't work + for (int ind=0,ce_level=0;ce_level<4;ce_level++) { + + if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[ce_level]==1)&& + (prach_mask&(1<<(1+ce_level)) > 0) && // prach is active and CE level has finished its repetitions + (eNB->prach_vars_br.repetition_number[ce_level]== + eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) { + */ + if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]==1){ + if ((eNB->prach_energy_counter == 100) && + (max_preamble_energy[0] > eNB->measurements.prach_I0 + 100)) { + eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles++; + + eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind];// + eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind]; + // note: fid is implicitly 0 here, this is the rule for eMTC RA-RNTI from 36.321, Section 5.1.4 + eNB->preamble_list_br[ind].preamble_rel8.rnti = 1+subframe+(eNB->prach_vars_br.first_frame[ce_level]%40); + eNB->preamble_list_br[ind].instance_length = 0; //don't know exactly what this is + eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type = 1+ce_level; // CE Level + LOG_D(PHY,"Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + ind, + ce_level, + prach_mask, + eNB->preamble_list_br[ind].preamble_rel8.timing_advance, + eNB->preamble_list_br[ind].preamble_rel8.preamble, + eNB->preamble_list_br[ind].preamble_rel8.rnti, + eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type); + } + /* + ind++; + } + } */// ce_level + } + } + else +#endif + + { + if ((eNB->prach_energy_counter == 100) && + (max_preamble_energy[0] > eNB->measurements.prach_I0+100)) { + + LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", + eNB->Mod_id, + eNB->CC_id, + frame, + subframe, + max_preamble[0], + max_preamble_energy[0]/10, + max_preamble_energy[0]%10, + max_preamble_delay[0]); + + T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), + T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; + eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; + eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; + eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; + eNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; + + eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; + eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; + eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; + eNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here + eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; + eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is + + if (nfapi_mode == 1) { // If NFAPI PNF then we need to send the message to the VNF + + LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), + eNB->preamble_list[0].preamble_rel8.timing_advance, + eNB->preamble_list[0].preamble_rel8.preamble, + eNB->preamble_list[0].preamble_rel8.rnti, + eNB->preamble_list[0].preamble_rel13.rach_resource_type); + + oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind); + + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; + } + + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + } // max_preamble_energy > prach_I0 + 100 + else { + eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); + if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",eNB->measurements.prach_I0/10,eNB->measurements.prach_I0%10); + if (eNB->prach_energy_counter < 100) eNB->prach_energy_counter++; + } + } // else br_flag + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); +} diff --git a/openair1/SCHED/pusch_pc.c b/openair1/SCHED/pusch_pc.c deleted file mode 100644 index 5e23f701e0e9ab167caed695b0c4f4dd1e4ab27c..0000000000000000000000000000000000000000 --- a/openair1/SCHED/pusch_pc.c +++ /dev/null @@ -1,272 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 pusch_pc.c - * \brief Implementation of UE PUSCH Power Control procedures from 36.213 LTE specifications (Section - * \author R. Knopp - * \date 2011 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr - * \note - * \warning - */ - -#include "defs.h" -#include "PHY/defs.h" -#include "PHY/LTE_TRANSPORT/proto.h" -#include "PHY/extern.h" - -// This is the formula from Section 5.1.1.1 in 36.213 100*10*log10((2^(MPR*Ks)-1)), where MPR is in the range [0,6] and Ks=1.25 -int16_t hundred_times_delta_TF[100] = {-32768,-1268,-956,-768,-631,-523,-431,-352,-282,-219,-161,-107,-57,-9,36,79,120,159,197,234,269,304,337,370,402,434,465,495,525,555,583,612,640,668,696,723,750,777,803,829,856,881,907,933,958,983,1008,1033,1058,1083,1108,1132,1157,1181,1205,1229,1254,1278,1302,1325,1349,1373,1397,1421,1444,1468,1491,1515,1538,1562,1585,1609,1632,1655,1679,1702,1725,1748,1772,1795,1818,1841,1864,1887,1910,1933,1956,1980,2003,2026,2049,2072,2095,2118,2141,2164,2186,2209,2232,2255}; -uint16_t hundred_times_log10_NPRB[100] = {0,301,477,602,698,778,845,903,954,1000,1041,1079,1113,1146,1176,1204,1230,1255,1278,1301,1322,1342,1361,1380,1397,1414,1431,1447,1462,1477,1491,1505,1518,1531,1544,1556,1568,1579,1591,1602,1612,1623,1633,1643,1653,1662,1672,1681,1690,1698,1707,1716,1724,1732,1740,1748,1755,1763,1770,1778,1785,1792,1799,1806,1812,1819,1826,1832,1838,1845,1851,1857,1863,1869,1875,1880,1886,1892,1897,1903,1908,1913,1919,1924,1929,1934,1939,1944,1949,1954,1959,1963,1968,1973,1977,1982,1986,1991,1995,2000}; -int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) -{ - - uint32_t Nre,sumKr,MPR_x100,Kr,r; - uint16_t beta_offset_pusch; - - DevAssert( UE_id < NUMBER_OF_UE_MAX+1 ); - DevAssert( harq_pid < 8 ); - - Nre = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_initial * - eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12; - - sumKr = 0; - - for (r=0; r<eNB->ulsch[UE_id]->harq_processes[harq_pid]->C; r++) { - if (r<eNB->ulsch[UE_id]->harq_processes[harq_pid]->Cminus) - Kr = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kminus; - else - Kr = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus; - - sumKr += Kr; - } - - if (Nre==0) - return(0); - - MPR_x100 = 100*sumKr/Nre; - // Note: MPR=is the effective spectral efficiency of the PUSCH - // FK 20140908 sumKr is only set after the ulsch_encoding - - beta_offset_pusch = 8; - //(eNB->ulsch[UE_id]->harq_processes[harq_pid]->control_only == 1) ? eNB->ulsch[UE_id]->beta_offset_cqi_times8:8; - - DevAssert( UE_id < NUMBER_OF_UE_MAX ); -//#warning "This condition happens sometimes. Need more investigation" // navid - //DevAssert( MPR_x100/6 < 100 ); - - if (1==1) { //eNB->ul_power_control_dedicated[UE_id].deltaMCS_Enabled == 1) { - // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch) - if (bw_factor == 1) { - uint8_t nb_rb = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb; - return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)) + hundred_times_log10_NPRB[nb_rb-1]; - } else - return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)); - } else { - return(0); - } -} - -int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid) -{ - int16_t UE_id; - if ((RC.eNB == NULL) || (module_idP > RC.nb_inst) || (CC_id > RC.nb_CC[module_idP])) { - LOG_E(PHY,"get_UE_stats: No eNB found (or not allocated) for Mod_id %d,CC_id %d\n",module_idP,CC_id); - return -1; - } - - UE_id = find_ulsch( rnti, RC.eNB[module_idP][CC_id],SEARCH_EXIST); - - if (UE_id == -1) { - // not found - return 0; - } - - return get_hundred_times_delta_IF_eNB( RC.eNB[module_idP][CC_id], UE_id, harq_pid, 0 ); -} - -int16_t get_hundred_times_delta_IF(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t harq_pid) -{ - - uint32_t Nre = 2*ue->ulsch[eNB_id]->harq_processes[harq_pid]->Nsymb_initial * - ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb*12; - - if (Nre==0) - return(0); - - uint32_t MPR_x100 = 100*ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/Nre; - // Note: MPR=is the effective spectral efficiency of the PUSCH - // FK 20140908 sumKr is only set after the ulsch_encoding - - uint16_t beta_offset_pusch = (ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? - ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; - - if (ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled == 1) { - // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch) - return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)); - } else { - return(0); - } -} - - - -uint8_t alpha_lut[8] = {0,40,50,60,70,80,90,100}; - -void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag) -{ - - - uint8_t harq_pid = subframe2harq_pid(&ue->frame_parms, - proc->frame_tx, - proc->subframe_tx); - - uint8_t nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; - int16_t PL; - - - // P_pusch = 10*log10(nb_rb + P_opusch(j)+ alpha(u)*PL + delta_TF(i) + f(i)) - // - // P_opusch(0) = P_oPTR + deltaP_Msg3 if PUSCH is transporting Msg3 - // else - // P_opusch(0) = PO_NOMINAL_PUSCH(j) + P_O_UE_PUSCH(j) - PL = get_PL(ue->Mod_id,ue->CC_id,eNB_id); - - ue->ulsch[eNB_id]->Po_PUSCH = (hundred_times_log10_NPRB[nb_rb-1]+ - get_hundred_times_delta_IF(ue,eNB_id,harq_pid) + - 100*ue->ulsch[eNB_id]->f_pusch)/100; - - if(ue->ulsch_Msg3_active[eNB_id] == 1) { // Msg3 PUSCH - - ue->ulsch[eNB_id]->Po_PUSCH += (get_Po_NOMINAL_PUSCH(ue->Mod_id,0) + PL); - - - LOG_I(PHY,"[UE %d][RAPROC] frame %d, subframe %d: Msg3 Po_PUSCH %d dBm (%d,%d,100*PL=%d,%d,%d)\n", - ue->Mod_id,proc->frame_tx,proc->subframe_tx,ue->ulsch[eNB_id]->Po_PUSCH, - 100*get_Po_NOMINAL_PUSCH(ue->Mod_id,0), - hundred_times_log10_NPRB[nb_rb-1], - 100*PL, - get_hundred_times_delta_IF(ue,eNB_id,harq_pid), - 100*ue->ulsch[eNB_id]->f_pusch); - } else if (j==0) { // SPS PUSCH - } else if (j==1) { // Normal PUSCH - - ue->ulsch[eNB_id]->Po_PUSCH += ((alpha_lut[ue->frame_parms.ul_power_control_config_common.alpha]*PL)/100); - ue->ulsch[eNB_id]->Po_PUSCH += ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; - ue->ulsch[eNB_id]->PHR = ue->tx_power_max_dBm-ue->ulsch[eNB_id]->Po_PUSCH; - - if (ue->ulsch[eNB_id]->PHR < -23) - ue->ulsch[eNB_id]->PHR = -23; - else if (ue->ulsch[eNB_id]->PHR > 40) - ue->ulsch[eNB_id]->PHR = 40; - - LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubframe %d.%d: nb_rb: %d, Po_PUSCH %d dBm : tx power %d, Po_NOMINAL_PUSCH %d,log10(NPRB) %f,PHR %d, PL %d, alpha*PL %f,delta_IF %f,f_pusch %d\n", - ue->Mod_id,harq_pid,proc->frame_tx,proc->subframe_tx,nb_rb, - ue->ulsch[eNB_id]->Po_PUSCH, - ue->tx_power_max_dBm, - ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH, - hundred_times_log10_NPRB[nb_rb-1]/100.0, - ue->ulsch[eNB_id]->PHR, - PL, - alpha_lut[ue->frame_parms.ul_power_control_config_common.alpha]*PL/100.0, - get_hundred_times_delta_IF(ue,eNB_id,harq_pid)/100.0, - ue->ulsch[eNB_id]->f_pusch); - } - -} - -int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id,uint8_t eNB_index) -{ - - return PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->PHR; -} - -// uint8_t eNB_id,uint8_t harq_pid, uint8_t UE_id, -int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs) -{ - - /// The payload + CRC size in bits, "B" - uint32_t B; - /// Number of code segments - uint32_t C; - /// Number of "small" code segments - uint32_t Cminus; - /// Number of "large" code segments - uint32_t Cplus; - /// Number of bits in "small" code segments (<6144) - uint32_t Kminus; - /// Number of bits in "large" code segments (<6144) - uint32_t Kplus; - /// Total number of bits across all segments - uint32_t sumKr; - /// Number of "Filler" bits - uint32_t F; - // num resource elements - uint32_t num_re=0.0; - // num symbols - uint32_t num_symb=0.0; - /// effective spectral efficiency of the PUSCH - uint32_t MPR_x100=0; - /// beta_offset - uint16_t beta_offset_pusch_x8=8; - /// delta mcs - float delta_mcs=0.0; - /// bandwidth factor - float bw_factor=0.0; - - B= tbs+24; - lte_segmentation(NULL, - NULL, - B, - &C, - &Cplus, - &Cminus, - &Kplus, - &Kminus, - &F); - - - sumKr = Cminus*Kminus + Cplus*Kplus; - num_symb = 12-(ncp<<1)-(use_srs==0?0:1); - num_re = num_symb * nb_rb * 12; - - if (num_re == 0) - return(0); - - MPR_x100 = 100*sumKr/num_re; - - if (control_only == 1 ) - beta_offset_pusch_x8=8; // fixme - - //(beta_offset_pusch_x8=ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; - - // if deltamcs_enabledm - delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch_x8)>>3))/100.0); - bw_factor = (hundred_times_log10_NPRB[nb_rb-1]/100.0); -#ifdef DEBUG_SEGMENTATION - printf("estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n", - (int16_t)ceil(delta_mcs + bw_factor), num_re, sumKr, MPR_x100, delta_mcs, bw_factor); -#endif - return (int16_t)ceil(delta_mcs + bw_factor); - -} diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 2c2fe6ecae054e6cfbd50686e3b61ec71b7ee587..5f65f81fbea2aef7e58495ddcd74fcec1c9ccacf 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -30,16 +30,15 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" - +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "SCHED/sched_eNB.h" +#include "PHY/MODULATION/modulation_eNB.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if5_tools.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/mac.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -138,12 +137,22 @@ static void *feptx_thread(void *param) { RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + thread_top_init("feptx_thread",1,85000,120000,500000); + pthread_setname_np( pthread_self(),"feptx processing"); + LOG_I(PHY,"thread feptx created id=%ld\n", syscall(__NR_gettid)); + //CPU_SET(6, &cpuset); + //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + //wait_sync("feptx_thread"); - thread_top_init("feptx_thread",0,870000,1000000,1000000); + while (!oai_exit) { if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break; + //stop_meas(&ru->ofdm_mod_wakeup_stats); feptx0(ru,1); if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break; @@ -152,6 +161,10 @@ static void *feptx_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return NULL; } + /*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.diff_now>30*3000){ + print_meas_now(&ru->ofdm_mod_wakeup_stats,"fep wakeup",stderr); + printf("delay in fep wakeup in frame_tx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx); + }*/ } @@ -168,7 +181,7 @@ void feptx_ofdm_2thread(RU_t *ru) { wait.tv_sec=0; wait.tv_nsec=5000000L; - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); start_meas(&ru->ofdm_mod_stats); if (subframe_select(fp,subframe) == SF_UL) return; @@ -198,17 +211,25 @@ void feptx_ofdm_2thread(RU_t *ru) { exit_fun( "ERROR pthread_cond_signal" ); return; } + //start_meas(&ru->ofdm_mod_wakeup_stats); pthread_mutex_unlock( &proc->mutex_feptx ); } // call first slot in this thread feptx0(ru,0); + start_meas(&ru->ofdm_mod_wait_stats); wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); + stop_meas(&ru->ofdm_mod_wait_stats); + /*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.diff_now>30*3000){ + print_meas_now(&ru->ofdm_mod_wait_stats,"fep wakeup",stderr); + printf("delay in feptx wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx); + }*/ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); stop_meas(&ru->ofdm_mod_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); } @@ -426,12 +447,23 @@ static void *fep_thread(void *param) { RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; - thread_top_init("fep_thread",0,870000,1000000,1000000); + thread_top_init("fep_thread",1,100000,120000,5000000); + pthread_setname_np( pthread_self(),"fep processing"); + LOG_I(PHY,"thread fep created id=%ld\n", syscall(__NR_gettid)); + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + //CPU_SET(2, &cpuset); + //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + //wait_sync("fep_thread"); while (!oai_exit) { - if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break; + if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break; + //stop_meas(&ru->ofdm_demod_wakeup_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 ); fep0(ru,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 ); if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"fep thread")<0) break; if (pthread_cond_signal(&proc->cond_fep) != 0) { @@ -439,6 +471,10 @@ static void *fep_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return NULL; } + /*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){ + print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); + printf("delay in fep wakeup in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); + }*/ } @@ -489,6 +525,7 @@ void ru_fep_full_2thread(RU_t *ru) { wait.tv_sec=0; wait.tv_nsec=5000000L; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); start_meas(&ru->ofdm_demod_stats); if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) { @@ -512,15 +549,23 @@ void ru_fep_full_2thread(RU_t *ru) { exit_fun( "ERROR pthread_cond_signal" ); return; } + //start_meas(&ru->ofdm_demod_wakeup_stats); pthread_mutex_unlock( &proc->mutex_fep ); // call second slot in this symbol fep0(ru,1); + start_meas(&ru->ofdm_demod_wait_stats); wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread"); + stop_meas(&ru->ofdm_demod_wait_stats); + if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){ + print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); + printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); + } stop_meas(&ru->ofdm_demod_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); } @@ -539,6 +584,7 @@ void fep_full(RU_t *ru) { remove_7_5_kHz(ru,proc->subframe_rx<<1); remove_7_5_kHz(ru,1+(proc->subframe_rx<<1)); + for (l=0; l<fp->symbols_per_tti/2; l++) { slot_fep_ul(ru, l, diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/sched_common.h similarity index 62% rename from openair1/SCHED/defs.h rename to openair1/SCHED/sched_common.h index 84b7b46b81336bfc5ee1609c05a8cb642cd4f481..fdf365af1c72587f4506fa906ab860e56bd7c8ba 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/sched_common.h @@ -25,195 +25,11 @@ \email knopp@eurecom.fr */ -#ifndef __openair_SCHED_H__ -#define __openair_SCHED_H__ +#ifndef __openair_SCHED_COMMON_H__ +#define __openair_SCHED_COMMON_H__ -#include "PHY/defs.h" -#include "PHY_INTERFACE/defs.h" - -enum THREAD_INDEX { OPENAIR_THREAD_INDEX = 0, - TOP_LEVEL_SCHEDULER_THREAD_INDEX, - DLC_SCHED_THREAD_INDEX, - openair_SCHED_NB_THREADS - }; // do not modify this line - - -#define OPENAIR_THREAD_PRIORITY 255 - - -#define OPENAIR_THREAD_STACK_SIZE PTHREAD_STACK_MIN //4096 //RTL_PTHREAD_STACK_MIN*6 -//#define DLC_THREAD_STACK_SIZE 4096 //DLC stack size -//#define UE_SLOT_PARALLELISATION - -enum openair_SCHED_STATUS { - openair_SCHED_STOPPED=1, - openair_SCHED_STARTING, - openair_SCHED_STARTED, - openair_SCHED_STOPPING -}; - -enum openair_ERROR { - // HARDWARE CAUSES - openair_ERROR_HARDWARE_CLOCK_STOPPED= 1, - - // SCHEDULER CAUSE - openair_ERROR_OPENAIR_RUNNING_LATE, - openair_ERROR_OPENAIR_SCHEDULING_FAILED, - - // OTHERS - openair_ERROR_OPENAIR_TIMING_OFFSET_OUT_OF_BOUNDS, -}; - -enum openair_SYNCH_STATUS { - openair_NOT_SYNCHED=1, - openair_SYNCHED, - openair_SCHED_EXIT -}; - -enum openair_HARQ_TYPE { - openair_harq_DL = 0, - openair_harq_UL, - openair_harq_RA -}; - -#define DAQ_AGC_ON 1 -#define DAQ_AGC_OFF 0 - - -/** @addtogroup _PHY_PROCEDURES_ - * @{ - */ - - - -/*! \brief Top-level entry routine for eNB procedures. Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required). On odd slots, it generate TX waveform for the following subframe. - @param subframe Index of current subframe (0-9) - @param phy_vars_eNB Pointer to eNB variables on which to act - @param abstraction_flag Indicator of PHY abstraction - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying - @param *phy_vars_rn pointer to RN variables -*/ -void phy_procedures_eNB_lte(uint8_t subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t abstraction_flag, relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn); - -/*! \brief Top-level entry routine for UE procedures. Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required). On odd slots, it generate TX waveform for the following subframe. - @param phy_vars_ue Pointer to UE variables on which to act - @param eNB_id ID of eNB on which to act - @param abstraction_flag Indicator of PHY abstraction - @param mode calibration/debug mode - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying - @param *phy_vars_rn pointer to RN variables -*/ -void phy_procedures_UE_lte(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn); - -#if defined(Rel10) || defined(Rel14) -/*! \brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs. - @param last_slot Index of last slot (0-19) - @param next_slot Index of next_slot (0-19) - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ -int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type); -/*! \brief Top-level entry routine for relay node procedures actinf as UE. This proc will make us of the existing UE procs. - @param last_slot Index of last slot (0-19) - @param next_slot Index of next_slot (0-19) - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ -int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type); -#endif - -/*! \brief Scheduling for UE TX procedures in normal subframes. - @param phy_vars_ue Pointer to UE variables on which to act - @param proc Pointer to RXn-TXnp4 proc information - @param eNB_id Local id of eNB on which to act - @param abstraction_flag Indicator of PHY abstraction - @param mode calib/normal mode - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ -void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type); -/*! \brief Scheduling for UE RX procedures in normal subframes. - @param last_slot Index of last slot (0-19) - @param phy_vars_ue Pointer to UE variables on which to act - @param proc Pointer to RXn_TXnp4 proc information - @param eNB_id Local id of eNB on which to act - @param abstraction_flag Indicator of PHY abstraction - @param mode calibration/debug mode - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying - @param phy_vars_rn pointer to RN variables -*/ -int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn); -int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, - uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode, - relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn); -#ifdef UE_SLOT_PARALLELISATION -void *UE_thread_slot1_dl_processing(void *arg); -#endif - -/*! \brief Scheduling for UE TX procedures in TDD S-subframes. - @param phy_vars_ue Pointer to UE variables on which to act - @param eNB_id Local id of eNB on which to act - @param abstraction_flag Indicator of PHY abstraction - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ -void phy_procedures_UE_S_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type); - -/*! \brief Scheduling for UE RX procedures in TDD S-subframes. - @param phy_vars_ue Pointer to UE variables on which to act - @param eNB_id Local id of eNB on which to act - @param abstraction_flag Indicator of PHY abstraction - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ -void phy_procedures_UE_S_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag, relaying_type_t r_type); - -/*! \brief Scheduling for eNB TX procedures in normal subframes. - @param phy_vars_eNB Pointer to eNB variables on which to act - @param abstraction_flag Indicator of PHY abstraction - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying - @param phy_vars_rn pointer to the RN variables - @param do_meas Do inline timing measurement -*/ -void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn,int do_meas); - -/*! \brief Scheduling for eNB RX UE-specific procedures in normal subframes. - @param phy_vars_eNB Pointer to eNB variables on which to act - @param proc Pointer to RXn-TXnp4 proc information - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ -void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type); - -/*! \brief Scheduling for eNB TX procedures in TDD S-subframes. - @param phy_vars_eNB Pointer to eNB variables on which to act - @param proc Pointer to RXn-TXnp4 proc information - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ - -/*! \brief Scheduling for eNB RX common procedures in normal subframes. - @param phy_vars_eNB Pointer to eNB variables on which to act - @param abstraction_flag Indicator of PHY abstraction -*/ -void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); - -/*! \brief Scheduling for eNB TX procedures in TDD S-subframes. - @param phy_vars_eNB Pointer to eNB variables on which to act - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ - -void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB,relaying_type_t r_type); - -/*! \brief Scheduling for eNB RX procedures in TDD S-subframes. - @param phy_vars_eNB Pointer to eNB variables on which to act - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying -*/ -void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type); - -/*! \brief Scheduling for eNB PRACH RX procedures - @param phy_vars_eNB Pointer to eNB variables on which to act - @param br_flag indicator for eMTC PRACH -*/ -#ifdef Rel14 -void prach_procedures(PHY_VARS_eNB *eNB, - int br_flag); -#else -void prach_procedures(PHY_VARS_eNB *eNB); -#endif +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" /*! \brief Function to compute subframe Number(DL and S) as a function of Frame type and TDD Configuration @param frame_parms Pointer to DL frame parameter descriptor @@ -238,13 +54,8 @@ lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) */ dci_detect_mode_t dci_detect_mode_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); -/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index. Same as subframe_select, except that it uses the Mod_id and is provided as a service to the MAC scheduler. - @param Mod_id Index of eNB - @param CC_id Component Carrier Index - @param subframe Subframe index - @returns Subframe type (DL,UL,S) -*/ -lte_subframe_t get_subframe_direction(uint8_t Mod_id, uint8_t CC_id,uint8_t subframe); + + /*! \brief Function to indicate PHICH transmission subframes. Implements Table 9.1.2-1 for TDD. @param frame_parms Pointer to DL frame parameter descriptor diff --git a/openair1/SCHED/extern.h b/openair1/SCHED/sched_common_extern.h similarity index 88% rename from openair1/SCHED/extern.h rename to openair1/SCHED/sched_common_extern.h index b1e8df67ef86a5bb11c9cf9bb2d5dd57374d2eee..b5edc6f38e390dc027a1f3699c2a05c157778092 100644 --- a/openair1/SCHED/extern.h +++ b/openair1/SCHED/sched_common_extern.h @@ -24,16 +24,7 @@ #ifndef __SCHED_EXTERN_H__ #define __SCHED_EXTERN_H__ -#include "defs.h" -//#include "dlc_engine.h" - -extern int openair_sched_status; - -//extern int exit_PHY; -//extern int exit_PHY_ack; - -extern int synch_wait_cnt; - +#include "sched_eNB.h" extern int16_t hundred_times_delta_TF[100]; extern uint16_t hundred_times_log10_NPRB[100]; diff --git a/openair1/SCHED/sched_common_vars.h b/openair1/SCHED/sched_common_vars.h new file mode 100644 index 0000000000000000000000000000000000000000..2cae2aa96f21bc49bc32dc156ac688b8c22f72eb --- /dev/null +++ b/openair1/SCHED/sched_common_vars.h @@ -0,0 +1,28 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include <stdint.h> + + +// This is the formula from Section 5.1.1.1 in 36.213 100*10*log10((2^(MPR*Ks)-1)), where MPR is in the range [0,6] and Ks=1.25 +int16_t hundred_times_delta_TF[100] = {-32768,-1268,-956,-768,-631,-523,-431,-352,-282,-219,-161,-107,-57,-9,36,79,120,159,197,234,269,304,337,370,402,434,465,495,525,555,583,612,640,668,696,723,750,777,803,829,856,881,907,933,958,983,1008,1033,1058,1083,1108,1132,1157,1181,1205,1229,1254,1278,1302,1325,1349,1373,1397,1421,1444,1468,1491,1515,1538,1562,1585,1609,1632,1655,1679,1702,1725,1748,1772,1795,1818,1841,1864,1887,1910,1933,1956,1980,2003,2026,2049,2072,2095,2118,2141,2164,2186,2209,2232,2255}; +uint16_t hundred_times_log10_NPRB[100] = {0,301,477,602,698,778,845,903,954,1000,1041,1079,1113,1146,1176,1204,1230,1255,1278,1301,1322,1342,1361,1380,1397,1414,1431,1447,1462,1477,1491,1505,1518,1531,1544,1556,1568,1579,1591,1602,1612,1623,1633,1643,1653,1662,1672,1681,1690,1698,1707,1716,1724,1732,1740,1748,1755,1763,1770,1778,1785,1792,1799,1806,1812,1819,1826,1832,1838,1845,1851,1857,1863,1869,1875,1880,1886,1892,1897,1903,1908,1913,1919,1924,1929,1934,1939,1944,1949,1954,1959,1963,1968,1973,1977,1982,1986,1991,1995,2000}; + diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h new file mode 100644 index 0000000000000000000000000000000000000000..3d4fb821c3eae2bffc7441dde051fd7be315420e --- /dev/null +++ b/openair1/SCHED/sched_eNB.h @@ -0,0 +1,227 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +/* + \author R. Knopp, F. Kaltenberger + \company EURECOM + \email knopp@eurecom.fr +*/ + +#ifndef __openair_SCHED_ENB_H__ +#define __openair_SCHED_ENB_H__ + +#include "PHY/defs_eNB.h" +#include "PHY_INTERFACE/phy_interface.h" +#include "sched_common.h" + +enum THREAD_INDEX { OPENAIR_THREAD_INDEX = 0, + TOP_LEVEL_SCHEDULER_THREAD_INDEX, + DLC_SCHED_THREAD_INDEX, + openair_SCHED_NB_THREADS + }; // do not modify this line + + +#define OPENAIR_THREAD_PRIORITY 255 + + +#define OPENAIR_THREAD_STACK_SIZE PTHREAD_STACK_MIN //4096 //RTL_PTHREAD_STACK_MIN*6 +//#define DLC_THREAD_STACK_SIZE 4096 //DLC stack size +//#define UE_SLOT_PARALLELISATION + +enum openair_SCHED_STATUS { + openair_SCHED_STOPPED=1, + openair_SCHED_STARTING, + openair_SCHED_STARTED, + openair_SCHED_STOPPING +}; + +enum openair_ERROR { + // HARDWARE CAUSES + openair_ERROR_HARDWARE_CLOCK_STOPPED= 1, + + // SCHEDULER CAUSE + openair_ERROR_OPENAIR_RUNNING_LATE, + openair_ERROR_OPENAIR_SCHEDULING_FAILED, + + // OTHERS + openair_ERROR_OPENAIR_TIMING_OFFSET_OUT_OF_BOUNDS, +}; + +enum openair_SYNCH_STATUS { + openair_NOT_SYNCHED=1, + openair_SYNCHED, + openair_SCHED_EXIT +}; + +enum openair_HARQ_TYPE { + openair_harq_DL = 0, + openair_harq_UL, + openair_harq_RA +}; + +#define DAQ_AGC_ON 1 +#define DAQ_AGC_OFF 0 + + +/** @addtogroup _PHY_PROCEDURES_ + * @{ + */ + + + +/*! \brief Scheduling for eNB TX procedures in normal subframes. + @param phy_vars_eNB Pointer to eNB variables on which to act + @param abstraction_flag Indicator of PHY abstraction + @param do_meas Do inline timing measurement +*/ +void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,int do_meas); + +/*! \brief Scheduling for eNB RX UE-specific procedures in normal subframes. + @param phy_vars_eNB Pointer to eNB variables on which to act + @param proc Pointer to RXn-TXnp4 proc information +*/ +void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); + +/*! \brief Scheduling for eNB TX procedures in TDD S-subframes. + @param phy_vars_eNB Pointer to eNB variables on which to act + @param proc Pointer to RXn-TXnp4 proc information + @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying +*/ + +/*! \brief Scheduling for eNB RX common procedures in normal subframes. + @param phy_vars_eNB Pointer to eNB variables on which to act + @param abstraction_flag Indicator of PHY abstraction +*/ +void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); + +/*! \brief Scheduling for eNB TX procedures in TDD S-subframes. + @param phy_vars_eNB Pointer to eNB variables on which to act +*/ + +void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB); + +/*! \brief Scheduling for eNB RX procedures in TDD S-subframes. + @param phy_vars_eNB Pointer to eNB variables on which to act +*/ +void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); + +/*! \brief Scheduling for eNB PRACH RX procedures + @param phy_vars_eNB Pointer to eNB variables on which to act + @param br_flag indicator for eMTC PRACH +*/ +#ifdef Rel14 +void prach_procedures(PHY_VARS_eNB *eNB, + int br_flag); +#else +void prach_procedures(PHY_VARS_eNB *eNB); +#endif + +/*! \brief Function to compute timing of Msg3 transmission on UL-SCH (first UE transmission in RA procedure). This implements the timing in paragraph a) from Section 6.1.1 in 36.213 (p. 17 in version 8.6). Used by eNB upon transmission of random-access response (RA_RNTI) to program corresponding ULSCH reception procedure. Used by UE upon reception of random-access response (RA_RNTI) to program corresponding ULSCH transmission procedure. This does not support the UL_delay field in RAR (always assumed to be 0). + @param frame_parms Pointer to DL frame parameter descriptor + @param current_subframe Index of subframe where RA_RNTI was received + @param current_frame Index of frame where RA_RNTI was received + @param frame Frame index where Msg3 is to be transmitted (n+6 mod 10 for FDD, different for TDD) + @param subframe subframe index where Msg3 is to be transmitted (n, n+1 or n+2) +*/ +void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t current_subframe, + uint32_t current_frame, + uint32_t *frame, + uint8_t *subframe); + +/*! \brief Function to compute timing of Msg3 retransmission on UL-SCH (first UE transmission in RA procedure). + @param frame_parms Pointer to DL frame parameter descriptor + @param current_subframe Index of subframe where RA_RNTI was received + @param current_frame Index of frame where RA_RNTI was received + @param frame Frame index where Msg3 is to be transmitted (n+6 mod 10 for FDD, different for TDD) + @param subframe subframe index where Msg3 is to be transmitted (n, n+1 or n+2) +*/ +void get_Msg3_alloc_ret(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t current_subframe, + uint32_t current_frame, + uint32_t *frame, + uint8_t *subframe); + +/*! \brief Get ULSCH harq_pid for Msg3 from RAR subframe. This returns n+k mod 10 (k>6) and corresponds to the rule in Section 6.1.1 from 36.213 + @param frame_parms Pointer to DL Frame Parameters + @param frame Frame index + @param current_subframe subframe of RAR transmission + @returns harq_pid (0 ... 7) + */ +uint8_t get_Msg3_harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t current_subframe); + +/*! \brief Get ULSCH harq_pid from PHICH subframe + @param frame_parms Pointer to DL Frame Parameters + @param subframe subframe of PHICH + @returns harq_pid (0 ... 7) + */ + +/*! \brief Function to indicate failure of contention resolution or RA procedure. It places the UE back in PRACH mode. + @param Mod_id Instance index of UE + @param CC_id Component Carrier Index + @param eNB_index Index of eNB + */ +void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + +/*! \brief Indicates the SR TXOp in current subframe for eNB and particular UE index. Implements Table 10.1-5 from 36.213. + @param phy_vars_eNB Pointer to eNB variables + @param UE_id ID of UE which may be issuing the SR + @returns 1 if TXOp is active. +*/ +uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id); + +int8_t find_ue_dlsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); +int8_t find_ue_ulsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); + + + + + +void schedule_response(Sched_Rsp_t *Sched_INFO); + +LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti); + +/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index. Same as subframe_select, except that it uses the Mod_id and is provided as a service to the MAC scheduler. + @param Mod_id Index of eNB + @param CC_id Component Carrier Index + @param subframe Subframe index + @returns Subframe type (DL,UL,S) +*/ +lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subframe); + + +int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor); + +int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid); + +int16_t get_target_pusch_rx_power(module_id_t module_idP, uint8_t CC_id); +int16_t get_target_pucch_rx_power(module_id_t module_idP, uint8_t CC_id); + +int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx); + +void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); + +/*@}*/ + + +#endif + + diff --git a/openair1/SCHED_NBIOT/README b/openair1/SCHED_NBIOT/README new file mode 100644 index 0000000000000000000000000000000000000000..319372ee93aa05bec7537d2b8c771fad0c7cb854 --- /dev/null +++ b/openair1/SCHED_NBIOT/README @@ -0,0 +1 @@ +213 procedures for NB-IoT eNB diff --git a/openair1/SCHED_NR/README b/openair1/SCHED_NR/README new file mode 100644 index 0000000000000000000000000000000000000000..8814a972b0e5a84dbb757a8769d485afb74ec131 --- /dev/null +++ b/openair1/SCHED_NR/README @@ -0,0 +1 @@ +213/214 procedures for NR gNB diff --git a/openair1/SCHED_NR_UE/README b/openair1/SCHED_NR_UE/README new file mode 100644 index 0000000000000000000000000000000000000000..b2bc9d09b8ae274660cf13da0636158b31811e57 --- /dev/null +++ b/openair1/SCHED_NR_UE/README @@ -0,0 +1 @@ +213/214 procedures for NR UE diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c similarity index 96% rename from openair1/SCHED/phy_procedures_lte_ue.c rename to openair1/SCHED_UE/phy_procedures_lte_ue.c index 4f24b2745d597ccfa4789aa5a4ed0973d819442b..8e08050a5b27a9faafc578cad2ac6b89f1b111ec 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -33,22 +33,23 @@ #define _GNU_SOURCE #include "assertions.h" -#include "defs.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" #include <sched.h> #include "targets/RT/USER/lte-softmodem.h" -#define DEBUG_PHY_PROC +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "SCHED_UE/sched_UE.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" + +//#define DEBUG_PHY_PROC #ifndef PUCCH #define PUCCH #endif -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/mac.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -58,13 +59,13 @@ # include "intertask_interface.h" #endif -#include "PHY/defs.h" +#include "PHY/defs_UE.h" -#include "PHY/CODING/extern.h" +#include "PHY/CODING/coding_extern.h" #include "T.h" -#include "PHY/TOOLS/defs.h" +#include "PHY/TOOLS/tools_defs.h" #define DLSCH_RB_ALLOC 0x1fbf // skip DC RB (total 23/25 RBs) #define DLSCH_RB_ALLOC_12 0x0aaa // skip DC RB (total 23/25 RBs) @@ -81,6 +82,7 @@ extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; #endif +//#define UE_DEBUG_TRACE 1 void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid) { @@ -505,6 +507,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id { int Mod_id = ue->Mod_id; int CC_id = ue->CC_id; + // Panos: Substitute call to ue_get_SR() with the filled ue_SR_config->SR_payload (0, or 1). SR_payload = ue_get_SR(Mod_id, CC_id, frame_tx, @@ -1265,7 +1268,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt } //#endif - if ((frame_tx%100) == 0) +// 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", ue->Mod_id,frame_tx,subframe_tx, ulsch_start, @@ -1287,16 +1290,25 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt nsymb, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); - else + else { normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - dummy_tx_buffer, + dummy_tx_buffer, #else - &ue->common_vars.txdata[aa][ulsch_start], + &ue->common_vars.txdata[aa][ulsch_start], #endif - nsymb, - &ue->frame_parms); + nsymb>>1, + &ue->frame_parms); + normal_prefix_mod(&ue->common_vars.txdataF[aa][((subframe_tx*nsymb)+(nsymb>>1))*frame_parms->ofdm_symbol_size], +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + dummy_tx_buffer+(frame_parms->samples_per_tti>>1), +#else + &ue->common_vars.txdata[aa][ulsch_start+(frame_parms->samples_per_tti>>1)], +#endif + nsymb>>1, + &ue->frame_parms); + } #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) apply_7_5_kHz(ue,dummy_tx_buffer,0); @@ -1312,13 +1324,13 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt for (k=ulsch_start,l=0; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) { - ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4; + ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]; + ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]; } for (k=0; k<overflow; k++,l++) { - ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4; + ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]; + ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]; } #if defined(EXMIMO) // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on @@ -1372,14 +1384,13 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin if (ue->mac_enabled==1){ // ask L2 for RACH transport if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { - LOG_D(PHY,"Getting PRACH resources\n"); + //LOG_D(PHY,"Getting PRACH resources\n"); ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id, ue->CC_id, frame_tx, eNB_id, subframe_tx); - LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]); } } @@ -1401,7 +1412,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->prach_resources[eNB_id]->ra_PreambleIndex = 19; } - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", + LOG_D(PHY,"[UE %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", ue->Mod_id, frame_tx, subframe_tx, @@ -1444,38 +1455,34 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->tx_power_dBm[subframe_tx], dB_fixed(prach_power), ue->prach_vars[eNB_id]->amp); - } else { - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1; - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex; - } - - if (ue->mac_enabled==1){ - Msg1_transmitted(ue->Mod_id, - ue->CC_id, - frame_tx, - eNB_id); - } - - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", - ue->Mod_id,frame_tx,subframe_tx,eNB_id, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id), - get_PL(ue->Mod_id,ue->CC_id,eNB_id)); - - - - // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue - if (mode == calib_prach_tx) - ue->prach_resources[eNB_id]=NULL; - LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n", - ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt); + if (ue->mac_enabled==1){ + Msg1_transmitted(ue->Mod_id, + ue->CC_id, + frame_tx, + eNB_id); + } + + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", + ue->Mod_id,frame_tx,subframe_tx,eNB_id, + ue->prach_resources[eNB_id]->ra_PreambleIndex, + ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id), + get_PL(ue->Mod_id,ue->CC_id,eNB_id)); + + + + // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue + if (mode == calib_prach_tx) + ue->prach_resources[eNB_id]=NULL; - ue->prach_cnt++; + LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n", + ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt); - if (ue->prach_cnt==3) - ue->generate_prach=0; + ue->prach_cnt++; + if (ue->prach_cnt==3) + ue->generate_prach=0; + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); } @@ -1507,18 +1514,21 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB frame_tx, subframe_tx); + LOG_D(PHY,"Frame %d, Subframe %d : ue_uespec_procedures, harq_pid %d => subframe_scheduling %d\n", + frame_tx,subframe_tx,harq_pid, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag); if (ue->mac_enabled == 1) { - if ((ue->ulsch_Msg3_active[eNB_id] == 1) && - (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) && - (ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3 + if ((ue->ulsch_Msg3_active[eNB_id] == 1) && + (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) && + (ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3 ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) - generate_ue_ulsch_params_from_rar(ue, - proc, - eNB_id); + generate_ue_ulsch_params_from_rar(ue, + proc, + eNB_id); ue->ulsch[eNB_id]->power_offset = 14; LOG_D(PHY,"[UE %d][RAPROC] Frame %d: Setting Msg3_flag in subframe %d, for harq_pid %d\n", @@ -1588,7 +1598,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1)) { - LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); + // LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; } @@ -1661,7 +1671,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB #ifdef UE_DEBUG_TRACE - LOG_I(PHY, + LOG_D(PHY, "[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, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx, @@ -1720,7 +1730,6 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB stop_meas(&ue->phy_proc_tx); printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); #endif - return; #if UE_TIMING_TRACE stop_meas(&ue->ulsch_encoding_stats); @@ -1744,6 +1753,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) { //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) { access_mode=SCHEDULED_ACCESS; + ue_get_sdu(Mod_id, CC_id, frame_tx, @@ -1825,7 +1835,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #ifdef UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); #endif #if UE_TIMING_TRACE @@ -1850,6 +1860,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB #if UE_TIMING_TRACE stop_meas(&ue->ulsch_modulation_stats); #endif + } if (abstraction_flag==1) { @@ -2068,10 +2079,10 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin (bundling_flag==bundling) || ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) { format = pucch_format1a; - LOG_D(PHY,"[UE] PUCCH 1a\n"); + // LOG_D(PHY,"[UE] PUCCH 1a\n"); } else { format = pucch_format1b; - LOG_D(PHY,"[UE] PUCCH 1b\n"); + // LOG_D(PHY,"[UE] PUCCH 1b\n"); } // Part - I @@ -2186,20 +2197,20 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #ifdef UE_DEBUG_TRACE if(format == pucch_format1) - { - LOG_I(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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx%1024, subframe_tx, - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, - Po_PUCCH); + { + 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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx%1024, 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_I(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", + 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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, @@ -2212,7 +2223,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin Po_PUCCH, tx_amp); } else { - LOG_I(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", + 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[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, @@ -2279,7 +2290,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif #ifdef UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", + LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", Mod_id, ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, @@ -2322,7 +2333,28 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } -void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type) { +void phy_procedures_UE_SL_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) { + + int subframe_tx = proc->subframe_tx; + int frame_tx = proc->frame_tx; + SLSS_t *slss; + SLDCH_t *sldch; + SLSCH_t *slsch; + + LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx); + + // check for SLBCH/SLSS + if ((slss = ue_get_slss(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slss(ue,slss,frame_tx,subframe_tx); + + // check for SLDCH + if ((sldch = ue_get_sldch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_sldch(ue,sldch,frame_tx,subframe_tx); + + // check for SLSCH + if ((slsch = ue_get_slsch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slsch(ue,slsch,frame_tx,subframe_tx); + +} + +void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) { LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; @@ -2365,6 +2397,8 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag); + LOG_D(PHY,"ULPOWERS After ulsch_uespec_procedures : ue->tx_power_dBm[%d]=%d, NPRB %d\n", + subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_total_RE[subframe_tx]); } if (ue->UE_mode[eNB_id] == PUSCH) { @@ -2439,7 +2473,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui #endif } -void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type) +void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag) { int aa;//i,aa; LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; @@ -2714,6 +2748,7 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin ue->pbch_vars[eNB_id]->pdu_errors_conseq++; ue->pbch_vars[eNB_id]->pdu_errors++; + // Panos: Substitute call to rrc_out_of_sync_ind() with fill_bch_incication(sync=0). if (ue->mac_enabled == 1) rrc_out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id); else AssertFatal(ue->pbch_vars[eNB_id]->pdu_errors_conseq<100, "More that 100 consecutive PBCH errors! Exiting!\n"); @@ -2734,6 +2769,8 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); } + + int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag) { @@ -2757,15 +2794,17 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint subframe_rx, eNB_id, ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, - ue->high_speed_flag, - ue->is_secondary_ue); + ue->high_speed_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN); - //printf("Decode SIB frame param agregation + DCI %d %d \n",agregationLevel,dciFormat); - + /*printf("Decode SIB frame param aggregation + DCI %d %d, num_pdcch_symbols %d\n", + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); + */ //agregation level == FF means no configuration on if(ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB) { @@ -2883,7 +2922,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint // we received a CRNTI, so we're in PUSCH if (ue->UE_mode[eNB_id] != PUSCH) { #ifdef DEBUG_PHY_PROC - LOG_I(PHY,"[UE %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti); + LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti); #endif //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); @@ -2900,7 +2939,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #ifdef DEBUG_PHY_PROC - LOG_I(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); + LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); #endif if (generate_ue_dlsch_params_from_dci(frame_rx, @@ -2921,7 +2960,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint ue->dlsch_SI_received[eNB_id]++; - LOG_I(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); + LOG_D(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); } @@ -2931,7 +2970,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { #ifdef DEBUG_PHY_PROC - LOG_I(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); + LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); #endif @@ -2963,7 +3002,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (dci_alloc_rx[i].format == format1A)) { #ifdef DEBUG_PHY_PROC - LOG_I(PHY,"[UE %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i); + LOG_D(PHY,"[UE %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i); #endif @@ -3029,7 +3068,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS)); #endif #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); + LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); #endif } @@ -3072,7 +3111,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint else { #ifdef DEBUG_PHY_PROC - LOG_I(PHY,"[UE %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti, + LOG_D(PHY,"[UE %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, ue->ulsch[eNB_id]->cba_rnti[0], dci_alloc_rx[i].format); @@ -3095,7 +3134,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs int subframe_rx = proc->subframe_rx; int frame_rx = proc->frame_rx; int pmch_mcs=-1; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int CC_id = ue->CC_id; #endif uint8_t sync_area=255; @@ -3104,11 +3143,11 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs int ret=0; if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { - LOG_D(PHY,"ue calling pmch subframe ..\n "); + // LOG_D(PHY,"ue calling pmch subframe ..\n "); LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) pmch_mcs = ue_query_mch(ue->Mod_id, CC_id, @@ -3199,7 +3238,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs // if (subframe_rx==9) // mac_xface->macphy_exit("Why are we exiting here?"); } else { // decoding successful -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mcch_active == 1) { ue_send_mch_sdu(ue->Mod_id, @@ -3222,7 +3261,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs } -#endif // Rel10 || Rel14 +#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) } // decoding sucessful } // pmch_mcs>=0 } // is_pmch_subframe=true @@ -3384,6 +3423,7 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo subframe_rx, ue->prach_resources[eNB_id]->ra_PreambleIndex); + // Panos: Substitute call to ue_process_rar() with call to fill_dlsch_rar_indication() timing_advance = ue_process_rar(ue->Mod_id, ue->CC_id, frame_rx, @@ -3714,6 +3754,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, switch (pdsch) { case PDSCH: + // Panos: Substitute call to ue_send_sdu() with call to fill_dlsch_indication() ue_send_sdu(ue->Mod_id, CC_id, frame_rx, @@ -3723,6 +3764,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, eNB_id); break; case SI_PDSCH: + // Panos: Substitute call with call to fill_dlsch_indication() ue_decode_si(ue->Mod_id, CC_id, frame_rx, @@ -3731,7 +3773,8 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); break; case P_PDSCH: - ue_decode_p(ue->Mod_id, + // Panos: Substitute call with call to fill_dlsch_indication() + ue_decode_p(ue->Mod_id, CC_id, frame_rx, eNB_id, @@ -3739,6 +3782,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); break; case RA_PDSCH: + // Panos: Substitute with call to fill_dlsch_rar_indication() process_rar(ue,proc,eNB_id,mode,abstraction_flag); break; case PDSCH1: @@ -3760,7 +3804,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(is_cw1_active) { if (ret1 == (1+dlsch0->max_turbo_iterations)) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3768,7 +3812,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[harq_pid]->TBS); } else { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -4125,8 +4169,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { #ifdef UE_SLOT_PARALLELISATION int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, - uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode, - relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) { + uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { int l,l2; int pmch_flag=0; @@ -4150,7 +4193,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr // start timers #ifdef UE_DEBUG_TRACE - LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); #endif #if UE_TIMING_TRACE @@ -4176,8 +4219,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr } #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", - (r_type == multicast_relay) ? "RN/UE" : "UE", + LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", ue->Mod_id,frame_rx, subframe_rx); #endif @@ -4641,9 +4683,13 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr #endif +void phy_procedures_UE_SL_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) { + + +} + int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, - uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode, - relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) { + uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { int l,l2; int pilot1; @@ -4692,8 +4738,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, } #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", - (r_type == multicast_relay) ? "RN/UE" : "UE", + LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", ue->Mod_id,frame_rx, subframe_rx); #endif @@ -5118,38 +5163,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, return (0); } -#if defined(Rel10) || defined(Rel14) - -int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type) -{ - int do_proc =0; // do nothing by default - switch(r_type) { - case no_relay: - do_proc=no_relay; // perform the normal UE operation - break; - - case multicast_relay: - if (slot_rx > 12) - do_proc = 0; // do nothing - else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12) - do_proc = multicast_relay ; // do PHY procedures UE RX - - break; - - default: // should'not be here - LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type); - do_proc= 0; - break; - } - - return do_proc; -} -#endif - -void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode, - relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn) +void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { #if defined(ENABLE_ITTI) MessageDef *msg_p; @@ -5211,30 +5227,22 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)|| (ue->frame_parms.frame_type == FDD)) { - phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode,r_type); + phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode); } if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) || - (ue->frame_parms.frame_type == FDD)) { -#if defined(Rel10) || defined(Rel14) - - if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 ) -#endif - phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type,phy_vars_rn); + (ue->frame_parms.frame_type == FDD)) { + phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode); } if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) && (slot==1)) { - phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag,r_type); + phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag); } if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) && - (slot==0)) { -#if defined(Rel10) || defined(Rel14) - - if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 ) -#endif - phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type,phy_vars_rn); + (slot==0)) { + phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode); } if (ue->mac_enabled==1) { diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED_UE/pucch_pc.c similarity index 95% rename from openair1/SCHED/pucch_pc.c rename to openair1/SCHED_UE/pucch_pc.c index f01d0d96dd7df5ddbc65cc8270d0ea4d760e5b43..f03cd93d34995b4313c1104aebd30f439b6afc8f 100644 --- a/openair1/SCHED/pucch_pc.c +++ b/openair1/SCHED_UE/pucch_pc.c @@ -30,10 +30,11 @@ * \warning */ -#include "PHY/defs.h" -#include "SCHED/defs.h" -#include "PHY/LTE_TRANSPORT/proto.h" -#include "PHY/extern.h" +#include "PHY/defs_UE.h" +#include "SCHED_UE/sched_UE.h" +#include "SCHED/sched_common_extern.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt) { diff --git a/openair1/SCHED_UE/pusch_pc.c b/openair1/SCHED_UE/pusch_pc.c new file mode 100644 index 0000000000000000000000000000000000000000..90c17099a04634f2193c3a73913affa40b2b0c51 --- /dev/null +++ b/openair1/SCHED_UE/pusch_pc.c @@ -0,0 +1,138 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 pusch_pc.c + * \brief Implementation of UE PUSCH Power Control procedures from 36.213 LTE specifications (Section + * \author R. Knopp + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ + +#include "sched_UE.h" +#include "SCHED/sched_common_extern.h" +#include "PHY/defs_UE.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" + +extern uint8_t nfapi_mode; + +int16_t get_hundred_times_delta_IF(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t harq_pid) +{ + + uint32_t Nre = 2*ue->ulsch[eNB_id]->harq_processes[harq_pid]->Nsymb_initial * + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb*12; + + if (Nre==0) + return(0); + + uint32_t MPR_x100 = 100*ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/Nre; + // Note: MPR=is the effective spectral efficiency of the PUSCH + // FK 20140908 sumKr is only set after the ulsch_encoding + + uint16_t beta_offset_pusch = (ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? + ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; + + if (ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled == 1) { + // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch) + return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)); + } else { + return(0); + } +} + + + +uint8_t alpha_lut[8] = {0,40,50,60,70,80,90,100}; + +void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag) +{ + + + uint8_t harq_pid = subframe2harq_pid(&ue->frame_parms, + proc->frame_tx, + proc->subframe_tx); + + uint8_t nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; + int16_t PL; + + + // P_pusch = 10*log10(nb_rb + P_opusch(j)+ alpha(u)*PL + delta_TF(i) + f(i)) + // + // P_opusch(0) = P_oPTR + deltaP_Msg3 if PUSCH is transporting Msg3 + // else + // P_opusch(0) = PO_NOMINAL_PUSCH(j) + P_O_UE_PUSCH(j) + PL = get_PL(ue->Mod_id,ue->CC_id,eNB_id); + + ue->ulsch[eNB_id]->Po_PUSCH = (hundred_times_log10_NPRB[nb_rb-1]+ + get_hundred_times_delta_IF(ue,eNB_id,harq_pid) + + 100*ue->ulsch[eNB_id]->f_pusch)/100; + + if(ue->ulsch_Msg3_active[eNB_id] == 1) { // Msg3 PUSCH + + ue->ulsch[eNB_id]->Po_PUSCH += (get_Po_NOMINAL_PUSCH(ue->Mod_id,0) + PL); + + + LOG_I(PHY,"[UE %d][RAPROC] frame %d, subframe %d: Msg3 Po_PUSCH %d dBm (%d,%d,100*PL=%d,%d,%d)\n", + ue->Mod_id,proc->frame_tx,proc->subframe_tx,ue->ulsch[eNB_id]->Po_PUSCH, + 100*get_Po_NOMINAL_PUSCH(ue->Mod_id,0), + hundred_times_log10_NPRB[nb_rb-1], + 100*PL, + get_hundred_times_delta_IF(ue,eNB_id,harq_pid), + 100*ue->ulsch[eNB_id]->f_pusch); + } else if (j==0) { // SPS PUSCH + } else if (j==1) { // Normal PUSCH + + ue->ulsch[eNB_id]->Po_PUSCH += ((alpha_lut[ue->frame_parms.ul_power_control_config_common.alpha]*PL)/100); + ue->ulsch[eNB_id]->Po_PUSCH += ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; + ue->ulsch[eNB_id]->PHR = ue->tx_power_max_dBm-ue->ulsch[eNB_id]->Po_PUSCH; + + if (ue->ulsch[eNB_id]->PHR < -23) + ue->ulsch[eNB_id]->PHR = -23; + else if (ue->ulsch[eNB_id]->PHR > 40) + ue->ulsch[eNB_id]->PHR = 40; + + LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubframe %d.%d: nb_rb: %d, Po_PUSCH %d dBm : tx power %d, Po_NOMINAL_PUSCH %d,log10(NPRB) %f,PHR %d, PL %d, alpha*PL %f,delta_IF %f,f_pusch %d\n", + ue->Mod_id,harq_pid,proc->frame_tx,proc->subframe_tx,nb_rb, + ue->ulsch[eNB_id]->Po_PUSCH, + ue->tx_power_max_dBm, + ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH, + hundred_times_log10_NPRB[nb_rb-1]/100.0, + ue->ulsch[eNB_id]->PHR, + PL, + alpha_lut[ue->frame_parms.ul_power_control_config_common.alpha]*PL/100.0, + get_hundred_times_delta_IF(ue,eNB_id,harq_pid)/100.0, + ue->ulsch[eNB_id]->f_pusch); + } + +} + +int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id,uint8_t eNB_index) +{ + if(nfapi_mode!=3) + return PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->PHR; + else + return 40; // For nfapi_mode=3 consider ideal conditions +} diff --git a/openair1/SCHED_UE/sched_UE.h b/openair1/SCHED_UE/sched_UE.h new file mode 100644 index 0000000000000000000000000000000000000000..32702b114893329bf0db88291e2df50be8661a34 --- /dev/null +++ b/openair1/SCHED_UE/sched_UE.h @@ -0,0 +1,288 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +/* + \author R. Knopp, F. Kaltenberger + \company EURECOM + \email knopp@eurecom.fr +*/ + +#ifndef __openair_SCHED_UE_H__ +#define __openair_SCHED_UE_H__ + +#include "PHY/defs_UE.h" +#include "../SCHED/sched_common.h" + +/*! \brief Scheduling for UE TX procedures in normal subframes. + @param phy_vars_ue Pointer to UE variables on which to act + @param proc Pointer to RXn-TXnp4 proc information + @param eNB_id Local id of eNB on which to act + @param abstraction_flag Indicator of PHY abstraction + @param mode calib/normal mode + @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying +*/ +void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode); +/*! \brief Scheduling for UE RX procedures in normal subframes. + @param last_slot Index of last slot (0-19) + @param phy_vars_ue Pointer to UE variables on which to act + @param proc Pointer to RXn_TXnp4 proc information + @param eNB_id Local id of eNB on which to act + @param abstraction_flag Indicator of PHY abstraction + @param mode calibration/debug mode + @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying + @param phy_vars_rn pointer to RN variables +*/ +int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode); + +/*! \brief Scheduling for UE Sidelink RX procedures in normal subframes. + @param ue Pointer to UE variables on which to act + @param proc Pointer to RXn_TXnp4 proc information +*/ +void phy_procedures_UE_SL_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc); + +/*! \brief Scheduling for UE Sidelink TX procedures in normal subframes. + @param ue Pointer to UE variables on which to act + @param proc Pointer to RXn_TXnp4 proc information +*/ +void phy_procedures_UE_SL_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc); + +int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, + uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode); +#ifdef UE_SLOT_PARALLELISATION +void *UE_thread_slot1_dl_processing(void *arg); +#endif + +/*! \brief Scheduling for UE TX procedures in TDD S-subframes. + @param phy_vars_ue Pointer to UE variables on which to act + @param eNB_id Local id of eNB on which to act + @param abstraction_flag Indicator of PHY abstraction + @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying +*/ +void phy_procedures_UE_S_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag); + +/*! \brief Scheduling for UE RX procedures in TDD S-subframes. + @param phy_vars_ue Pointer to UE variables on which to act + @param eNB_id Local id of eNB on which to act + @param abstraction_flag Indicator of PHY abstraction + @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying +*/ +void phy_procedures_UE_S_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag); + +/*! \brief Get ULSCH harq_pid for Msg3 from RAR subframe. This returns n+k mod 10 (k>6) and corresponds to the rule in Section 6.1.1 from 36.213 + @param frame_parms Pointer to DL Frame Parameters + @param frame Frame index + @param current_subframe subframe of RAR transmission + @returns harq_pid (0 ... 7) + */ +uint8_t get_Msg3_harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t current_subframe); + +/*! \brief Get ULSCH harq_pid from PHICH subframe + @param frame_parms Pointer to DL Frame Parameters + @param subframe subframe of PHICH + @returns harq_pid (0 ... 7) + */ + +/*! \brief Function to indicate failure of contention resolution or RA procedure. It places the UE back in PRACH mode. + @param Mod_id Instance index of UE + @param CC_id Component Carrier Index + @param eNB_index Index of eNB + */ +void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + +/*! \brief Function to indicate success of contention resolution or RA procedure. + @param Mod_id Instance index of UE + @param CC_id Component Carrier Index + @param eNB_index Index of eNB + */ +void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + +uint8_t phich_subframe_to_harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe); + +/*! \brief Get PDSCH subframe (n+k) from PDCCH subframe n using relationship from Table 8-2 from 36.213 + @param frame_parms Pointer to DL Frame Parameters + @param n subframe of PDCCH + @returns PDSCH subframe (0 ... 7) (note: this is n+k from Table 8-2) + */ +uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); + + +/*! \brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69. + @param frame_parms Pointer to DL frame parameter descriptor + @param harq_ack Pointer to dlsch_ue harq_ack status descriptor + @param subframe Subframe for UE transmission (n in 36.213) + @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_tx,uint8_t subframe_rx,uint8_t *o_ACK, uint8_t cw_idx); + +/*! \brief Reset ACK/NACK information + @param frame_parms Pointer to DL frame parameter descriptor + @param harq_ack Pointer to dlsch_ue harq_ack status descriptor + @param subframe Subframe for UE transmission (n in 36.213) + @param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH + @returns status indicator for PUCCH/PUSCH transmission +*/ +uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms, + harq_status_t *harq_ack, + unsigned char subframe_tx, + unsigned char subframe_rx, + unsigned char *o_ACK, + uint8_t *pN_bundled, + 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 + @param subframe Subframe for UE transmission (n in 36.213) + @param ACK_index TTI bundling index (0,1) + @returns Subframe index for corresponding DL transmission +*/ +uint8_t ul_ACK_subframe2_dl_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe,uint8_t ACK_index); + +/*! \brief Computes number of DL subframes represented by a particular ACK received on UL (M from Table 10.1-1 in 36.213, p. 69 in version 8.6) + @param frame_parms Pointer to DL frame parameter descriptor + @param subframe Subframe for UE transmission (n in 36.213) + @returns Number of DL subframes (M) +*/ +uint8_t ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe); + +/*! \brief Indicates the SR TXOp in current subframe. Implements Table 10.1-5 from 36.213. + @param phy_vars_ue Pointer to UE variables + @param proc Pointer to RXn_TXnp4 thread context + @param eNB_id ID of eNB which is to receive the SR + @returns 1 if TXOp is active. +*/ +uint8_t is_SR_TXOp(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id); + +uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); + +/*! \brief Gives the UL frame corresponding to a PDDCH order in subframe n + @param frame_parms Pointer to DL frame parameters + @param frame Frame of received PDCCH + @param n subframe of PDCCH + @returns UL frame corresponding to pdcch order +*/ +uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n); + + +uint16_t get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1); + + + +void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance); +void process_timing_advance_rar(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint16_t timing_advance); + +unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb); + +void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + +/*! \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in +subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch. For +TDD, this routine computes the complex procedure described in Section 10.1 of 36.213 (through tables 10.1-1,10.1-2) +@param phy_vars_ue Pointer to UE variables +@param proc Pointer to RXn-TXnp4 proc information +@param harq_ack Pointer to dlsch_ue harq_ack status descriptor +@param eNB_id Index of eNB +@param b Pointer to PUCCH payload (b[0],b[1]) +@param SR 1 means there's a positive SR in parallel to ACK/NAK +@returns n1_pucch +*/ +uint16_t get_n1_pucch(PHY_VARS_UE *phy_vars_ue, + UE_rxtx_proc_t *proc, + harq_status_t *harq_ack, + uint8_t eNB_id, + uint8_t *b, + uint8_t SR); + + + + +/*! \brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC. + @param Mod_id Local UE index on which to act + @param CC_id Component Carrier Index + @param eNB_index ID of eNB + @returns UE mode +*/ +UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + +/*! \brief This function implements the power control mechanism for PUCCH from 36.213. + @param phy_vars_ue PHY variables + @param proc Pointer to proc descriptor + @param eNB_id Index of eNB + @param pucch_fmt Format of PUCCH that is being transmitted + @returns Transmit power + */ +int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt); + +/*! \brief This function implements the power control mechanism for PUCCH from 36.213. + @param phy_vars_ue PHY variables + @param proc Pointer to proc descriptor + @param eNB_id Index of eNB + @param j index of type of PUSCH (SPS, Normal, Msg3) + @returns Transmit power + */ +void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag); + +/*! \brief This function implements the power control mechanism for SRS from 36.213. + @param phy_vars_ue PHY variables + @param proc Pointer to proc descriptor + @param eNB_id Index of eNB + @param j index of type of PUSCH (SPS, Normal, Msg3) + @returns Transmit power + */ +void srs_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t *pnb_rb_srs, uint8_t abstraction_flag); + +void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id); + +int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index); + + + +LTE_DL_FRAME_PARMS *get_lte_frame_parms(module_id_t Mod_id, uint8_t CC_id); + +MU_MIMO_mode* get_mu_mimo_mode (module_id_t Mod_id, uint8_t CC_id, rnti_t rnti); + +int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t harq_pid); + + +int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid); + +int16_t get_target_pusch_rx_power(module_id_t module_idP, uint8_t CC_id); +int16_t get_target_pucch_rx_power(module_id_t module_idP, uint8_t CC_id); + +int get_ue_active_harq_pid(uint8_t Mod_id,uint8_t CC_id,uint16_t rnti,int frame, uint8_t subframe,uint8_t *harq_pid,uint8_t *round,uint8_t ul_flag); + +void dump_dlsch(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid); +void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); +void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); + +void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid); + + +int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx); + +void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); + +/*@}*/ + + +#endif + + diff --git a/openair1/SCHED/srs_pc.c b/openair1/SCHED_UE/srs_pc.c similarity index 96% rename from openair1/SCHED/srs_pc.c rename to openair1/SCHED_UE/srs_pc.c index 04dacecc25a5aa59e6feb2ea35811dbe913082fc..9463db2cd62b594db9fad1adeb7514fbcd34516e 100644 --- a/openair1/SCHED/srs_pc.c +++ b/openair1/SCHED_UE/srs_pc.c @@ -30,9 +30,10 @@ * \warning */ -#include "PHY/defs.h" -#include "PHY/LTE_TRANSPORT/proto.h" -#include "PHY/extern.h" +#include "PHY/defs_UE.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" void srs_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t *pnb_rb_srs, uint8_t abstraction_flag) { diff --git a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c index 1ba724976fabdd87b82c623ee50ea9b43cb8cbfb..8cf9e13212244ec7e1ab7350c1228deff9b1d5e0 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c @@ -113,7 +113,7 @@ multicast_link_init(void) if (multicast_if != NULL) { if (setsockopt(group_list[group].socket, SOL_SOCKET,SO_BINDTODEVICE, - multicast_if, 4) < 0) { + multicast_if, strlen(multicast_if)) < 0) { LOG_E(EMU, "[MULTICAST] ERROR : setsockopt:SO_BINDTODEVICE on interface %s, exiting ...\n", multicast_if); diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index b578721a1a0ffed4b79f7956551d8ae3fe49c00c..230eeac726fb3039ca23bdc88ba3839be4e2c0c4 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -39,6 +39,13 @@ #include <fcntl.h> #include <errno.h> #include "platform_constants.h" +#ifdef UE_NAS_USE_TUN +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <linux/if.h> +#include <linux/if_tun.h> +#include "openairinterface5g_limits.h" +#endif char nl_rx_buf[NL_MAX_PAYLOAD]; @@ -47,12 +54,119 @@ struct nlmsghdr *nas_nlh_tx = NULL; struct nlmsghdr *nas_nlh_rx = NULL; struct iovec nas_iov_tx; struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)}; +#ifdef UE_NAS_USE_TUN +int nas_sock_fd[NUMBER_OF_UE_MAX]; +#else int nas_sock_fd; +#endif struct msghdr nas_msg_tx; struct msghdr nas_msg_rx; #define GRAAL_NETLINK_ID 31 +#ifdef UE_NAS_USE_TUN + +static int tun_alloc(char *dev) +{ + struct ifreq ifr; + int fd, err; + + if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { + printf("[TUN] failed to open /dev/net/tun\n"); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + + /* Flags: IFF_TUN - TUN device (no Ethernet headers) + * IFF_TAP - TAP device + * + * IFF_NO_PI - Do not provide packet information + */ + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + if( *dev ) + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + + if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ + close(fd); + return err; + } + strcpy(dev, ifr.ifr_name); + return fd; +} + +int netlink_init(void) +{ + int i; + int ret; + + char ifname[64]; + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + sprintf(ifname, "oip%d", i+1); + nas_sock_fd[i] = tun_alloc(ifname); + + if (nas_sock_fd[i] == -1) { + printf("[NETLINK] Error opening socket %d (%d:%s)\n",nas_sock_fd[i],errno, strerror(errno)); + exit(1); + } + + printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd[i]); + +#if !defined(PDCP_USE_NETLINK_QUEUES) + ret = fcntl(nas_sock_fd[i],F_SETFL,O_NONBLOCK); + + if (ret == -1) { + printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno)); +#if defined(LINK_ENB_PDCP_TO_IP_DRIVER) + exit(1); +#endif + } + +#endif + + memset(&nas_src_addr, 0, sizeof(nas_src_addr)); + nas_src_addr.nl_family = AF_NETLINK; + nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ + nas_src_addr.nl_groups = 0; /* not in mcast groups */ + ret = bind(nas_sock_fd[i], (struct sockaddr*)&nas_src_addr, sizeof(nas_src_addr)); + + + + memset(&nas_dest_addr, 0, sizeof(nas_dest_addr)); + nas_dest_addr.nl_family = AF_NETLINK; + nas_dest_addr.nl_pid = 0; /* For Linux Kernel */ + nas_dest_addr.nl_groups = 0; /* unicast */ + + // TX PART + nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD)); + memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD)); + /* Fill the netlink message header */ + nas_nlh_tx->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD); + nas_nlh_tx->nlmsg_pid = 1;//getpid(); /* self pid */ + nas_nlh_tx->nlmsg_flags = 0; + + nas_iov_tx.iov_base = (void *)nas_nlh_tx; + nas_iov_tx.iov_len = nas_nlh_tx->nlmsg_len; + memset(&nas_msg_tx,0,sizeof(nas_msg_tx)); + nas_msg_tx.msg_name = (void *)&nas_dest_addr; + nas_msg_tx.msg_namelen = sizeof(nas_dest_addr); + nas_msg_tx.msg_iov = &nas_iov_tx; + nas_msg_tx.msg_iovlen = 1; + + + // RX PART + memset(&nas_msg_rx,0,sizeof(nas_msg_rx)); + nas_msg_rx.msg_name = (void *)&nas_src_addr; + nas_msg_rx.msg_namelen = sizeof(nas_src_addr); + nas_msg_rx.msg_iov = &nas_iov_rx; + nas_msg_rx.msg_iovlen = 1; + } + + return 1; +} + +#else /* UE_NAS_USE_TUN */ + int netlink_init(void) { int ret; @@ -119,3 +233,5 @@ int netlink_init(void) return(nas_sock_fd); } + +#endif /* UE_NAS_USE_TUN */ diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 34055517b24507482545f26ac4357882a4ea3a72..77b8c0e674d3b09cad69be0fcb6048abc7f54f46 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -36,14 +36,15 @@ #include <execinfo.h> #include <signal.h> -#include "SIMULATION/TOOLS/defs.h" +#include "SIMULATION/TOOLS/sim.h" #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/vars.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_vars.h" -#include "SCHED/defs.h" -#include "SCHED/vars.h" -#include "LAYER2/MAC/vars.h" +#include "SCHED/sched_eNB.h" +#include "SCHED/sched_common_vars.h" +#include "LAYER2/MAC/mac_vars.h" #include "OCG_vars.h" #include "UTIL/LOG/log.h" @@ -54,8 +55,20 @@ #include "PHY/TOOLS/lte_phy_scope.h" -PHY_VARS_eNB *eNB; -PHY_VARS_UE *UE; +#include "dummy_functions.c" + +#include "PHY/MODULATION/modulation_common.h" +#include "PHY/MODULATION/modulation_eNB.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "SCHED/sched_eNB.h" +#include "SCHED_UE/sched_UE.h" +#include "common/config/config_load_configmodule.h" +#include "PHY/INIT/phy_init.h" + +void feptx_ofdm(RU_t *ru); +void feptx_prec(RU_t *ru); double cpuf; @@ -68,6 +81,8 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ +int codingw = 0; + void handler(int sig) { void *array[10]; @@ -123,7 +138,7 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_ } -void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], +void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) { int i,u; @@ -134,18 +149,18 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { - for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { + for (aa=0; aa<ru->frame_parms.nb_antennas_tx; aa++) { if (awgn_flag == 0) { - s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); - s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); + s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } else { for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) { if (aa==0) { - r_re[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } else { - r_re[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } } @@ -180,11 +195,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou if(abstx) { if (trials==0 && round==0) { // calculate freq domain representation to compute SINR - freq_channel(eNB2UE[0], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[0], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); // snr=pow(10.0,.1*SNR); fprintf(csv_fd,"%f,",SNR); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) { channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; @@ -195,9 +210,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } if(num_rounds>1) { - freq_channel(eNB2UE[1], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) { channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; @@ -207,9 +222,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } - freq_channel(eNB2UE[2], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) { channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; @@ -219,9 +234,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } - freq_channel(eNB2UE[3], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) { channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; @@ -237,11 +252,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou //AWGN // tx_lev is the average energy over the whole subframe // but SNR should be better defined wrt the energy in the reference symbols - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR; + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { - for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { + for (aa=0; aa<UE->frame_parms.nb_antennas_rx; aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); @@ -251,28 +266,118 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } +uint16_t +fill_tx_req(nfapi_tx_request_body_t *tx_req_body, + uint16_t absSF, + uint16_t pdu_length, + uint16_t pdu_index, + uint8_t *pdu) +{ + nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; + LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", + tx_req_body->number_of_pdus, pdu_length); + + TX_req->pdu_length = pdu_length; + TX_req->pdu_index = pdu_index; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pdu_length; + TX_req->segments[0].segment_data = pdu; + tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req_body->number_of_pdus++; + + return (((absSF / 10) << 4) + (absSF % 10)); +} + +void +fill_dlsch_config(nfapi_dl_config_request_body_t * dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector) +{ + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_req->number_pdu++; +} void fill_DCI(PHY_VARS_eNB *eNB, - DCI_ALLOC_t *dci_alloc, + int frame, int subframe, + Sched_Rsp_t *sched_resp, + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000], int n_rnti, int n_users, int transmission_mode, + int retrans, int common_flag, + int NB_RB, int DLSCH_RB_ALLOC, int TPC, int mcs1, int mcs2, int ndi, int rv, + int pa, int *num_common_dci, int *num_ue_spec_dci, int *num_dci) { int k; - int dci_length = -1,dci_length_bytes = -1; - // printf("Generating DCIs for %d users, TM %d, mcs1 %d\n",n_users,transmission_mode,mcs1); + nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body; + + dl_req->number_dci=0; + dl_req->number_pdu=0; + TX_req->number_of_pdus=0; + for(k=0; k<n_users; k++) { switch(transmission_mode) { case 1: @@ -282,903 +387,106 @@ void fill_DCI(PHY_VARS_eNB *eNB, case 7: if (common_flag == 0) { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - dci_length = sizeof_DCI1_20MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 100: - dci_length = sizeof_DCI1_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - } - } + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = n_rnti+k; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = DLSCH_RB_ALLOC; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0; + + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + + fill_dlsch_config(dl_req, + get_TBS_DL(mcs1,NB_RB), + (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ + n_rnti, + 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + DLSCH_RB_ALLOC, // resource_block_coding, + get_Qm(mcs1), + rv, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + transmission_mode == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + pa, // pa + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + transmission_mode, + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + fill_tx_req(TX_req, + (frame * 10) + subframe, + get_TBS_DL(mcs1,NB_RB), + 0, + input_buffer[k]); + } + else { - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format1; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - // printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format1, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci+1; - *num_ue_spec_dci = *num_ue_spec_dci+1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } + } - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci=*num_common_dci+1; - *num_dci = *num_dci + 1; + break; - } + case 3: + if (common_flag == 0) { - break; + if (eNB->frame_parms.nb_antennas_tx == 2) { - case 3: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); - break; - } - } + if (eNB->frame_parms.frame_type == TDD) { - else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - } - } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { + } + else { - } + } + } + } + break; - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format2A; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - //printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci + 1; - *num_ue_spec_dci = *num_ue_spec_dci + 1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } + case 4: + if (common_flag == 0) { - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - //printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci = *num_common_dci + 1; - *num_dci = *num_dci + 1; + if (eNB->frame_parms.nb_antennas_tx == 2) { - } + if (eNB->frame_parms.frame_type == TDD) { - //printf("Generated DCI format 2A (Transmission Mode 3)\n"); - break; - case 4: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - dci_length = sizeof_DCI2_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); - break; - } - } + } - else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - dci_length = sizeof_DCI2_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - } - } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { + else { - } + } + } else if (eNB->frame_parms.nb_antennas_tx == 4) { - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format2; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci + 1; - *num_ue_spec_dci = *num_ue_spec_dci + 1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } + } - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci = *num_common_dci + 1; - *num_dci = *num_dci + 1; + } + else { } @@ -1186,90 +494,31 @@ void fill_DCI(PHY_VARS_eNB *eNB, case 5: case 6: - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - dci_alloc[*num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format1E_2A_M10PRB; - dci_alloc[*num_dci].firstCCE = 4*k; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu2_1E[k], - n_rnti+k, - format1E_2A_M10PRB, - eNB->dlsch[k], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[k].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - *num_ue_spec_dci = *num_ue_spec_dci + 1; - *num_dci = *num_dci + 1; break; - default: - printf("Unsupported Transmission Mode!!!"); - exit(-1); - break; - } + default: + printf("Unsupported Transmission Mode %d!!!\n",transmission_mode); + exit(-1); + break; } + } + *num_dci = dl_req->number_dci; + *num_ue_spec_dci = dl_req->number_dci; + *num_common_dci = 0; } int n_users = 1; sub_frame_t subframe=7; -DCI_PDU DCI_pdu; int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1; - - -DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) { - - if (subframeP == subframe) { - DCI_pdu.Num_dci = num_ue_spec_dci + num_common_dci; - DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; - } else { - DCI_pdu.Num_dci = 0; - DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; - } - - return &DCI_pdu; -} - -void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) { - - return; -} - uint16_t n_rnti=0x1234; -unsigned char *input_buffer0[2],*input_buffer1[2]; -unsigned short input_buffer_length0,input_buffer_length1; - -uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex) { - - int k; - - for (k=0;k<n_users;k++) - if (rnti == n_rnti+k) - break; - if (k<n_users) - return(TBindex==0 ? input_buffer0[k] : input_buffer1[k]); - else { - printf("RNTI not found,exiting\n"); - exit(-1); - } -} + int nfapi_mode=0; int main(int argc, char **argv) { int c; - int k,i,aa; + int k,i,j,aa; int re; int s,Kr,Kr_bytes; @@ -1300,12 +549,18 @@ int main(int argc, char **argv) SCM_t channel_model=Rayleigh1; // unsigned char *input_data,*decoded_output; - DCI_ALLOC_t *dci_alloc = &DCI_pdu.dci_alloc[0]; + DCI_ALLOC_t da; + DCI_ALLOC_t *dci_alloc = &da; - unsigned int ret; unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors[4]={0,0,0,0};//,num_layers; + unsigned int tx_lev=0,tx_lev_dB=0,trials; + unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers; + memset(errs,0,4*sizeof(unsigned int)); + memset(errs2,0,4*sizeof(unsigned int)); + memset(round_trials,0,4*sizeof(unsigned int)); + memset(dci_errors,0,4*sizeof(unsigned int)); + //int re_allocated; char fname[32],vname[32]; FILE *bler_fd; @@ -1319,16 +574,6 @@ int main(int argc, char **argv) unsigned char input_trch_file=0; FILE *input_fd=NULL; unsigned char input_file=0; - // char input_val_str[50],input_val_str2[50]; - - char input_trch_val[16]; - - // unsigned char pbch_pdu[6]; - - - - - // FILE *rx_frame_file; int n_frames; int n_ch_rlz = 1; @@ -1351,7 +596,7 @@ int main(int argc, char **argv) // void *data; // int ii; // int bler; - double blerr[4],uncoded_ber=0; //,avg_ber; + double blerr[4]; short *uncoded_ber_bit=NULL; uint8_t N_RB_DL=25,osf=1; frame_t frame_type = FDD; @@ -1392,6 +637,7 @@ int main(int argc, char **argv) int threequarter_fs=0; + opp_enabled=1; // to enable the time meas FILE *csv_fd=NULL; @@ -1402,6 +648,17 @@ int main(int argc, char **argv) int log_level = LOG_ERR; int dci_received; + PHY_VARS_eNB *eNB; + RU_t *ru; + PHY_VARS_UE *UE; + nfapi_dl_config_request_t DL_req; + nfapi_ul_config_request_t UL_req; + nfapi_hi_dci0_request_t HI_DCI0_req; + nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU]; + nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; + nfapi_tx_request_t TX_req; + Sched_Rsp_t sched_resp; + int pa=dB0; #if defined(__arm__) FILE *proc_fd = NULL; @@ -1420,6 +677,18 @@ int main(int argc, char **argv) cpu_freq_GHz = get_cpu_freq_GHz(); #endif printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + memset((void*)&sched_resp,0,sizeof(sched_resp)); + sched_resp.DL_req = &DL_req; + sched_resp.UL_req = &UL_req; + sched_resp.HI_DCI0_req = &HI_DCI0_req; + sched_resp.TX_req = &TX_req; + memset((void*)&DL_req,0,sizeof(DL_req)); + memset((void*)&UL_req,0,sizeof(UL_req)); + memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void*)&TX_req,0,sizeof(TX_req)); + + DL_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdu_list; + TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; cpuf = cpu_freq_GHz; @@ -1612,7 +881,7 @@ int main(int argc, char **argv) channel_model=AWGN; break; default: - msg("Unsupported channel model!\n"); + printf("Unsupported channel model!\n"); exit(-1); } @@ -1634,7 +903,7 @@ int main(int argc, char **argv) UE->use_ia_receiver = 1; if ((n_tx_port!=2) || (transmission_mode!=5)) { - msg("IA receiver only supported for TM5!"); + printf("IA receiver only supported for TM5!"); exit(-1); } @@ -1644,7 +913,7 @@ int main(int argc, char **argv) i_mod = atoi(optarg); if (i_mod!=2 && i_mod!=4 && i_mod!=6) { - msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); exit(-1); } @@ -1658,7 +927,7 @@ int main(int argc, char **argv) n_tx_port=atoi(optarg); if ((n_tx_port==0) || ((n_tx_port>2))) { - msg("Unsupported number of cell specific antennas ports %d\n",n_tx_port); + printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port); exit(-1); } @@ -1675,7 +944,7 @@ int main(int argc, char **argv) (transmission_mode!=5) && (transmission_mode!=6) && (transmission_mode!=7)) { - msg("Unsupported transmission mode %d\n",transmission_mode); + printf("Unsupported transmission mode %d\n",transmission_mode); exit(-1); } @@ -1689,17 +958,17 @@ int main(int argc, char **argv) n_tx_phy=atoi(optarg); if (n_tx_phy < n_tx_port) { - msg("n_tx_phy mush not be smaller than n_tx_port"); + printf("n_tx_phy mush not be smaller than n_tx_port"); exit(-1); } if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) { - msg("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); + printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); exit(-1); } if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { - msg("Physical number of antennas not supported for TM7.\n"); + printf("Physical number of antennas not supported for TM7.\n"); exit(-1); } @@ -1718,7 +987,7 @@ int main(int argc, char **argv) n_rx=atoi(optarg); if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); + printf("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } @@ -1770,9 +1039,14 @@ int main(int argc, char **argv) } } + if (transmission_mode>1) pa=dBm3; + printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); + + AssertFatal(load_configmodule(argc,argv) != NULL, + "cannot load configuration module, exiting\n"); logInit(); // enable these lines if you need debug info - set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1); + set_comp_log(PHY,LOG_INFO,LOG_HIGH,1); set_glog(log_level,LOG_HIGH); // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore @@ -1822,30 +1096,40 @@ int main(int argc, char **argv) n_users = 2; printf("dual_stream_UE=%d\n", dual_stream_UE); } + RC.nb_L1_inst = 1; + RC.nb_RU = 1; - lte_param_init(n_tx_port, + lte_param_init(&eNB,&UE,&ru, + n_tx_port, n_tx_phy, - n_rx, + 1, + n_rx, transmission_mode, extended_prefix_flag, frame_type, Nid_cell, tdd_config, N_RB_DL, + pa, threequarter_fs, osf, perfect_ce); - + RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); + RC.ru = (RU_t **)malloc(sizeof(RC.ru)); + RC.eNB[0][0] = eNB; + RC.ru[0] = ru; + printf("lte_param_init done\n"); if ((transmission_mode==1) || (transmission_mode==7)) { - for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) - for (re=0; re<eNB->frame_parms.ofdm_symbol_size; re++) - eNB->common_vars.beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; + for (aa=0; aa<ru->nb_tx; aa++) + for (re=0; re<ru->frame_parms.ofdm_symbol_size; re++) + ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; } if (transmission_mode<7) - eNB->do_precoding=0; + ru->do_precoding=0; else - eNB->do_precoding=1; + ru->do_precoding=1; eNB->mac_enabled=1; if (two_thread_flag == 0) { @@ -1860,9 +1144,6 @@ int main(int argc, char **argv) } // callback functions required for phy_procedures_tx - mac_xface->get_dci_sdu = get_dci_sdu; - mac_xface->get_dlsch_sdu = get_dlsch_sdu; - mac_xface->eNB_dlsch_ulsch_scheduler = eNB_dlsch_ulsch_scheduler; // eNB_id_i = UE->n_connected_eNB; @@ -1875,7 +1156,10 @@ int main(int argc, char **argv) snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000]; + for (i=0;i<n_users;i++) + for (j=0;j<20000;j++) input_buffer[i][j] = (uint8_t)((taus())&255); frame_parms = &eNB->frame_parms; @@ -2024,48 +1308,7 @@ int main(int argc, char **argv) UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti; - // Fill in UL_alloc - UL_alloc_pdu.type = 0; - UL_alloc_pdu.hopping = 0; - UL_alloc_pdu.rballoc = UL_RB_ALLOC; - UL_alloc_pdu.mcs = 1; - UL_alloc_pdu.ndi = 1; - UL_alloc_pdu.TPC = 0; - UL_alloc_pdu.cqi_req = 1; - - CCCH_alloc_pdu.type = 0; - CCCH_alloc_pdu.vrb_type = 0; - CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; - CCCH_alloc_pdu.ndi = 1; - CCCH_alloc_pdu.mcs = 1; - CCCH_alloc_pdu.harq_pid = 0; - - DLSCH_alloc_pdu2_1E[0].rah = 0; - DLSCH_alloc_pdu2_1E[0].rballoc = DLSCH_RB_ALLOC; - DLSCH_alloc_pdu2_1E[0].TPC = 0; - DLSCH_alloc_pdu2_1E[0].dai = 0; - DLSCH_alloc_pdu2_1E[0].harq_pid = 0; - //DLSCH_alloc_pdu2_1E[0].tb_swap = 0; - DLSCH_alloc_pdu2_1E[0].mcs = mcs1; - DLSCH_alloc_pdu2_1E[0].ndi = 1; - DLSCH_alloc_pdu2_1E[0].rv = 0; - // Forget second codeword - DLSCH_alloc_pdu2_1E[0].tpmi = (transmission_mode>=5 ? 5 : 0); // precoding - DLSCH_alloc_pdu2_1E[0].dl_power_off = (transmission_mode==5 ? 0 : 1); - - DLSCH_alloc_pdu2_1E[1].rah = 0; - DLSCH_alloc_pdu2_1E[1].rballoc = DLSCH_RB_ALLOC; - DLSCH_alloc_pdu2_1E[1].TPC = 0; - DLSCH_alloc_pdu2_1E[1].dai = 0; - DLSCH_alloc_pdu2_1E[1].harq_pid = 0; - //DLSCH_alloc_pdu2_1E[1].tb_swap = 0; - DLSCH_alloc_pdu2_1E[1].mcs = mcs_i; - DLSCH_alloc_pdu2_1E[1].ndi = 1; - DLSCH_alloc_pdu2_1E[1].rv = 0; - // Forget second codeword - DLSCH_alloc_pdu2_1E[1].tpmi = (transmission_mode>=5 ? 5 : 0) ; // precoding - DLSCH_alloc_pdu2_1E[1].dl_power_off = (transmission_mode==5 ? 0 : 1); - + printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx); eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, @@ -2088,7 +1331,7 @@ int main(int argc, char **argv) } if (eNB2UE[0]==NULL) { - msg("Problem generating channel model. Exiting.\n"); + printf("Problem generating channel model. Exiting.\n"); exit(-1); } @@ -2114,7 +1357,7 @@ int main(int argc, char **argv) break; } - for (k=0; k<n_users; k++) { + for (k=0; k<NUMBER_OF_UE_MAX; k++) { // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); @@ -2166,24 +1409,31 @@ int main(int argc, char **argv) eNB->UE_stats[1].DL_pmi_single = 0; } + eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]]; if (input_fd==NULL) { - + DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols; + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; // UE specific DCI fill_DCI(eNB, - &dci_alloc[0], - subframe, + proc_eNB->frame_tx,subframe, + &sched_resp, + input_buffer, n_rnti, n_users, transmission_mode, + 0, common_flag, + NB_RB, DLSCH_RB_ALLOC, TPC, mcs1, mcs2, 1, 0, + pa, &num_common_dci, &num_ue_spec_dci, &num_dci); @@ -2194,65 +1444,8 @@ int main(int argc, char **argv) - - for (k=0; k<n_users; k++) { - - input_buffer_length0 = eNB->dlsch[k][0]->harq_processes[0]->TBS/8; - input_buffer0[k] = (unsigned char *)malloc(input_buffer_length0+4); - memset(input_buffer0[k],0,input_buffer_length0+4); - input_buffer_length1 = eNB->dlsch[k][1]->harq_processes[0]->TBS/8; - input_buffer1[k] = (unsigned char *)malloc(input_buffer_length1+4); - memset(input_buffer1[k],0,input_buffer_length1+4); - - if (input_trch_file==0) { - for (i=0; i<input_buffer_length0; i++) { - //input_buffer0[k][i] = (unsigned char)(i&0xff); - input_buffer0[k][i] = (unsigned char)(taus()&0xff); - } - - for (i=0; i<input_buffer_length1; i++) { - input_buffer1[k][i]= (unsigned char)(taus()&0xff); - } - } - - else { - i=0; - - while ((!feof(input_trch_fd)) && (i<input_buffer_length0<<3)) { - ret=fscanf(input_trch_fd,"%s",input_trch_val); - if (ret != 1) printf("ERROR: error reading file\n"); - - if (input_trch_val[0] == '1') - input_buffer0[k][i>>3]+=(1<<(7-(i&7))); - - if (i<16) - printf("input_trch_val %d : %c\n",i,input_trch_val[0]); - - i++; - - if (((i%8) == 0) && (i<17)) - printf("%x\n",input_buffer0[k][(i-1)>>3]); - } - - printf("Read in %d bits\n",i); - } - } } - // this is for user 0 only - coded_bits_per_codeword = get_G(&eNB->frame_parms, - eNB->dlsch[0][0]->harq_processes[0]->nb_rb, - eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, - get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - eNB->dlsch[0][0]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0, - subframe, - transmission_mode>=7?transmission_mode:0); - - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); - snr_step = input_snr_step; UE->high_speed_flag = 1; UE->ch_est_alpha=0; @@ -2332,7 +1525,7 @@ int main(int argc, char **argv) struct list time_vector_rx_dec; initialize(&time_vector_rx_dec); - eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[UE->current_thread_id[subframe]]; + for (trials = 0; trials<n_frames; trials++) { //printf("Trial %d\n",trials); @@ -2365,7 +1558,7 @@ int main(int argc, char **argv) // printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { - memset(&eNB->common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } if (input_fd==NULL) { @@ -2383,108 +1576,73 @@ int main(int argc, char **argv) TB0_active = 1; eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; - - fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC, - mcs1,mcs2,!(trials&1),round&3,&num_common_dci,&num_ue_spec_dci,&num_dci); + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); } else { - fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC, - (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,&num_common_dci,&num_ue_spec_dci,&num_dci); - } - for (i=num_common_dci; i<num_dci; i++) { - - dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table, - 1<<dci_alloc[i].L, - numCCE, - (dci_alloc[i].rnti==SI_RNTI)? 1 : 0, - dci_alloc[i].rnti, - subframe); - - if (dci_alloc[i].firstCCE < 0) { - printf("firstCCE <0 !! dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format, - dci_alloc[i].firstCCE,numCCE); - exit(-1); - } - if (n_frames==1) - printf("dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format, - dci_alloc[i].firstCCE,numCCE); + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); } - - } // common_flag == 0 - - - - /* - else { // Read signal from file - i=0; - while (!feof(input_fd)) { - fscanf(input_fd,"%s %s",input_val_str,input_val_str2); - - if ((i%4)==0) { - ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); - if ((i/4)<100) - printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); - } - i++; - if (i>(FRAME_LENGTH_SAMPLES)) - break; - } - printf("Read in %d samples\n",i/4); - write_output("txsig0.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1); - // write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); - tx_lev = signal_energy(&txdata[0][0], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - } - */ - + } proc_eNB->subframe_tx = subframe; - eNB->abstraction_flag=0; - - phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1,dci_flag); + sched_resp.subframe=subframe; + sched_resp.frame=proc_eNB->frame_tx; + eNB->abstraction_flag=0; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,1); + + if (uncoded_ber_bit == NULL) { + // this is for user 0 only + printf("nb_rb %d, rb_alloc %x, mcs %d\n", + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0], + eNB->dlsch[0][0]->harq_processes[0]->mcs); + + coded_bits_per_codeword = get_G(&eNB->frame_parms, + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, + get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), + eNB->dlsch[0][0]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe, + transmission_mode>=7?transmission_mode:0); + + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); + } start_meas(&eNB->ofdm_mod_stats); - /* - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2), - &eNB->frame_parms); - - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2)+1, - &eNB->frame_parms); - */ - - do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2), - &eNB->frame_parms, - eNB->do_precoding); + ru->proc.subframe_tx=subframe; + memcpy((void*)&ru->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + feptx_prec(ru); + feptx_ofdm(ru); - do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2)+1, - &eNB->frame_parms, - eNB->do_precoding); + stop_meas(&eNB->ofdm_mod_stats); - stop_meas(&eNB->ofdm_mod_stats); // generate next subframe for channel estimation + DL_req.dl_config_request_body.number_dci=0; + DL_req.dl_config_request_body.number_pdu=0; + TX_req.tx_request_body.number_of_pdus=0; proc_eNB->subframe_tx = subframe+1; + sched_resp.subframe=subframe+1; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,0); - phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0,dci_flag); - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2)+2, - &eNB->frame_parms); + ru->proc.subframe_tx=(subframe+1)%10; + feptx_prec(ru); + feptx_ofdm(ru); proc_eNB->frame_tx++; @@ -2492,7 +1650,7 @@ int main(int argc, char **argv) tx_lev = 0; for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { - tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa] + tx_lev += signal_energy(&ru->common.txdata[aa] [subframe*eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti); } @@ -2500,21 +1658,22 @@ int main(int argc, char **argv) tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + if (n_frames==1) { printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); - write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); + write_output("txsig0.m","txs0", &ru->common.txdata[0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); if (transmission_mode<7) { - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); } else if (transmission_mode == 7) { - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); - write_output("txsigF0_BF.m","txsF0_BF", &eNB->common_vars.txdataF_BF[eNB_id][0][0],eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0.m","txsF0", &ru->common.txdataF_BF[5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0_BF.m","txsF0_BF", &ru->common.txdataF_BF[0][0],eNB->frame_parms.ofdm_symbol_size,1,1); } } } - DL_channel(eNB,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); + DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]]; @@ -2532,6 +1691,8 @@ int main(int argc, char **argv) if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); if (dci_flag==0) { + memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t)); + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; if (n_frames==1) printf("bypassing PDCCH/DCI detection\n"); if (generate_ue_dlsch_params_from_dci(proc->frame_rx, @@ -2541,7 +1702,7 @@ int main(int argc, char **argv) dci_alloc[0].format, UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], - UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], + UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -2565,31 +1726,55 @@ int main(int argc, char **argv) dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; - phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx,no_relay,NULL); + phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx); dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; if (dci_flag && (dci_received == 0)) { - //printf("DCI not received\n"); + printf("DCI not received\n"); dci_errors[round]++; - /* - write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],12*UE->frame_parms.N_RB_DL*3,1,1); + write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*12*UE->frame_parms.N_RB_DL,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,12*UE->frame_parms.N_RB_DL*4*2,1,4); - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); - write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + exit(-1); - */ + } + int bit_errors=0; if ((test_perf ==0 ) && (n_frames==1)) { + + dlsch_unscrambling(&eNB->frame_parms, + 0, + UE->dlsch[UE->current_thread_id[subframe]][0][0], + coded_bits_per_codeword, + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0], + 0, + subframe<<1); + for (i=0;i<coded_bits_per_codeword;i++) + if ((eNB->dlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)|| + (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { + uncoded_ber_bit[bit_errors++] = 1; + printf("error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + } + else { + /* + printf("no error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + */ + } + + write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); if (eNB->frame_parms.nb_antennas_tx>1) @@ -2625,6 +1810,7 @@ int main(int argc, char **argv) UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); //pdsch_vars + printf("coded_bits_per_codeword %d\n",coded_bits_per_codeword); dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); @@ -2648,7 +1834,7 @@ int main(int argc, char **argv) iter_trials++; if (n_frames==1) - printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); + printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; @@ -2662,8 +1848,10 @@ int main(int argc, char **argv) iter_trials++; if (n_frames==1) { + + //if ((n_frames==1) || (SNR>=30)) { - printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); + printf("DLSCH errors found (round %d), uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) { if (s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus) @@ -3292,13 +2480,6 @@ int main(int argc, char **argv) uncoded_ber_bit = NULL; - for (k=0; k<n_users; k++) { - free(input_buffer0[k]); - free(input_buffer1[k]); - input_buffer0[k]=NULL; - input_buffer1[k]=NULL; - } - printf("Freeing dlsch structures\n"); for (i=0; i<2; i++) { @@ -3310,7 +2491,7 @@ int main(int argc, char **argv) if (test_perf && !test_passed) return(-1); - else + else return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c new file mode 100644 index 0000000000000000000000000000000000000000..ac96d53b0f5d2f6baa8bc91c849813c15b621eb9 --- /dev/null +++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c @@ -0,0 +1,92 @@ + +PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, + frame_t frameP, uint8_t new_Msg3, + sub_frame_t subframe){ return(NULL);} + +void ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * ulsch_buffer, uint16_t buflen, + uint8_t * access_mode){} + +void Msg1_transmitted(module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t eNB_id){} + +void Msg3_transmitted(module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t eNB_id){} + +uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, + uint8_t eNB_id, rnti_t rnti, sub_frame_t subframe){ return(0);} + +void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) +{} + +UE_L2_STATE_t ue_scheduler(const module_id_t module_idP, + const frame_t rxFrameP, + const sub_frame_t rxSubframe, + const frame_t txFrameP, + const sub_frame_t txSubframe, + const lte_subframe_t direction, + const uint8_t eNB_index, const int CC_id){ return(0);} + +void ue_decode_p(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len){} + +void ue_decode_si(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len){} + +void ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frame, + sub_frame_t subframe, uint8_t * sdu, uint16_t sdu_len, + uint8_t CH_index){} + +SLSS_t *ue_get_slss(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe) {return(NULL);} + +SLDCH_t *ue_get_sldch(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe) {return(NULL);} + +SLSCH_t *ue_get_slsch(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe) {return(NULL);} + +void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {} + +uint16_t +ue_process_rar(const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const rnti_t ra_rnti, + uint8_t * const dlsch_buffer, + rnti_t * const t_crnti, + const uint8_t preamble_index, + uint8_t * selected_rar_buffer){ return(0);} + +void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, + uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index, + uint8_t sync_area){} + +int ue_query_mch(uint8_t Mod_id, uint8_t CC_id, uint32_t frame, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * sync_area, uint8_t * mcch_active){ return(0);} + +void dl_phy_sync_success(module_id_t module_idP, + frame_t frameP, + unsigned char eNB_index, uint8_t first_sync){} + +uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { return(0);} + +int32_t get_uldl_offset(int eutra_bandP) { return(0);} + +IF_Module_t *IF_Module_init(int Mod_id) { return(NULL);} + +int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id) { return(0);} + +int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id) { return(0);} + +void thread_top_init(char *thread_name, + int affinity, + uint64_t runtime, + uint64_t deadline, + uint64_t period) {} + +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index cabe9664917882cc1ca26c4aee7fbf9c3eec6725..22cac3719374c4dcd86a2e71eefc17151dc97d2f 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -33,24 +33,30 @@ #include <string.h> #include <math.h> #include <unistd.h> -#include "SIMULATION/TOOLS/defs.h" +#include "SIMULATION/TOOLS/sim.h" #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/vars.h" +#include "PHY/defs_common.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_vars.h" -#include "SCHED/defs.h" -#include "SCHED/vars.h" -#include "LAYER2/MAC/vars.h" + +#include "SCHED/sched_common_vars.h" +#include "SCHED/sched_eNB.h" +#include "SCHED_UE/sched_UE.h" +#include "LAYER2/MAC/mac_vars.h" #include "OCG_vars.h" -#include "intertask_interface_init.h" + +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/INIT/phy_init.h" #include "unitary_defs.h" #include "PHY/TOOLS/lte_phy_scope.h" +#include "dummy_functions.c" -PHY_VARS_eNB *eNB; -PHY_VARS_UE *UE; - +#include "common/config/config_load_configmodule.h" double cpuf; @@ -78,9 +84,114 @@ double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ +int nfapi_mode = 0; + +extern void fep_full(RU_t *ru); +extern void ru_fep_full_2thread(RU_t *ru); + +nfapi_dl_config_request_t DL_req; +nfapi_ul_config_request_t UL_req; +nfapi_hi_dci0_request_t HI_DCI0_req; +nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_DL_PDU]; +nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; +nfapi_tx_request_t TX_req; +Sched_Rsp_t sched_resp; + +int codingw = 0; + +void +fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint8_t cqi_req, + uint8_t p_eNB, + uint8_t cqi_ReportModeAperiodic, + uint8_t betaOffset_CQI_Index, + uint8_t betaOffset_RI_Index, + uint8_t dl_cqi_pmi_size, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t modulation_type, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) +{ + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + // printf("filling ul_config_pdu: modulation type %d, rvidx %d\n",modulation_type,redundancy_version); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = resource_block_start; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = number_of_resource_blocks; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = modulation_type; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = cyclic_shift_2_for_drms; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = frequency_hopping_bits; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = new_data_indication; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = redundancy_version; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = harq_process_number; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = ul_tx_mode; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = current_tx_nb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = n_srs; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = size; + + if (cqi_req == 1) { + // Add CQI portion + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type = 1; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); + + if (p_eNB <= 2 + && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; + else if (p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; + else if (p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; + + for (int ri = 0; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + ri++) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; + + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = betaOffset_CQI_Index; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = betaOffset_RI_Index; + } +} - -void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mcs,int ndi,int cqi_flag) { +void fill_ulsch_dci(PHY_VARS_eNB *eNB, + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint16_t rnti, + void *UL_dci, + int first_rb, + int nb_rb, + int mcs, + int modulation_type, + int ndi, + int cqi_flag, + uint8_t beta_CQI, + uint8_t beta_RI, + uint8_t cqi_size) { + + nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body; + int harq_pid = ((frame*10)+subframe)&7; + + // printf("ulsch in frame %d, subframe %d => harq_pid %d, mcs %d, ndi %d\n",frame,subframe,harq_pid,mcs,ndi); switch (eNB->frame_parms.N_RB_UL) { case 6: @@ -162,6 +273,36 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mc break; } + fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0], + cqi_flag&1, + 1, // p_eNB + 0, // reportmode Aperiodic + beta_CQI, + beta_RI, + cqi_size, + //cc, + //UE_template->physicalConfigDedicated, + 1, + 0, + 14, // rnti + first_rb, // resource_block_start + nb_rb, // number_of_resource_blocks + modulation_type, + 0, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + mcs>28?(mcs-28):0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL(mcs,nb_rb)); + + sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->number_of_pdus=1; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); @@ -172,22 +313,26 @@ int main(int argc, char **argv) char c; int i,j,aa,u; - + PHY_VARS_eNB *eNB; + PHY_VARS_UE *UE; + RU_t *ru; int aarx,aatx; double channelx,channely; double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; double input_snr_step=.2,snr_int=30; double blerr; - + int rvidx[8]={0,2,3,1,0,2,3,1}; int **txdata; LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720],s_im0[30720],r_re0[30720],r_im0[30720]; double s_re1[30720],s_im1[30720],r_re1[30720],r_im1[30720]; + double r_re2[30720],r_im2[30720]; + double r_re3[30720],r_im3[30720]; double *s_re[2]={s_re0,s_re1}; double *s_im[2]={s_im0,s_im1}; - double *r_re[2]={r_re0,r_re1}; - double *r_im[2]={r_im0,r_im1}; + double *r_re[4]={r_re0,r_re1,r_re2,r_re3}; + double *r_im[4]={r_im0,r_im1,r_im2,r_im3}; double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel double iqim=0.0; uint8_t extended_prefix_flag=0; @@ -254,8 +399,7 @@ int main(int argc, char **argv) uint8_t N_RB_DL=25,osf=1; //uint8_t cyclic_shift = 0; - uint8_t cooperation_flag = 0; //0 no cooperation, 1 delay diversity, 2 Alamouti - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; uint8_t tdd_config=3,frame_type=FDD; uint8_t N0=30; @@ -282,10 +426,24 @@ int main(int argc, char **argv) opp_enabled=1; // to enable the time meas + sched_resp.DL_req = &DL_req; + sched_resp.UL_req = &UL_req; + sched_resp.HI_DCI0_req = &HI_DCI0_req; + sched_resp.TX_req = &TX_req; + memset((void*)&DL_req,0,sizeof(DL_req)); + memset((void*)&UL_req,0,sizeof(UL_req)); + memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void*)&TX_req,0,sizeof(TX_req)); + + UL_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdu_list; + TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; + cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + AssertFatal(load_configmodule(argc,argv) != NULL, + "cannot load configuration module, exiting\n"); logInit(); /* @@ -565,20 +723,44 @@ int main(int argc, char **argv) break; } } + RC.nb_L1_inst = 1; + RC.nb_RU = 1; - lte_param_init(1, - 1, + lte_param_init(&eNB,&UE,&ru, + 1, + 1, n_rx, + 1, 1, extended_prefix_flag, frame_type, 0, tdd_config, N_RB_DL, + 4, threequarter_fs, osf, 0); + RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); + RC.ru = (RU_t **)malloc(sizeof(RC.ru)); + RC.eNB[0][0] = eNB; + RC.ru[0] = ru; + for (int k=0;k<eNB->RU_list[0]->nb_rx;k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; + + memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); + + printf("Setting indication lists\n"); + eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; + eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; + + printf("lte_param_init done\n"); + // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE PHY_vars_UE_g = (PHY_VARS_UE***)malloc(sizeof(PHY_VARS_UE**)); PHY_vars_UE_g[0] = (PHY_VARS_UE**) malloc(sizeof(PHY_VARS_UE*)); @@ -587,7 +769,7 @@ int main(int argc, char **argv) if (nb_rb_set == 0) nb_rb = eNB->frame_parms.N_RB_UL; - printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0][0]); + printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0]); printf("Setting mcs = %d\n",mcs); printf("n_frames = %d\n", n_frames); @@ -670,7 +852,6 @@ int main(int argc, char **argv) eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0; eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 0; - eNB->cooperation_flag = cooperation_flag; eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK; eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI; @@ -688,8 +869,8 @@ int main(int argc, char **argv) printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8); - UE2eNB = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, - UE->frame_parms.nb_antennas_rx, + UE2eNB = new_channel_desc_scm(1, + n_rx, channel_model, N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), @@ -700,8 +881,9 @@ int main(int argc, char **argv) UE2eNB->max_Doppler = maxDoppler; // NN: N_RB_UL has to be defined in ulsim - eNB->ulsch[0] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + for (int k=0;k<NUMBER_OF_UE_MAX;k++) eNB->ulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); + printf("ULSCH %p\n",UE->ulsch[0]); if (parallel_flag == 1) { extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); @@ -751,7 +933,7 @@ int main(int argc, char **argv) UE->mac_enabled=0; - + eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; @@ -761,9 +943,9 @@ int main(int argc, char **argv) proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; - proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; - proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; printf("Init UL hopping UE\n"); init_ul_hopping(&UE->frame_parms); @@ -775,34 +957,6 @@ int main(int argc, char **argv) UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; - /* - generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, - 14, - proc_rxtx->subframe_tx, - format0, - UE, - proc_rxtx_ue, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - 0, - srs_flag); - - // printf("RIV %d\n",UL_alloc_pdu.rballoc); - - generate_eNB_ulsch_params_from_dci(eNB,proc_rxtx, - (void *)&UL_alloc_pdu, - 14, - format0, - 0, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - srs_flag); - */ - coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb; if (cqi_flag == 1) coded_bits_per_codeword-=UE->ulsch[0]->O; @@ -915,7 +1069,6 @@ int main(int argc, char **argv) reset_meas(&UE->ulsch_multiplexing_stats); reset_meas(&eNB->phy_proc_rx); - reset_meas(&eNB->ofdm_demod_stats); reset_meas(&eNB->ulsch_channel_estimation_stats); reset_meas(&eNB->ulsch_freq_offset_estimation_stats); reset_meas(&eNB->rx_dft_stats); @@ -932,7 +1085,7 @@ int main(int argc, char **argv) reset_meas(&eNB->ulsch_tc_intl1_stats); reset_meas(&eNB->ulsch_tc_intl2_stats); - // initialization + // initialization struct list time_vector_tx; initialize(&time_vector_tx); struct list time_vector_tx_ifft; @@ -965,19 +1118,38 @@ int main(int argc, char **argv) round=0; while (round < 4) { + proc_rxtx->frame_rx=1; + proc_rxtx->subframe_rx=subframe; + + proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); + proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); + + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); + proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; + eNB->ulsch[0]->harq_processes[harq_pid]->round=round; UE->ulsch[0]->harq_processes[harq_pid]->round=round; - // printf("Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_rx,proc_rxtx_ue->frame_rx); + if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); round_trials[round]++; + UL_req.sfn_sf = (1<<4)+subframe; + if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe); + + int modulation_type; + if (mcs < 11) modulation_type = 2; + else if (mcs < 21) modulation_type = 4; + else if (mcs < 29) modulation_type = 6; - fill_ulsch_dci(eNB,(void*)&UL_alloc_pdu,first_rb,nb_rb,mcs,ndi,cqi_flag); + fill_ulsch_dci(eNB,proc_rxtx->frame_rx,subframe,&sched_resp,14,(void*)&UL_alloc_pdu,first_rb,nb_rb,(round==0)?mcs:(28+rvidx[round]),modulation_type,ndi,cqi_flag,beta_CQI,beta_RI,cqi_size); UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; + if (n_frames==1) printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx); generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, 14, - proc_rxtx->subframe_tx, + (subframe+6)%10, format0, UE, proc_rxtx_ue, @@ -988,17 +1160,11 @@ int main(int argc, char **argv) 0, srs_flag); - generate_eNB_ulsch_params_from_dci(eNB,proc_rxtx, - (void *)&UL_alloc_pdu, - 14, - format0, - 0, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - srs_flag); - eNB->ulsch[0]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; + sched_resp.subframe=(subframe+6)%10; + sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; + + schedule_response(&sched_resp); + ///////////////////// if (abstx) { @@ -1020,90 +1186,29 @@ int main(int argc, char **argv) eNB->proc.frame_rx = 1; eNB->proc.subframe_rx = subframe; + ru->proc.frame_rx = 1; + ru->proc.subframe_rx = subframe; + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; - phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx,no_relay); + phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx); - /* - if (srs_flag) - generate_srs_tx(UE,0,AMP,subframe); - - generate_drs_pusch(UE,proc_rxtx_ue,0, - AMP,subframe, - UE->ulsch[0]->harq_processes[harq_pid]->first_rb, - UE->ulsch[0]->harq_processes[harq_pid]->nb_rb, - 0); - - if ((cqi_flag == 1) && (n_frames == 1) ) { - printf("CQI information (O %d) %d %d\n",UE->ulsch[0]->O, - UE->ulsch[0]->o[0],UE->ulsch[0]->o[1]); - print_CQI(UE->ulsch[0]->o,UE->ulsch[0]->uci_format,UE->frame_parms.N_RB_DL,0); - } - - UE->ulsch[0]->o_ACK[0] = taus()&1; - - start_meas(&UE->ulsch_encoding_stats); - - if (ulsch_encoding(input_buffer, - UE, - harq_pid, - eNB_id, - 2, // transmission mode - control_only_flag, - 1// Nbundled - )==-1) { - printf("ulsim.c Problem with ulsch_encoding\n"); - exit(-1); - } - - stop_meas(&UE->ulsch_encoding_stats); - - start_meas(&UE->ulsch_modulation_stats); - ulsch_modulation(UE->common_vars.txdataF,AMP, - proc_rxtx_ue->frame_tx,subframe,&UE->frame_parms, - UE->ulsch[0]); - stop_meas(&UE->ulsch_modulation_stats); - */ - - - - - /* - for (aa=0; aa<1; aa++) { - if (frame_parms->Ncp == EXTENDED) - PHY_ofdm_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX], // input - &txdata[aa][eNB->frame_parms.samples_per_tti*subframe], // output - UE->frame_parms.ofdm_symbol_size, - nsymb, // number of symbols - UE->frame_parms.nb_prefix_samples, // number of prefix samples - CYCLIC_PREFIX); - else - normal_prefix_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX], - &txdata[aa][eNB->frame_parms.samples_per_tti*subframe], - nsymb, - frame_parms); - - - apply_7_5_kHz(UE,UE->common_vars.txdata[aa],subframe<<1); - apply_7_5_kHz(UE,UE->common_vars.txdata[aa],1+(subframe<<1)); - -*/ tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], eNB->frame_parms.samples_per_tti); - - + + if (n_frames==1) { write_output("txsigF0UL.m","txsF0", &UE->common_vars.txdataF[0][eNB->frame_parms.ofdm_symbol_size*nsymb*subframe],eNB->frame_parms.ofdm_symbol_size*nsymb,1, 1); //write_output("txsigF1.m","txsF1", UE->common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1); } - + } // input_fd == NULL - + tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev); if (n_frames==1) { @@ -1113,11 +1218,11 @@ int main(int argc, char **argv) //AWGN //Set target wideband RX noise level to N0 - sigma2_dB = N0;//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; + sigma2_dB = N0;//-10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12));//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); // compute tx_gain to achieve target SNR (per resource element!) - tx_gain = sqrt(pow(10.0,.1*(N0+SNR))*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); + tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);//*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); if (n_frames==1) @@ -1128,8 +1233,8 @@ int main(int argc, char **argv) for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -1186,38 +1291,38 @@ int main(int argc, char **argv) for (i=0; i<eNB->frame_parms.samples_per_tti; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - ((short*) &eNB->common_vars.rxdata[0][aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) &eNB->common_vars.rxdata[0][aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( + ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( sigma2/2)*gaussdouble(0.0,1.0)); } } - if (n_frames==1) { + if (n_frames<=10) { printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int*) - &eNB->common_vars.rxdata[0][0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); - printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&eNB->common_vars.rxdata[0][0][160+(eNB->frame_parms.samples_per_tti*subframe)], + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); } - SNRmeas = 10*log10(((double)signal_energy((int*)&eNB->common_vars.rxdata[0][0][160+(eNB->frame_parms.samples_per_tti*subframe)], + SNRmeas = 10*log10(((double)signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int*) - &eNB->common_vars.rxdata[0][0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)) - 1)+10*log10(eNB->frame_parms.N_RB_UL/nb_rb); - if (n_frames==1) { + if (n_frames<=10) { printf("SNRmeas %f\n",SNRmeas); - // write_output("rxsig0UL.m","rxs0", &eNB->common_vars.rxdata[0][0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - //write_output("rxsig1UL.m","rxs1", &eNB->common_vars.rxdata[0][0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + write_output("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) write_output("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); } - eNB->fep = (parallel_flag == 1) ? eNB_fep_full_2thread : eNB_fep_full; + ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->do_prach = NULL; - phy_procedures_eNB_common_RX(eNB,proc_rxtx); - phy_procedures_eNB_uespec_RX(eNB,proc_rxtx,no_relay); + + ru->feprx(ru); + phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); if (cqi_flag > 0) { @@ -1249,10 +1354,10 @@ int main(int argc, char **argv) // printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]); - + // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { - - if (eNB->ulsch[0]->harq_processes[harq_pid]->round == 0) { + + if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { // avg_iter += ret; iter_trials++; @@ -1264,7 +1369,7 @@ int main(int argc, char **argv) print_CQI(eNB->ulsch[0]->harq_processes[harq_pid]->o, eNB->ulsch[0]->harq_processes[harq_pid]->uci_format,0,eNB->frame_parms.N_RB_DL); - dump_ulsch(eNB,proc_rxtx,0); + dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); exit(-1); } @@ -1293,18 +1398,17 @@ int main(int argc, char **argv) eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]); } - dump_ulsch(eNB,proc_rxtx,0); - exit(-1); + dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); + if (round == 4) exit(-1); } - // printf("round %d errors %d/%d\n",round,errs[round],trials); + if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); round++; if (n_frames==1) { printf("ULSCH in error in round %d\n",round); } } // ulsch error - } // round @@ -1324,7 +1428,7 @@ int main(int argc, char **argv) double t_rx = (double)eNB->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)eNB->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)ru->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)eNB->ulsch_demodulation_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_dec = (double)eNB->ulsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; @@ -1449,12 +1553,12 @@ int main(int argc, char **argv) tx_lev_dB, 20*log10(tx_gain), (double)N0, - eNB->measurements[0].n0_power_tot_dB, + eNB->measurements.n0_power_tot_dB, get_hundred_times_delta_IF(UE,eNB_id,harq_pid) , dB_fixed(eNB->pusch_vars[0]->ulsch_power[0]), dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]), - eNB->measurements->n0_power_dB[0], - eNB->measurements->n0_power_dB[1]); + eNB->measurements.n0_power_dB[0], + eNB->measurements.n0_power_dB[1]); effective_rate = ((double)(round_trials[0])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); @@ -1548,10 +1652,10 @@ int main(int argc, char **argv) printf("Total PHY proc rx :%f us (%d trials)\n",(double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_rx.trials); printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - std_phy_proc_rx_fft = sqrt((double)eNB->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ofdm_demod_stats.trials - pow((double)eNB->ofdm_demod_stats.diff/eNB->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_demod time :%f us (%d trials)\n",(double)eNB->ofdm_demod_stats.diff/eNB->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, - eNB->ofdm_demod_stats.trials); + std_phy_proc_rx_fft = sqrt((double)ru->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/ru->ofdm_demod_stats.trials - pow((double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); + printf("OFDM_demod time :%f us (%d trials)\n",(double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, + ru->ofdm_demod_stats.trials); printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); std_phy_proc_rx_demod = sqrt((double)eNB->ulsch_demodulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, 2)/eNB->ulsch_demodulation_stats.trials - pow((double)eNB->ulsch_demodulation_stats.diff/eNB->ulsch_demodulation_stats.trials/cpu_freq_GHz/1000,2)); @@ -1672,7 +1776,7 @@ int main(int argc, char **argv) UE->ulsch_modulation_stats.trials, UE->ulsch_encoding_stats.trials, eNB->phy_proc_rx.trials, - eNB->ofdm_demod_stats.trials, + ru->ofdm_demod_stats.trials, eNB->ulsch_demodulation_stats.trials, eNB->ulsch_decoding_stats.trials ); @@ -1682,7 +1786,7 @@ int main(int argc, char **argv) get_time_meas_us(&UE->ulsch_modulation_stats), get_time_meas_us(&UE->ulsch_encoding_stats), get_time_meas_us(&eNB->phy_proc_rx), - get_time_meas_us(&eNB->ofdm_demod_stats), + get_time_meas_us(&ru->ofdm_demod_stats), get_time_meas_us(&eNB->ulsch_demodulation_stats), get_time_meas_us(&eNB->ulsch_decoding_stats) ); @@ -1733,7 +1837,7 @@ int main(int argc, char **argv) oai_exit=1; - pthread_cond_signal(&eNB->proc.cond_fep); + pthread_cond_signal(&ru->proc.cond_fep); if (abstx) { // ABSTRACTION fprintf(csv_fdUL,"];"); diff --git a/openair1/SIMULATION/RF/dac.c b/openair1/SIMULATION/RF/dac.c index 8cf6b496231d630df17437b3712fd0f617eb218a..b09bd20374bf7bec5df4143443a841472c3a2876 100644 --- a/openair1/SIMULATION/RF/dac.c +++ b/openair1/SIMULATION/RF/dac.c @@ -22,8 +22,8 @@ //#define DEBUG_DAC 1 #include <math.h> #include <stdio.h> -#include "PHY/TOOLS/defs.h" - +#include "PHY/TOOLS/tools_defs.h" +#include "rf.h" void dac(double *s_re[2], double *s_im[2], uint32_t **input, @@ -91,10 +91,8 @@ double dac_fixed_gain(double *s_re[2], int i; int aa; - double amp,amp1_local,*amp1p; - - amp = //sqrt(NB_RE)*pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); //this is amp per tx antenna - pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); //this is amp per tx antenna + double amp1_local,*amp1p; + double amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); //this is amp per tx antenna if (amp1==NULL) amp1p = &1_local; else amp1p = amp1; @@ -123,7 +121,7 @@ double dac_fixed_gain(double *s_re[2], //printf("DL: amp1 %f dB (%d,%d), tx_power %f\n",20*log10(amp1),input_offset,input_offset_meas,txpwr_dBm); */ - + // printf("DAC: amp/amp1p %f amp1 %f dB (%d,%d), tx_power %f\n",amp/(*amp1p),20*log10(*amp1p),input_offset,input_offset_meas,txpwr_dBm); for (i=0; i<length; i++) { for (aa=0; aa<nb_tx_antennas; aa++) { s_re[aa][i] = amp*((double)(((short *)input[aa]))[((i+input_offset)<<1)])/(*amp1p); @@ -131,7 +129,7 @@ double dac_fixed_gain(double *s_re[2], } } - // printf("ener %e\n",signal_energy_fp(s_re,s_im,nb_tx_antennas,length,0)); + // printf("ener %e\n",signal_energy_fp(s_re,s_im,nb_tx_antennas,length<length_meas?length:length_meas,0)); return(signal_energy_fp(s_re,s_im,nb_tx_antennas,length<length_meas?length:length_meas,0)/NB_RE); } diff --git a/openair1/SIMULATION/RF/rf.c b/openair1/SIMULATION/RF/rf.c index 3cf770ac7cf8c1a0f3038626807dedf18fccdef2..51b7e7524d4bb2bc953fc908a4b2fd1a5a0aa5ee 100644 --- a/openair1/SIMULATION/RF/rf.c +++ b/openair1/SIMULATION/RF/rf.c @@ -19,14 +19,13 @@ * contact@openairinterface.org */ -//#include "defs.h" #include <stdio.h> #include <stdlib.h> #include <math.h> //#include "PHY/defs.h" -#include "SIMULATION/TOOLS/defs.h" - +#include "SIMULATION/TOOLS/sim.h" +#include "rf.h" /* extern void randominit(void); extern double gaussdouble(double,double); diff --git a/openair1/SIMULATION/RF/defs.h b/openair1/SIMULATION/RF/rf.h similarity index 98% rename from openair1/SIMULATION/RF/defs.h rename to openair1/SIMULATION/RF/rf.h index 05e74647a06c0f6c4ac17d61369eb76fdb56c841..65055bc71a4257495cec26f333952103b630cd16 100644 --- a/openair1/SIMULATION/RF/defs.h +++ b/openair1/SIMULATION/RF/rf.h @@ -76,7 +76,7 @@ void adc(double *r_re[2], void dac(double *s_re[2], double *s_im[2], - int **input, + unsigned int **input, unsigned int input_offset, unsigned int nb_tx_antennas, unsigned int length, @@ -87,7 +87,7 @@ void dac(double *s_re[2], double dac_fixed_gain(double *s_re[2], double *s_im[2], - int **input, + unsigned int **input, unsigned int input_offset, unsigned int nb_tx_antennas, unsigned int length, diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c index 7e99371c3736dae18f92ac18c2b6536347506087..6b846bb2d5db9e584d54cfd027792506d6363ae8 100644 --- a/openair1/SIMULATION/TOOLS/abstraction.c +++ b/openair1/SIMULATION/TOOLS/abstraction.c @@ -26,8 +26,9 @@ #include <string.h> #include <errno.h> -#include "PHY/TOOLS/defs.h" -#include "defs.h" +#include "SIMULATION/TOOLS/sim.h" +#include "PHY/TOOLS/tools_defs.h" +#include "assertions.h" // NEW code with lookup table for sin/cos based on delay profile (TO BE TESTED) diff --git a/openair1/SIMULATION/TOOLS/multipath_channel.c b/openair1/SIMULATION/TOOLS/multipath_channel.c index 757d5023de214d5ae8a823b3a3dd03e6ca045b9e..02f4abbc7e25285ca3cfa291ffdd52cd275e6126 100644 --- a/openair1/SIMULATION/TOOLS/multipath_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_channel.c @@ -23,8 +23,9 @@ #include <stdlib.h> #include <math.h> #include <string.h> -#include "defs.h" -#include "SIMULATION/RF/defs.h" +#include "PHY/TOOLS/tools_defs.h" +#include "SIMULATION/RF/rf.h" +#include "sim.h" //#define DEBUG_CH uint8_t multipath_channel_nosigconv(channel_desc_t *desc) diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c index c2078b91d478763895c25771f24fe109260e4eb6..daa3462b1c85c1f4cf6ec22fcb29cea1e740c6e3 100644 --- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c @@ -23,8 +23,8 @@ #include <stdlib.h> #include <math.h> #include <string.h> -#include "defs.h" -#include "SIMULATION/RF/defs.h" +#include "sim.h" +#include "SIMULATION/RF/rf.h" #include <complex.h> void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length); diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 222a196e20b9c0e171ecd3ac5c5177a88138e889..dc8df153159c58cd75506054941237c4701439fe 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -26,12 +26,14 @@ #include <string.h> -#include "PHY/TOOLS/defs.h" -#include "defs.h" +#include "PHY/TOOLS/tools_defs.h" +#include "sim.h" #include "scm_corrmat.h" #include "UTIL/LOG/log.h" //#define DEBUG_CH +#include "assertions.h" + extern void print_shorts(char *s,__m128i *x); void fill_channel_desc(channel_desc_t *chan_desc, @@ -1210,10 +1212,8 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { struct complex anew[NB_ANTENNAS_TX*NB_ANTENNAS_RX],acorr[NB_ANTENNAS_TX*NB_ANTENNAS_RX]; struct complex phase, alpha, beta; - if ((desc->nb_tx>NB_ANTENNAS_TX) || (desc->nb_rx > NB_ANTENNAS_RX)) { - LOG_E(PHY,"random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); - return(-1); - } + AssertFatal(desc->nb_tx<=NB_ANTENNAS_TX && desc->nb_rx <= NB_ANTENNAS_RX, + "random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); start_meas(&desc->random_channel); for (i=0;i<(int)desc->nb_taps;i++) { @@ -1372,8 +1372,7 @@ double N_RB2sampling_rate(uint16_t N_RB) break; default: - LOG_E(PHY,"Unknown N_PRB\n"); - return(-1); + AssertFatal(1==0,"Unknown N_PRB %d",N_RB); } return(sampling_rate); diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 0fc01a8d3132233ff34502b71466e4a3886adb3a..6dcdd9418e2bf703a1d21d2780c184dc5cd2deeb 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -24,7 +24,7 @@ #include <math.h> #include <time.h> -#include "defs.h" +#include "sim.h" static unsigned int seed, iy, ir[98]; /* diff --git a/openair1/SIMULATION/TOOLS/defs.h b/openair1/SIMULATION/TOOLS/sim.h similarity index 99% rename from openair1/SIMULATION/TOOLS/defs.h rename to openair1/SIMULATION/TOOLS/sim.h index a958c6b4ebcfb2737c58f30fff63d6475d8446d3..420e5d0072f193a42057902ceae63d2b54cf1a51 100644 --- a/openair1/SIMULATION/TOOLS/defs.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -21,7 +21,7 @@ #ifndef __SIMULATION_TOOLS_DEFS_H__ #define __SIMULATION_TOOLS_DEFS_H__ -#include "PHY/defs.h" +#include "PHY/defs_common.h" /** @defgroup _numerical_ Useful Numerical Functions *@{ diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index 3a73000e505aa5452bd53543669bf3bec0e0ec8e..fb229bf951b58d757ab0c9f2253a110dc1974baf 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -34,7 +34,7 @@ #include "RadioResourceConfigDedicated.h" #include "MeasGapConfig.h" #include "TDD-Config.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-SubframeConfigList.h" #endif @@ -356,7 +356,7 @@ typedef struct { TDD_Config_t *tdd_Config, uint8_t *SIwindowsize, uint16_t *SIperiod -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , MBMS_flag_t MBMS_Flag, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList, @@ -364,10 +364,20 @@ typedef struct { struct PMCH_InfoList_r9 *pmch_InfoList #endif ); - unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, const unsigned int,char*); + unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, const unsigned int,char* +#ifdef Rel14 + ,uint32_t + ,uint32_t +#endif + ); void (*mac_rlc_data_ind)(module_id_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* ); mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, sub_frame_t subframeP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP, - logical_chan_id_t channel_idP, tb_size_t tb_sizeP); + logical_chan_id_t channel_idP, tb_size_t tb_sizeP +#ifdef Rel14 + ,uint32_t sourceL2Id + ,uint32_t destinationL2Id +#endif + ); signed int (*rrc_rlc_data_req)(module_id_t, rb_id_t, mui_t, confirm_t, sdu_size_t, char *); void (*rrc_rlc_register_rrc) (void (*rrc_data_indP)(module_id_t , rb_id_t , sdu_size_t , char* ), void (*rrc_data_confP) (module_id_t , rb_id_t , mui_t ) ) ; diff --git a/openair2/COMMON/phy_messages_types.h b/openair2/COMMON/phy_messages_types.h index c425efa89cb38b88fe08c804ecbcc11bf0e29ecb..1f040a0a773e00163df53a660af70c799629f5d2 100644 --- a/openair2/COMMON/phy_messages_types.h +++ b/openair2/COMMON/phy_messages_types.h @@ -29,10 +29,8 @@ #ifndef PHY_MESSAGES_TYPES_H_ #define PHY_MESSAGES_TYPES_H_ -#include "PHY/impl_defs_lte.h" -#if ENABLE_RAL -#include "ral_messages_types.h" //LG: MIH moved from repository/trunk to repository/extras -#endif +#include "PHY/defs_common.h" + //-------------------------------------------------------------------------------------------// // Defines to access message fields. #define PHY_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.phy_configuration_req diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index f4004bdbf991c4c87bec639aacfb13d3071caf76..917c149833f9d21df65dc988c70fa0ec14007078 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -69,18 +69,24 @@ #ifdef LARGE_SCALE # define MAX_MOBILES_PER_ENB 128 -//# define MAX_RG 2 +# define MAX_MOBILES_PER_ENB_NB_IoT 128 +# define MAX_eNB 2 #else # define MAX_MOBILES_PER_ENB 16 -//# define MAX_RG 2 +# define MAX_MOBILES_PER_ENB_NB_IoT 16 +# define MAX_eNB 2 #endif #define MAX_MANAGED_ENB_PER_MOBILE 2 +///NB-IOT +#define NB_RB_MAX_NB_IOT (maxDRB_NB_r13 + 3) //MP: NB_IoT --> 2(DRB)+3(SRBs - 2 is not used) = 5 + + #define DEFAULT_RAB_ID 1 #define NB_RB_MAX (maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */ -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #define NB_RB_MBMS_MAX (maxSessionPerPMCH*maxServiceCount) #else // Do not allocate unused memory diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index cc46598cbe7aab76ca6cf8822bb94fbabca6c398..3f736e5b3cf5406c1b22d930142320aa393282dc 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -69,6 +69,7 @@ typedef uint32_t frame_t; typedef int32_t sframe_t; typedef uint32_t sub_frame_t; typedef uint16_t module_id_t; +typedef uint8_t slice_id_t; typedef uint8_t eNB_index_t; typedef uint16_t ue_id_t; typedef int16_t smodule_id_t; @@ -87,6 +88,10 @@ typedef boolean_t srb_flag_t; #define SRB_FLAG_NO FALSE #define SRB_FLAG_YES TRUE +typedef boolean_t sl_discovery_flag_t; +#define SL_DISCOVERY_FLAG_NO FALSE +#define SL_DISCOVERY_FLAG_YES TRUE + typedef enum link_direction_e { UNKNOWN_DIR = 0, DIR_UPLINK = 1, @@ -99,6 +104,15 @@ typedef enum rb_type_e { RADIO_ACCESS_BEARER = 2 } rb_type_t; +typedef enum { + CR_ROUND = 0, + CR_SRB12 = 1, + CR_HOL = 2, + CR_LC = 3, + CR_CQI = 4, + CR_NUM = 5 +} sorting_criterion_t; + //----------------------------------------------------------------------------- // PHY TYPES //----------------------------------------------------------------------------- @@ -154,7 +168,9 @@ typedef enum ip_traffic_type_e { TRAFFIC_IPV4_TYPE_UNICAST = 5, TRAFFIC_IPV4_TYPE_MULTICAST = 6, TRAFFIC_IPV4_TYPE_BROADCAST = 7, - TRAFFIC_IPV4_TYPE_UNKNOWN = 8 + TRAFFIC_IPV4_TYPE_UNKNOWN = 8, + TRAFFIC_PC5S_SIGNALLING = 9, + TRAFFIC_PC5S_SESSION_INIT = 10 } ip_traffic_type_t; //----------------------------------------------------------------------------- diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index be3d18c996126583c79b6df83f84754a34116dac..08ea93f427add5aa6dbd032e54180848cb3e85da 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -54,6 +54,7 @@ MESSAGE_DEF(RRC_STATE_IND, MESSAGE_PRIORITY_MED, RrcStateInd, //-------------------------------------------------------------------------------------------// // eNB: ENB_APP -> RRC messages MESSAGE_DEF(RRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED, RrcConfigurationReq, rrc_configuration_req) +MESSAGE_DEF(NBIOTRRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED, NbIoTRrcConfigurationReq, nbiotrrc_configuration_req) // UE: NAS -> RRC messages MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefreshReq, nas_kenb_refresh_req) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 79edbd320941b18f427e4c62b6cf8933dfe03e07..7ef9a960f92fbbc687f554932abd664a652a16a0 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -37,6 +37,12 @@ #else #include "RRC/LITE/MESSAGES/SystemInformationBlockType2.h" #endif +#include "SL-OffsetIndicator-r12.h" +#include "SubframeBitmapSL-r12.h" +#include "SL-CP-Len-r12.h" +#include "SL-PeriodComm-r12.h" +#include "SL-DiscResourcePool-r12.h" + //-------------------------------------------------------------------------------------------// // Messages for RRC logging @@ -62,6 +68,8 @@ typedef UL_DCCH_Message_t RrcUlDcchMessage; #define RRC_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_configuration_req +#define NBIOTRRC_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nbiotrrc_configuration_req + #define NAS_KENB_REFRESH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_kenb_refresh_req #define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req #define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req @@ -115,7 +123,7 @@ typedef struct RrcConfigurationReq_s { long pucch_delta_shift[MAX_NUM_CCs]; long pucch_nRB_CQI[MAX_NUM_CCs]; long pucch_nCS_AN[MAX_NUM_CCs]; -//#if !defined(Rel10) && !defined(Rel14) +//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) long pucch_n1_AN[MAX_NUM_CCs]; //#endif long pdsch_referenceSignalPower[MAX_NUM_CCs]; @@ -167,8 +175,126 @@ typedef struct RrcConfigurationReq_s { long ue_TimersAndConstants_n311[MAX_NUM_CCs]; long ue_TransmissionMode[MAX_NUM_CCs]; long ue_multiple_max[MAX_NUM_CCs]; + + //TTN - for D2D + //SIB18 + e_SL_CP_Len_r12 rxPool_sc_CP_Len[MAX_NUM_CCs]; + e_SL_PeriodComm_r12 rxPool_sc_Period[MAX_NUM_CCs]; + e_SL_CP_Len_r12 rxPool_data_CP_Len[MAX_NUM_CCs]; + long rxPool_ResourceConfig_prb_Num[MAX_NUM_CCs]; + long rxPool_ResourceConfig_prb_Start[MAX_NUM_CCs]; + long rxPool_ResourceConfig_prb_End[MAX_NUM_CCs]; + SL_OffsetIndicator_r12_PR rxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; + long rxPool_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; + SubframeBitmapSL_r12_PR rxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; + char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; + long rxPool_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; + long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; + + //SIB19 + //for discRxPool + SL_CP_Len_r12_t discRxPool_cp_Len[MAX_NUM_CCs]; + e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPool_discPeriod[MAX_NUM_CCs]; + long discRxPool_numRetx[MAX_NUM_CCs]; + long discRxPool_numRepetition[MAX_NUM_CCs]; + long discRxPool_ResourceConfig_prb_Num[MAX_NUM_CCs]; + long discRxPool_ResourceConfig_prb_Start[MAX_NUM_CCs]; + long discRxPool_ResourceConfig_prb_End[MAX_NUM_CCs]; + SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; + long discRxPool_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; + SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; + char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; + long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; + long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; + //for discRxPoolPS + SL_CP_Len_r12_t discRxPoolPS_cp_Len[MAX_NUM_CCs]; + e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPoolPS_discPeriod[MAX_NUM_CCs]; + long discRxPoolPS_numRetx[MAX_NUM_CCs]; + long discRxPoolPS_numRepetition[MAX_NUM_CCs]; + long discRxPoolPS_ResourceConfig_prb_Num[MAX_NUM_CCs]; + long discRxPoolPS_ResourceConfig_prb_Start[MAX_NUM_CCs]; + long discRxPoolPS_ResourceConfig_prb_End[MAX_NUM_CCs]; + SL_OffsetIndicator_r12_PR discRxPoolPS_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; + long discRxPoolPS_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; + SubframeBitmapSL_r12_PR discRxPoolPS_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; + char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; + long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; + long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; } RrcConfigurationReq; +#define MAX_NUM_NBIOT_CELEVELS 3 + +typedef struct NbIoTRrcConfigurationReq_s { + uint32_t cell_identity; + + uint16_t tac; + + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + lte_frame_type_t frame_type; + uint8_t tdd_config; + uint8_t tdd_config_s; + lte_prefix_type_t prefix_type; + lte_prefix_type_t prefix_type_UL; + int16_t eutra_band; + uint32_t downlink_frequency; + int32_t uplink_frequency_offset; + int16_t Nid_cell;// for testing, change later + int16_t N_RB_DL;// for testing, change later + //RACH + long rach_raResponseWindowSize_NB; + long rach_macContentionResolutionTimer_NB; + long rach_powerRampingStep_NB; + long rach_preambleInitialReceivedTargetPower_NB; + long rach_preambleTransMax_CE_NB; + //BCCH + long bcch_modificationPeriodCoeff_NB; + //PCCH + long pcch_defaultPagingCycle_NB; + long pcch_nB_NB; + long pcch_npdcch_NumRepetitionPaging_NB; + //NPRACH + long nprach_CP_Length; + long nprach_rsrp_range; + long nprach_Periodicity[MAX_NUM_NBIOT_CELEVELS]; + long nprach_StartTime[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierOffset[MAX_NUM_NBIOT_CELEVELS]; + long nprach_NumSubcarriers[MAX_NUM_NBIOT_CELEVELS]; + long numRepetitionsPerPreambleAttempt_NB[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierMSG3_RangeStart; + long maxNumPreambleAttemptCE_NB; + long npdcch_NumRepetitions_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_StartSF_CSS_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_Offset_RA[MAX_NUM_NBIOT_CELEVELS]; + //NPDSCH + long npdsch_nrs_Power; + //NPUSCH + long npusch_ack_nack_numRepetitions_NB; + long npusch_srs_SubframeConfig_NB; + long npusch_threeTone_CyclicShift_r13; + long npusch_sixTone_CyclicShift_r13; + BOOLEAN_t npusch_groupHoppingEnabled; + long npusch_groupAssignmentNPUSCH_r13; + + //DL_GapConfig + long dl_GapThreshold_NB; + long dl_GapPeriodicity_NB; + long dl_GapDurationCoeff_NB; + //Uplink power control Common + long npusch_p0_NominalNPUSCH; + long npusch_alpha; + long deltaPreambleMsg3; + //UE timers and constants + long ue_TimersAndConstants_t300_NB; + long ue_TimersAndConstants_t301_NB; + long ue_TimersAndConstants_t310_NB; + long ue_TimersAndConstants_t311_NB; + long ue_TimersAndConstants_n310_NB; + long ue_TimersAndConstants_n311_NB; +} NbIoTRrcConfigurationReq; + + // UE: NAS -> RRC messages typedef kenb_refresh_req_t NasKenbRefreshReq; typedef cell_info_req_t NasCellSelectionReq; diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h index a39953d8f77e777ca79b1e4644be41690ae3f799..d81bd87ed5f97b990caf7abfbc0dae4d2180182e 100644 --- a/openair2/COMMON/s1ap_messages_def.h +++ b/openair2/COMMON/s1ap_messages_def.h @@ -38,6 +38,7 @@ MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgTex MESSAGE_DEF(S1AP_PAGING_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_paging_log) MESSAGE_DEF(S1AP_E_RAB_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_request_log) MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_response_log) +MESSAGE_DEF(S1AP_E_RAB_ERROR_INDICATION_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_error_indication_log) /* eNB application layer -> S1AP messages */ MESSAGE_DEF(S1AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, s1ap_register_enb_req_t , s1ap_register_enb_req) diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 530365828dbaca39d594d5d278efb3cc73b29727..92d1ff4128fb5413dbd71de4e98eed9157eac15b 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -40,6 +40,10 @@ SUB_TASK_DEF(TASK_L2L1, TASK_PDCP_ENB, 200) /// Radio Resource Control task TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200) + +// Define here for now +TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200) + /// S1ap task /// RAL task for ENB TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index fcf9fb537c013180a016509d5873505b1b60c961..0545eeb3be11e59522aebcafb3161b4aaa61e60a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -17,7 +17,7 @@ *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org - */ + */ /*! \file flexran_agent_mac.c * \brief FlexRAN agent message handler for MAC layer @@ -31,16 +31,15 @@ #include "flexran_agent_common.h" #include "flexran_agent_mac_internal.h" #include "flexran_agent_net_comm.h" +#include "flexran_agent_timer.h" +#include "flexran_agent_ran_api.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/flexran_agent_mac_proto.h" -#include "LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h" +#include "LAYER2/MAC/mac_proto.h" #include "liblfds700.h" #include "log.h" - /*Flags showing if a mac agent has already been registered*/ unsigned int mac_agent_registered[NUM_MAX_ENB]; @@ -54,683 +53,595 @@ struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; -int flexran_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg){ - - // TODO: Must deal with sanitization of input - // TODO: Must check if RNTIs and cell ids of the request actually exist - // TODO: Must resolve conflicts among stats requests +int flexran_agent_mac_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report) { - int i; - err_code_t err_code; - xid_t xid; - uint32_t usec_interval, sec_interval; - //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 + // Protocol__FlexHeader *header; + int i, j, k; + int cc_id = 0; int enb_id = mod_id; - //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; - //UE_list_t *eNB_UE_list= &eNB->UE_list; - - report_config_t report_config; - - uint32_t ue_flags = 0; - uint32_t c_flags = 0; - - Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; - - Protocol__FlexStatsRequest *stats_req = input->stats_request_msg; - xid = (stats_req->header)->xid; - - // Check the type of request that is made - switch(stats_req->body_case) { - case PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ; - Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request; - if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF) { - /*Disable both periodic and continuous updates*/ - flexran_agent_disable_cont_mac_stats_update(mod_id); - flexran_agent_destroy_timer_by_task_id(xid); - *msg = NULL; - return 0; - } else { //One-off, periodical or continuous reporting - //Set the proper flags - ue_flags = comp_req->ue_report_flags; - c_flags = comp_req->cell_report_flags; - //Create a list of all eNB RNTIs and cells - - //Set the number of UEs and create list with their RNTIs stats configs - report_config.nr_ue = flexran_get_num_ues(mod_id); //eNB_UE_list->num_UEs - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; - report_config.ue_report_type[i].ue_report_flags = ue_flags; - } - //Set the number of CCs and create a list with the cell stats configs - report_config.nr_cc = MAX_NUM_CCs; - report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); - if (report_config.cc_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids - report_config.cc_report_type[i].cc_id = i; - report_config.cc_report_type[i].cc_report_flags = c_flags; - } - /* Check if request was periodical */ - if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) { - /* Create a one off flexran message as an argument for the periodical task */ - Protocol__FlexranMessage *timer_msg; - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - flexran_agent_mac_stats_request(enb_id, xid, &request_config, &timer_msg); - /* Create a timer */ - long timer_id = 0; - flexran_agent_timer_args_t *timer_args; - timer_args = malloc(sizeof(flexran_agent_timer_args_t)); - memset (timer_args, 0, sizeof(flexran_agent_timer_args_t)); - timer_args->mod_id = enb_id; - timer_args->msg = timer_msg; - /*Convert subframes to usec time*/ - usec_interval = 1000*comp_req->sf; - sec_interval = 0; - /*add seconds if required*/ - if (usec_interval >= 1000*1000) { - sec_interval = usec_interval/(1000*1000); - usec_interval = usec_interval%(1000*1000); - } - flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, flexran_agent_handle_timed_task,(void*) timer_args, &timer_id); - } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) { - /*If request was for continuous updates, disable the previous configuration and - set up a new one*/ - flexran_agent_disable_cont_mac_stats_update(mod_id); - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - flexran_agent_enable_cont_mac_stats_update(enb_id, xid, &request_config); - } - } - break; - case PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST:; - Protocol__FlexCellStatsRequest *cell_req = stats_req->cell_stats_request; - // UE report config will be blank - report_config.nr_ue = 0; - report_config.ue_report_type = NULL; - report_config.nr_cc = cell_req->n_cell; - report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); - if (report_config.cc_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids - report_config.cc_report_type[i].cc_id = cell_req->cell[i]; - report_config.cc_report_type[i].cc_report_flags = cell_req->flags; - } - break; - case PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST:; - Protocol__FlexUeStatsRequest *ue_req = stats_req->ue_stats_request; - // Cell report config will be blank - report_config.nr_cc = 0; - report_config.cc_report_type = NULL; - report_config.nr_ue = ue_req->n_rnti; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i]; - report_config.ue_report_type[i].ue_report_flags = ue_req->flags; - } - break; - default: - //TODO: Add appropriate error code - err_code = -100; - goto error; - } + /* Allocate memory for list of UE reports */ + if (report_config->nr_ue > 0) { - if (flexran_agent_mac_stats_reply(enb_id, xid, &report_config, msg) < 0 ){ - err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; - goto error; - } - free(report_config.ue_report_type); - free(report_config.cc_report_type); + for (i = 0; i < report_config->nr_ue; i++) { + + ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; + ue_report[i]->has_rnti = 1; + + /* Check flag for creation of buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { + //TODO should be automated + ue_report[i]->n_bsr = 4; + uint32_t *elem; + elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); + if (elem == NULL) + goto error; + for (j = 0; j < ue_report[i]->n_bsr; j++) { + // NN: we need to know the cc_id here, consider the first one + elem[j] = flexran_get_ue_bsr_ul_buffer_info (enb_id, i, j); + } + + ue_report[i]->bsr = elem; + } + + /* Check flag for creation of PHR report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { + ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; + ue_report[i]->has_phr = 1; + + } + + /* Check flag for creation of RLC buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { + ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs + Protocol__FlexRlcBsr ** rlc_reports; + rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report); + if (rlc_reports == NULL) + goto error; + + // NN: see LAYER2/openair2_proc.c for rlc status + for (j = 0; j < ue_report[i]->n_rlc_report; j++) { + + rlc_reports[j] = malloc(sizeof(Protocol__FlexRlcBsr)); + 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]->has_lc_id = 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 = 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; + //TODO:Set retransmission queue head of line delay in ms + rlc_reports[j]->retransmission_queue_hol_delay = 100; + rlc_reports[j]->has_retransmission_queue_hol_delay = 0; + //TODO DONE:Set current size of the pending message in bytes + rlc_reports[j]->status_pdu_size = flexran_get_num_pdus_buffer(enb_id , i, j + 1); + rlc_reports[j]->has_status_pdu_size = 1; + + } + // Add RLC buffer status reports to the full report + if (ue_report[i]->n_rlc_report > 0) + ue_report[i]->rlc_report = rlc_reports; + + + } + + /* Check flag for creation of MAC CE buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { + // TODO: Fill in the actual MAC CE buffer status report + ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; + // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the + // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values + // found in stats_common.pb-c.h. See + // flex_ce_type in FlexRAN specification + ue_report[i]->has_pending_mac_ces = 1; + + } + + /* Check flag for creation of DL CQI report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { + // TODO: Fill in the actual DL CQI report for the UE based on its configuration + Protocol__FlexDlCqiReport * dl_report; + dl_report = malloc(sizeof(Protocol__FlexDlCqiReport)); + if (dl_report == NULL) + goto error; + protocol__flex_dl_cqi_report__init(dl_report); + + dl_report->sfn_sn = flexran_get_sfn_sf(enb_id); + dl_report->has_sfn_sn = 1; + //Set the number of DL CQI reports for this UE. One for each CC + dl_report->n_csi_report = flexran_get_active_CC(enb_id,i); + dl_report->n_csi_report = 1 ; + //Create the actual CSI reports. + Protocol__FlexDlCsi **csi_reports; + csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); + if (csi_reports == NULL) + goto error; + for (j = 0; j < dl_report->n_csi_report; j++) { + + csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); + if (csi_reports[j] == NULL) + goto error; + protocol__flex_dl_csi__init(csi_reports[j]); + //The servCellIndex for this report + csi_reports[j]->serv_cell_index = j; + csi_reports[j]->has_serv_cell_index = 1; + //The rank indicator value for this cc + csi_reports[j]->ri = flexran_get_current_RI(enb_id,i,j); + csi_reports[j]->has_ri = 1; + //TODO: the type of CSI report based on the configuration of the UE + //For now we only support type P10, which only needs a wideband value + //The full set of types can be found in stats_common.pb-c.h and + //in the FlexRAN specifications + csi_reports[j]->type = PROTOCOL__FLEX_CSI_TYPE__FLCSIT_P10; + csi_reports[j]->has_type = 1; + csi_reports[j]->report_case = PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI; - return 0; + if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI){ - error : - LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code); - return err_code; -} + Protocol__FlexCsiP10 *csi10; + csi10 = malloc(sizeof(Protocol__FlexCsiP10)); + if (csi10 == NULL) + goto error; + protocol__flex_csi_p10__init(csi10); + //TODO: set the wideband value + // NN: this is also depends on cc_id + csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; + csi10->has_wb_cqi = 1; + //Add the type of measurements to the csi report in the proper union type + csi_reports[j]->p10csi = csi10; + } -int flexran_agent_mac_stats_request(mid_t mod_id, - xid_t xid, - const stats_request_config_t *report_config, - Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; - int i; + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI){ - Protocol__FlexStatsRequest *stats_request_msg; - stats_request_msg = malloc(sizeof(Protocol__FlexStatsRequest)); - if(stats_request_msg == NULL) - goto error; - protocol__flex_stats_request__init(stats_request_msg); - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REQUEST, &header) != 0) - goto error; + Protocol__FlexCsiP11 *csi11; + csi11 = malloc(sizeof(Protocol__FlexCsiP11)); + if (csi11 == NULL) + goto error; + protocol__flex_csi_p11__init(csi11); - stats_request_msg->header = header; + csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); + csi11->n_wb_cqi = 1; + csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); + // According To spec 36.213 - stats_request_msg->type = report_config->report_type; - stats_request_msg->has_type = 1; + if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { + // TODO PMI + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); + csi11->has_wb_pmi = 1; - switch (report_config->report_type) { - case PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS: - stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST; - Protocol__FlexCompleteStatsRequest *complete_stats; - complete_stats = malloc(sizeof(Protocol__FlexCompleteStatsRequest)); - if(complete_stats == NULL) - goto error; - protocol__flex_complete_stats_request__init(complete_stats); - complete_stats->report_frequency = report_config->report_frequency; - complete_stats->has_report_frequency = 1; - complete_stats->sf = report_config->period; - complete_stats->has_sf = 1; - complete_stats->has_cell_report_flags = 1; - complete_stats->has_ue_report_flags = 1; - if (report_config->config->nr_cc > 0) { - complete_stats->cell_report_flags = report_config->config->cc_report_type[0].cc_report_flags; - } - if (report_config->config->nr_ue > 0) { - complete_stats->ue_report_flags = report_config->config->ue_report_type[0].ue_report_flags; - } - stats_request_msg->complete_stats_request = complete_stats; - break; - case PROTOCOL__FLEX_STATS_TYPE__FLST_CELL_STATS: - stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST; - Protocol__FlexCellStatsRequest *cell_stats; - cell_stats = malloc(sizeof(Protocol__FlexCellStatsRequest)); - if(cell_stats == NULL) - goto error; - protocol__flex_cell_stats_request__init(cell_stats); - cell_stats->n_cell = report_config->config->nr_cc; - cell_stats->has_flags = 1; - if (cell_stats->n_cell > 0) { - uint32_t *cells; - cells = (uint32_t *) malloc(sizeof(uint32_t)*cell_stats->n_cell); - for (i = 0; i < cell_stats->n_cell; i++) { - cells[i] = report_config->config->cc_report_type[i].cc_id; - } - cell_stats->cell = cells; - cell_stats->flags = report_config->config->cc_report_type[i].cc_report_flags; - } - stats_request_msg->cell_stats_request = cell_stats; - break; - case PROTOCOL__FLEX_STATS_TYPE__FLST_UE_STATS: - stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST; - Protocol__FlexUeStatsRequest *ue_stats; - ue_stats = malloc(sizeof(Protocol__FlexUeStatsRequest)); - if(ue_stats == NULL) - goto error; - protocol__flex_ue_stats_request__init(ue_stats); - ue_stats->n_rnti = report_config->config->nr_ue; - ue_stats->has_flags = 1; - if (ue_stats->n_rnti > 0) { - uint32_t *ues; - ues = (uint32_t *) malloc(sizeof(uint32_t)*ue_stats->n_rnti); - for (i = 0; i < ue_stats->n_rnti; i++) { - ues[i] = report_config->config->ue_report_type[i].ue_rnti; - } - ue_stats->rnti = ues; - ue_stats->flags = report_config->config->ue_report_type[i].ue_report_flags; - } - stats_request_msg->ue_stats_request = ue_stats; - break; - default: - goto error; - } - *msg = malloc(sizeof(Protocol__FlexranMessage)); - if(*msg == NULL) - goto error; - protocol__flexran_message__init(*msg); - (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG; - (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; - (*msg)->stats_request_msg = stats_request_msg; - return 0; + } - error: - // TODO: Need to make proper error handling - if (header != NULL) - free(header); - if (stats_request_msg != NULL) - free(stats_request_msg); - if(*msg != NULL) - free(*msg); - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; -} + else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){ + // TODO PMI + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); + csi11->has_wb_pmi = 1; -int flexran_agent_mac_destroy_stats_request(Protocol__FlexranMessage *msg) { - if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG) - goto error; - free(msg->stats_request_msg->header); - if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST) { - free(msg->stats_request_msg->cell_stats_request->cell); - } - if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST) { - free(msg->stats_request_msg->ue_stats_request->rnti); - } - free(msg->stats_request_msg); - free(msg); - return 0; + } - error: - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; -} + else if (flexran_get_antenna_ports(enb_id, j) == 4 && csi_reports[j]->ri == 2){ + // TODO PMI + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); + csi11->has_wb_pmi = 1; -int flexran_agent_mac_stats_reply(mid_t mod_id, - xid_t xid, - const report_config_t *report_config, - Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; - int i, j, k; - int enb_id = mod_id; - //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; - //UE_list_t *eNB_UE_list= &eNB->UE_list; - Protocol__FlexStatsReply *stats_reply_msg; - stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); - if (stats_reply_msg == NULL) - goto error; - protocol__flex_stats_reply__init(stats_reply_msg); + } - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) - goto error; + csi11->has_wb_pmi = 0; - stats_reply_msg->header = header; + csi_reports[j]->p11csi = csi11; - stats_reply_msg->n_ue_report = report_config->nr_ue; - stats_reply_msg->n_cell_report = report_config->nr_cc; + } - Protocol__FlexUeStatsReport **ue_report; - Protocol__FlexCellStatsReport **cell_report; - /* Allocate memory for list of UE reports */ - if (report_config->nr_ue > 0) { - ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * report_config->nr_ue); - if (ue_report == NULL) - goto error; - for (i = 0; i < report_config->nr_ue; i++) { - ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); - protocol__flex_ue_stats_report__init(ue_report[i]); - ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; - ue_report[i]->has_rnti = 1; - ue_report[i]->flags = report_config->ue_report_type[i].ue_report_flags; - ue_report[i]->has_flags = 1; - /* Check the types of reports that need to be constructed based on flag values */ - - /* Check flag for creation of buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { - ue_report[i]->n_bsr = 4; - uint32_t *elem; - elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); - if (elem == NULL) - goto error; - for (j = 0; j < ue_report[i]->n_bsr; j++) { - // NN: we need to know the cc_id here, consider the first one - elem[j] = flexran_get_ue_bsr (enb_id, i, j); - } - ue_report[i]->bsr = elem; - } - /* Check flag for creation of PRH report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PRH) { - ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; - ue_report[i]->has_phr = 1; - } - /* Check flag for creation of RLC buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { - ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs - Protocol__FlexRlcBsr ** rlc_reports; - rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report); - if (rlc_reports == NULL) - goto error; - - // NN: see LAYER2/openair2_proc.c for rlc status - for (j = 0; j < ue_report[i]->n_rlc_report; j++) { - rlc_reports[j] = malloc(sizeof(Protocol__FlexRlcBsr)); - 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]->has_lc_id = 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 = 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; - //TODO:Set retransmission queue head of line delay in ms - rlc_reports[j]->retransmission_queue_hol_delay = 100; - rlc_reports[j]->has_retransmission_queue_hol_delay = 0; - //TODO:Set current size of the pending message in bytes - rlc_reports[j]->status_pdu_size = 100; - rlc_reports[j]->has_status_pdu_size = 0; - } - // Add RLC buffer status reports to the full report - if (ue_report[i]->n_rlc_report > 0) - ue_report[i]->rlc_report = rlc_reports; - } + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){ - /* Check flag for creation of MAC CE buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { - // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; /* Use as bitmap. Set one or more of the - PROTOCOL__FLEX_CE_TYPE__FLPCET_ values - found in stats_common.pb-c.h. See - flex_ce_type in FlexRAN specification */ - ue_report[i]->has_pending_mac_ces = 1; - } + Protocol__FlexCsiP20 *csi20; + csi20 = malloc(sizeof(Protocol__FlexCsiP20)); + if (csi20 == NULL) + goto error; + protocol__flex_csi_p20__init(csi20); - /* Check flag for creation of DL CQI report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { - // TODO: Fill in the actual DL CQI report for the UE based on its configuration - Protocol__FlexDlCqiReport * dl_report; - dl_report = malloc(sizeof(Protocol__FlexDlCqiReport)); - if (dl_report == NULL) - goto error; - protocol__flex_dl_cqi_report__init(dl_report); - - dl_report->sfn_sn = flexran_get_sfn_sf(enb_id); - dl_report->has_sfn_sn = 1; - //Set the number of DL CQI reports for this UE. One for each CC - dl_report->n_csi_report = flexran_get_active_CC(enb_id,i); - - //Create the actual CSI reports. - Protocol__FlexDlCsi **csi_reports; - csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); - if (csi_reports == NULL) - goto error; - for (j = 0; j < dl_report->n_csi_report; j++) { - csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); - if (csi_reports[j] == NULL) - goto error; - protocol__flex_dl_csi__init(csi_reports[j]); - //The servCellIndex for this report - csi_reports[j]->serv_cell_index = j; - csi_reports[j]->has_serv_cell_index = 1; - //The rank indicator value for this cc - csi_reports[j]->ri = flexran_get_current_RI(enb_id,i,j); - csi_reports[j]->has_ri = 1; - //TODO: the type of CSI report based on the configuration of the UE - //For now we only support type P10, which only needs a wideband value - //The full set of types can be found in stats_common.pb-c.h and - //in the FlexRAN specifications - csi_reports[j]->type = PROTOCOL__FLEX_CSI_TYPE__FLCSIT_P10; - csi_reports[j]->has_type = 1; - csi_reports[j]->report_case = PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI; - if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI){ - Protocol__FlexCsiP10 *csi10; - csi10 = malloc(sizeof(Protocol__FlexCsiP10)); - if (csi10 == NULL) - goto error; - protocol__flex_csi_p10__init(csi10); - //TODO: set the wideband value - // NN: this is also depends on cc_id - csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; - csi10->has_wb_cqi = 1; - //Add the type of measurements to the csi report in the proper union type - csi_reports[j]->p10csi = csi10; - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI){ - - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){ - - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI){ - - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI){ - - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI){ - - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI){ - - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI){ - - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI){ - - } - } - //Add the csi reports to the full DL CQI report - dl_report->csi_report = csi_reports; - //Add the DL CQI report to the stats report - ue_report[i]->dl_cqi_report = dl_report; - } + csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + csi20->has_wb_cqi = 1; - /* Check flag for creation of paging buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { - //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI - //set in the report must be a P-RNTI - Protocol__FlexPagingBufferReport *paging_report; - paging_report = malloc(sizeof(Protocol__FlexPagingBufferReport)); - if (paging_report == NULL) - goto error; - protocol__flex_paging_buffer_report__init(paging_report); - //Set the number of pending paging messages - paging_report->n_paging_info = 1; - //Provide a report for each pending paging message - Protocol__FlexPagingInfo **p_info; - p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * paging_report->n_paging_info); - if (p_info == NULL) - goto error; - for (j = 0; j < paging_report->n_paging_info; j++) { - p_info[j] = malloc(sizeof(Protocol__FlexPagingInfo)); - if(p_info[j] == NULL) - goto error; - protocol__flex_paging_info__init(p_info[j]); - //TODO: Set paging index. This index is the same that will be used for the scheduling of the - //paging message by the controller - p_info[j]->paging_index = 10; - p_info[j]->has_paging_index = 0; - //TODO:Set the paging message size - p_info[j]->paging_message_size = 100; - p_info[j]->has_paging_message_size = 0; - //TODO: Set the paging subframe - p_info[j]->paging_subframe = 10; - p_info[j]->has_paging_subframe = 0; - //TODO: Set the carrier index for the pending paging message - p_info[j]->carrier_index = 0; - p_info[j]->has_carrier_index = 0; - } - //Add all paging info to the paging buffer rerport - paging_report->paging_info = p_info; - //Add the paging report to the UE report - ue_report[i]->pbr = paging_report; - } - /* Check flag for creation of UL CQI report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { - //Fill in the full UL CQI report of the UE - Protocol__FlexUlCqiReport *full_ul_report; - full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport)); - if(full_ul_report == NULL) - goto error; - protocol__flex_ul_cqi_report__init(full_ul_report); - //TODO:Set the SFN and SF of the generated report - full_ul_report->sfn_sn = flexran_get_sfn_sf(enb_id); - full_ul_report->has_sfn_sn = 1; - //TODO:Set the number of UL measurement reports based on the types of measurements - //configured for this UE and on the servCellIndex - full_ul_report->n_cqi_meas = 1; - Protocol__FlexUlCqi **ul_report; - ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas); - if(ul_report == NULL) - goto error; - //Fill each UL report of the UE for each of the configured report types - for(j = 0; j < full_ul_report->n_cqi_meas; j++) { - ul_report[j] = malloc(sizeof(Protocol__FlexUlCqi)); - if(ul_report[j] == NULL) - goto error; - protocol__flex_ul_cqi__init(ul_report[j]); - //TODO: Set the type of the UL report. As an example set it to SRS UL report - // See enum flex_ul_cqi_type in FlexRAN specification for more details - ul_report[j]->type = PROTOCOL__FLEX_UL_CQI_TYPE__FLUCT_SRS; - ul_report[j]->has_type = 1; - //TODO:Set the number of SINR measurements based on the report type - //See struct flex_ul_cqi in FlexRAN specification for more details - ul_report[j]->n_sinr = 0; - uint32_t *sinr_meas; - sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[j]->n_sinr); - if (sinr_meas == NULL) - goto error; - //TODO:Set the SINR measurements for the specified type - for (k = 0; k < ul_report[j]->n_sinr; k++) { - sinr_meas[k] = 10; - } - ul_report[j]->sinr = sinr_meas; - //TODO: Set the servCellIndex for this report - ul_report[j]->serv_cell_index = 0; - ul_report[j]->has_serv_cell_index = 1; - - //Set the list of UL reports of this UE to the full UL report - full_ul_report->cqi_meas = ul_report; - - full_ul_report->n_pucch_dbm = MAX_NUM_CCs; - full_ul_report->pucch_dbm = malloc(sizeof(Protocol__FlexPucchDbm *) * full_ul_report->n_pucch_dbm); - - for (j = 0; j < MAX_NUM_CCs; j++) { - full_ul_report->pucch_dbm[j] = malloc(sizeof(Protocol__FlexPucchDbm)); - protocol__flex_pucch_dbm__init(full_ul_report->pucch_dbm[j]); - full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1; - full_ul_report->pucch_dbm[j]->serv_cell_index = j; - if(flexran_get_p0_pucch_dbm(enb_id,i, j) != -1){ - 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); - } + csi20->bandwidth_part_index = 1 ;//TODO + csi20->has_bandwidth_part_index = 1; - //Add full UL CQI report to the UE report - ue_report[i]->ul_cqi_report = full_ul_report; - } - } - } - /* Add list of all UE reports to the message */ - stats_reply_msg->ue_report = ue_report; - } + csi20->sb_index = 1 ;//TODO + csi20->has_sb_index = 1 ; + + + csi_reports[j]->p20csi = csi20; + + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI){ + + // Protocol__FlexCsiP21 *csi21; + // csi21 = malloc(sizeof(Protocol__FlexCsiP21)); + // if (csi21 == NULL) + // goto error; + // protocol__flex_csi_p21__init(csi21); + + // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + + // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside + // csi21->has_wb_pmi = 1; + + // csi21->sb_cqi = 1; // TODO + + // csi21->bandwidth_part_index = 1 ; //TDO inside + // csi21->has_bandwidth_part_index = 1 ; + + // csi21->sb_index = 1 ;//TODO + // csi21->has_sb_index = 1 ; + + + // csi_reports[j]->p20csi = csi21; + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI){ + + + // Protocol__FlexCsiA12 *csi12; + // csi12 = malloc(sizeof(Protocol__FlexCsiA12)); + // if (csi12 == NULL) + // goto error; + // protocol__flex_csi_a12__init(csi12); + + // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi12->sb_pmi = 1 ; //TODO inside + + // TODO continou + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI){ + + // Protocol__FlexCsiA22 *csi22; + // csi22 = malloc(sizeof(Protocol__FlexCsiA22)); + // if (csi22 == NULL) + // goto error; + // protocol__flex_csi_a22__init(csi22); + + // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi22->sb_cqi = 1 ; //TODO inside + + // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i); + // csi22->has_wb_pmi = 1; + + // csi22->sb_pmi = 1 ; //TODO inside + // csi22->has_wb_pmi = 1; + + // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i); + + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI){ + + // Protocol__FlexCsiA20 *csi20; + // csi20 = malloc(sizeof(Protocol__FlexCsiA20)); + // if (csi20 == NULL) + // goto error; + // protocol__flex_csi_a20__init(csi20); + + // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi20->has_wb_cqi = 1; + + // csi20>sb_cqi = 1 ; //TODO inside + // csi20>has_sb_cqi = 1 ; + + // csi20->sb_list = 1; // TODO inside + + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI){ + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI){ + + } + + } + //Add the csi reports to the full DL CQI report + dl_report->csi_report = csi_reports; + //Add the DL CQI report to the stats report + ue_report[i]->dl_cqi_report = dl_report; + + } + + /* Check flag for creation of paging buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { + //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI + //set in the report must be a P-RNTI + Protocol__FlexPagingBufferReport *paging_report; + paging_report = malloc(sizeof(Protocol__FlexPagingBufferReport)); + if (paging_report == NULL) + goto error; + protocol__flex_paging_buffer_report__init(paging_report); + //Set the number of pending paging messages + paging_report->n_paging_info = 1; + //Provide a report for each pending paging message + Protocol__FlexPagingInfo **p_info; + p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * paging_report->n_paging_info); + if (p_info == NULL) + goto error; + + for (j = 0; j < paging_report->n_paging_info; j++) { + + p_info[j] = malloc(sizeof(Protocol__FlexPagingInfo)); + if(p_info[j] == NULL) + goto error; + protocol__flex_paging_info__init(p_info[j]); + //TODO: Set paging index. This index is the same that will be used for the scheduling of the + //paging message by the controller + p_info[j]->paging_index = 10; + p_info[j]->has_paging_index = 1; + //TODO:Set the paging message size + p_info[j]->paging_message_size = 100; + p_info[j]->has_paging_message_size = 1; + //TODO: Set the paging subframe + p_info[j]->paging_subframe = 10; + p_info[j]->has_paging_subframe = 1; + //TODO: Set the carrier index for the pending paging message + p_info[j]->carrier_index = 0; + p_info[j]->has_carrier_index = 1; + + } + //Add all paging info to the paging buffer rerport + paging_report->paging_info = p_info; + //Add the paging report to the UE report + ue_report[i]->pbr = paging_report; + } + + /* Check flag for creation of UL CQI report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { + + //Fill in the full UL CQI report of the UE + Protocol__FlexUlCqiReport *full_ul_report; + full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport)); + if(full_ul_report == NULL) + goto error; + protocol__flex_ul_cqi_report__init(full_ul_report); + //TODO:Set the SFN and SF of the generated report + full_ul_report->sfn_sn = flexran_get_sfn_sf(enb_id); + full_ul_report->has_sfn_sn = 1; + //TODO:Set the number of UL measurement reports based on the types of measurements + //configured for this UE and on the servCellIndex + full_ul_report->n_cqi_meas = 1; + Protocol__FlexUlCqi **ul_report; + ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas); + if(ul_report == NULL) + goto error; + //Fill each UL report of the UE for each of the configured report types + for(j = 0; j < full_ul_report->n_cqi_meas; j++) { + + ul_report[j] = malloc(sizeof(Protocol__FlexUlCqi)); + if(ul_report[j] == NULL) + goto error; + protocol__flex_ul_cqi__init(ul_report[j]); + //TODO: Set the type of the UL report. As an example set it to SRS UL report + // See enum flex_ul_cqi_type in FlexRAN specification for more details + ul_report[j]->type = PROTOCOL__FLEX_UL_CQI_TYPE__FLUCT_SRS; + ul_report[j]->has_type = 1; + //TODO:Set the number of SINR measurements based on the report type + //See struct flex_ul_cqi in FlexRAN specification for more details + ul_report[j]->n_sinr = 0; + uint32_t *sinr_meas; + sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[j]->n_sinr); + if (sinr_meas == NULL) + goto error; + //TODO:Set the SINR measurements for the specified type + for (k = 0; k < ul_report[j]->n_sinr; k++) { + sinr_meas[k] = 10; + } + ul_report[j]->sinr = sinr_meas; + //TODO: Set the servCellIndex for this report + ul_report[j]->serv_cell_index = 0; + ul_report[j]->has_serv_cell_index = 1; + + //Set the list of UL reports of this UE to the full UL report + full_ul_report->cqi_meas = ul_report; + + full_ul_report->n_pucch_dbm = MAX_NUM_CCs; + full_ul_report->pucch_dbm = malloc(sizeof(Protocol__FlexPucchDbm *) * full_ul_report->n_pucch_dbm); + + for (j = 0; j < MAX_NUM_CCs; j++) { + + full_ul_report->pucch_dbm[j] = malloc(sizeof(Protocol__FlexPucchDbm)); + protocol__flex_pucch_dbm__init(full_ul_report->pucch_dbm[j]); + full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1; + full_ul_report->pucch_dbm[j]->serv_cell_index = j; + + if(flexran_get_p0_pucch_dbm(enb_id,i, j) != -1){ + 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; + } + } + + + } + // Add full UL CQI report to the UE report + ue_report[i]->ul_cqi_report = full_ul_report; + + + } + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { + + Protocol__FlexMacStats *macstats; + macstats = malloc(sizeof(Protocol__FlexMacStats)); + if (macstats == NULL) + goto error; + protocol__flex_mac_stats__init(macstats); + + + macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, i, cc_id); + macstats->has_total_bytes_sdus_dl = 1; + + macstats->total_bytes_sdus_ul = flexran_get_total_size_ul_mac_sdus(mod_id, i, cc_id); + macstats->has_total_bytes_sdus_ul = 1; + + macstats->tbs_dl = flexran_get_TBS_dl(mod_id, i, cc_id); + macstats->has_tbs_dl = 1; + + macstats->tbs_ul = flexran_get_TBS_ul(mod_id, i, cc_id); + macstats->has_tbs_ul = 1; + + macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, i, cc_id); + macstats->has_prb_retx_dl = 1; + + macstats->prb_retx_ul = flexran_get_num_prb_retx_ul_per_ue(mod_id, i, cc_id); + macstats->has_prb_retx_ul = 1; + + macstats->prb_dl = flexran_get_num_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->has_prb_dl = 1; + + macstats->prb_ul = flexran_get_num_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->has_prb_ul = 1; + + macstats->mcs1_dl = flexran_get_mcs1_dl(mod_id, i, cc_id); + macstats->has_mcs1_dl = 1; + + macstats->mcs2_dl = flexran_get_mcs2_dl(mod_id, i, cc_id); + macstats->has_mcs2_dl = 1; + + macstats->mcs1_ul = flexran_get_mcs1_ul(mod_id, i, cc_id); + macstats->has_mcs1_ul = 1; + + macstats->mcs2_ul = flexran_get_mcs2_ul(mod_id, i, cc_id); + macstats->has_mcs2_ul = 1; + + macstats->total_prb_dl = flexran_get_total_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->has_total_prb_dl = 1; + + macstats->total_prb_ul = flexran_get_total_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->has_total_prb_ul = 1; + + macstats->total_pdu_dl = flexran_get_total_num_pdu_dl(mod_id, i, cc_id); + macstats->has_total_pdu_dl = 1; + + macstats->total_pdu_ul = flexran_get_total_num_pdu_ul(mod_id, i, cc_id); + macstats->has_total_pdu_ul = 1; + + macstats->total_tbs_dl = flexran_get_total_TBS_dl(mod_id, i, cc_id); + macstats->has_total_tbs_dl = 1; + + macstats->total_tbs_ul = flexran_get_total_TBS_ul(mod_id, i, cc_id); + macstats->has_total_tbs_ul = 1; + + macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, i); + macstats->has_harq_round = 1; + + Protocol__FlexMacSdusDl ** mac_sdus; + mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, i, cc_id)); + if (mac_sdus == NULL) + goto error; + + macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, i, cc_id); + + for (j = 0; j < macstats->n_mac_sdus_dl; j++){ + + + mac_sdus[j] = malloc(sizeof(Protocol__FlexMacSdusDl)); + protocol__flex_mac_sdus_dl__init(mac_sdus[j]); + + mac_sdus[j]->lcid = flexran_get_mac_sdu_lcid_index(mod_id, i, cc_id, j); + mac_sdus[j]->has_lcid = 1; + + mac_sdus[j]->sdu_length = flexran_get_mac_sdu_size(mod_id, i, cc_id, mac_sdus[j]->lcid); + mac_sdus[j]->has_sdu_length = 1; + + + } + + + macstats->mac_sdus_dl = mac_sdus; + + + ue_report[i]->mac_stats = macstats; + + } + + + + + } + + + + + } /* Allocate memory for list of cell reports */ if (report_config->nr_cc > 0) { - cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * report_config->nr_cc); - if (cell_report == NULL) - goto error; - // Fill in the Cell reports - for (i = 0; i < report_config->nr_cc; i++) { - cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); - if(cell_report[i] == NULL) - goto error; - protocol__flex_cell_stats_report__init(cell_report[i]); - cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id; - cell_report[i]->has_carrier_index = 1; - cell_report[i]->flags = report_config->cc_report_type[i].cc_report_flags; - cell_report[i]->has_flags = 1; - - /* Check flag for creation of noise and interference report */ - if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { - // TODO: Fill in the actual noise and interference report for this cell - Protocol__FlexNoiseInterferenceReport *ni_report; - ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); - if(ni_report == NULL) - goto error; - protocol__flex_noise_interference_report__init(ni_report); - // Current frame and subframe number - ni_report->sfn_sf = flexran_get_sfn_sf(enb_id); - ni_report->has_sfn_sf = 1; - //TODO:Received interference power in dbm - ni_report->rip = 0; - ni_report->has_rip = 0; - //TODO:Thermal noise power in dbm - ni_report->tnp = 0; - ni_report->has_tnp = 0; - - ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); - ni_report->has_p0_nominal_pucch = 1; - cell_report[i]->noise_inter_report = ni_report; - } - } - /* Add list of all cell reports to the message */ - stats_reply_msg->cell_report = cell_report; + + + // Fill in the Cell reports + for (i = 0; i < report_config->nr_cc; i++) { + + + /* Check flag for creation of noise and interference report */ + if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { + // TODO: Fill in the actual noise and interference report for this cell + Protocol__FlexNoiseInterferenceReport *ni_report; + ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); + if(ni_report == NULL) + goto error; + protocol__flex_noise_interference_report__init(ni_report); + // Current frame and subframe number + ni_report->sfn_sf = flexran_get_sfn_sf(enb_id); + ni_report->has_sfn_sf = 1; + //TODO:Received interference power in dbm + ni_report->rip = 0; + ni_report->has_rip = 1; + //TODO:Thermal noise power in dbm + ni_report->tnp = 0; + ni_report->has_tnp = 1; + + ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); + ni_report->has_p0_nominal_pucch = 1; + cell_report[i]->noise_inter_report = ni_report; + } + } + + + + } - *msg = malloc(sizeof(Protocol__FlexranMessage)); - if(*msg == NULL) - goto error; - protocol__flexran_message__init(*msg); - (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; - (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; - (*msg)->stats_reply_msg = stats_reply_msg; return 0; error: - // TODO: Need to make proper error handling - if (header != NULL) - free(header); - if (stats_reply_msg != NULL) - free(stats_reply_msg); - if(*msg != NULL) - free(*msg); - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + + if (cell_report != NULL) + free(cell_report); + if (ue_report != NULL) + free(ue_report); + return -1; } @@ -854,7 +765,7 @@ int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) { } int flexran_agent_mac_sr_info(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; int i; const int xid = *((int *)params); @@ -922,11 +833,11 @@ 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; + Protocol__FlexHeader *header = NULL; int i, j, UE_id; - - int available_harq[NUMBER_OF_UE_MAX]; - + + int available_harq[MAX_MOBILES_PER_ENB]; + const int xid = *((int *)params); @@ -943,17 +854,17 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle frame_t frame; sub_frame_t subframe; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; 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); - + if (subframe < flexran_get_current_subframe(mod_id)) { frame = (frame + 1) % 1024; } @@ -967,16 +878,16 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle sf_trigger_msg->n_dl_info = 0; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { for (j = 0; j < 8; j++) { - if (harq_pid_updated[i][j] == 1) { + if (RC.mac && RC.mac[mod_id] && RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid == 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); @@ -993,7 +904,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle goto error; i = -1; //Fill the status of the current HARQ process for each UE - for(UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + for(UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (available_harq[UE_id] < 0) { continue; } else { @@ -1009,17 +920,18 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // 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; + if (RC.mac && RC.mac[mod_id]) + RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][UE_id].harq_pid = 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 + dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[i].round[UE_PCCID(mod_id,i)][j]; + // TODO: This should be different per TB } // 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) { @@ -1052,13 +964,16 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle protocol__flex_ul_info__init(ul_info[i]); ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, i); ul_info[i]->has_rnti = 1; - /*Fill in the Tx power control command for this UE (if available)*/ - if(flexran_get_tpc(mod_id,i) != 1){ - ul_info[i]->tpc = flexran_get_tpc(mod_id,i); + /* Fill in the Tx power control command for this UE (if available), + * primary carrier */ + if(flexran_get_tpc(mod_id, i, 0) != 1){ + /* assume primary carrier */ + ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); ul_info[i]->has_tpc = 1; } else{ - ul_info[i]->tpc = flexran_get_tpc(mod_id,i); + /* assume primary carrier */ + ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); ul_info[i]->has_tpc = 0; } /*TODO: fill in the amount of data in bytes in the MAC SDU received in this subframe for the @@ -1095,7 +1010,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle for (i = 0; i < sf_trigger_msg->n_dl_info; i++) { free(sf_trigger_msg->dl_info[i]->harq_status); } - free(sf_trigger_msg->dl_info); + free(sf_trigger_msg->dl_info); free(sf_trigger_msg->ul_info); free(sf_trigger_msg); } @@ -1134,7 +1049,7 @@ int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg) { int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg) { int xid = 0; - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_DL_MAC_CONFIG, &header) != 0) goto error; @@ -1226,13 +1141,85 @@ int flexran_agent_mac_destroy_dl_config(Protocol__FlexranMessage *msg) { return -1; } +int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMessage **msg) { + + int xid = 0; + Protocol__FlexHeader *header = NULL; + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UL_MAC_CONFIG, &header) != 0) + goto error; + + Protocol__FlexUlMacConfig *ul_mac_config_msg; + ul_mac_config_msg = malloc(sizeof(Protocol__FlexUlMacConfig)); + if (ul_mac_config_msg == NULL) { + goto error; + } + protocol__flex_ul_mac_config__init(ul_mac_config_msg); + + ul_mac_config_msg->header = header; + ul_mac_config_msg->has_sfn_sf = 1; + ul_mac_config_msg->sfn_sf = flexran_get_sfn_sf(mod_id); + + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) + goto error; + protocol__flexran_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + (*msg)->ul_mac_config_msg = ul_mac_config_msg; + + return 0; + + error: + return -1; +} + + +int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { + int i; //,j, k; + if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG) + goto error; + + // Protocol__FlexUlDci *ul_dci; + + free(msg->ul_mac_config_msg->header); + for (i = 0; i < msg->ul_mac_config_msg->n_ul_ue_data; i++) { + // TODO uplink rlc ... + // free(msg->ul_mac_config_msg->dl_ue_data[i]->ce_bitmap); + // for (j = 0; j < msg->ul_mac_config_msg->ul_ue_data[i]->n_rlc_pdu; j++) { + // for (k = 0; k < msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->n_rlc_pdu_tb; k++) { + // free(msg->ul_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb[k]); + // } + // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb); + // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]); + // } + // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu); + // ul_dci = msg->ul_mac_config_msg->ul_ue_data[i]->ul_dci; + // free(dl_dci->tbs_size); + // free(ul_dci->mcs); + // free(ul_dci->ndi); + // free(ul_dci->rv); + // free(ul_dci); + // free(msg->ul_mac_config_msg->ul_ue_data[i]); + } + free(msg->ul_mac_config_msg->ul_ue_data); + + free(msg->ul_mac_config_msg); + free(msg); + + return 0; + + error: + return -1; +} + + void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg) { struct lfds700_misc_prng_state ls; - + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; lfds700_misc_prng_init(&ls); - + if (lfds700_ringbuffer_read(&ringbuffer_state[mod_id], NULL, (void **) msg, &ls) == 0) { *msg = NULL; } @@ -1243,10 +1230,10 @@ int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Pro struct lfds700_misc_prng_state ls; enum lfds700_misc_flag overwrite_occurred_flag; Protocol__FlexranMessage *overwritten_dl_config; - + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; lfds700_misc_prng_init(&ls); - + lfds700_ringbuffer_write( &ringbuffer_state[mod_id], NULL, (void *) params, @@ -1275,9 +1262,10 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { //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 (i = 0; i < MAX_MOBILES_PER_ENB; i++) { for (j = 0; j < 8; j++) { - harq_pid_updated[i][j] = 0; + if (RC.mac && RC.mac[mod_id]) + RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid = 0; } } } @@ -1346,58 +1334,7 @@ void flexran_agent_send_sf_trigger(mid_t mod_id) { LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n"); } -void flexran_agent_send_update_mac_stats(mid_t mod_id) { - - Protocol__FlexranMessage *current_report = NULL; - void *data; - int size; - err_code_t err_code; - int priority = 0; - - if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) { - goto error; - } - - if (mac_stats_context[mod_id].cont_update == 1) { - - /*Create a fresh report with the required flags*/ - err_code = flexran_agent_mac_handle_stats(mod_id, (void *) mac_stats_context[mod_id].stats_req, ¤t_report); - if (err_code < 0) { - goto error; - } - } - /* /\*TODO:Check if a previous reports exists and if yes, generate a report */ - /* *that is the diff between the old and the new report, */ - /* *respecting the thresholds. Otherwise send the new report*\/ */ - /* if (mac_stats_context[mod_id].prev_stats_reply != NULL) { */ - - /* msg = flexran_agent_generate_diff_mac_stats_report(current_report, mac_stats_context[mod_id].prev_stats_reply); */ - - /* /\*Destroy the old stats*\/ */ - /* flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].prev_stats_reply); */ - /* } */ - /* /\*Use the current report for future comparissons*\/ */ - /* mac_stats_context[mod_id].prev_stats_reply = current_report; */ - - - if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) { - goto error; - } - - if (current_report != NULL){ - data=flexran_agent_pack_message(current_report, &size); - /*Send any stats updates using the MAC channel of the eNB*/ - if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; - goto error; - } - LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); - return; - } - error: - LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n"); -} int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { if (mac_agent_registered[mod_id]) { @@ -1408,14 +1345,11 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { //xface->agent_ctxt = &shared_ctxt[mod_id]; xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; - xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; - xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; - //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; + //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; - xface->flexran_agent_notify_ue_state_change = flexran_agent_ue_state_change; - - xface->dl_scheduler_loaded_lib = NULL; + xface->dl_scheduler_loaded_lib = NULL; + xface->ul_scheduler_loaded_lib = NULL; mac_agent_registered[mod_id] = 1; agent_mac_xface[mod_id] = xface; @@ -1427,13 +1361,11 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { //xface->agent_ctxt = NULL; xface->flexran_agent_send_sr_info = NULL; xface->flexran_agent_send_sf_trigger = NULL; - xface->flexran_agent_send_update_mac_stats = NULL; - xface->flexran_agent_schedule_ue_spec = NULL; + //xface->flexran_agent_send_update_mac_stats = NULL; xface->flexran_agent_get_pending_dl_mac_config = NULL; - xface->flexran_agent_notify_ue_state_change = NULL; xface->dl_scheduler_loaded_lib = NULL; - + xface->ul_scheduler_loaded_lib = NULL; mac_agent_registered[mod_id] = 0; agent_mac_xface[mod_id] = NULL; @@ -1441,89 +1373,7 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { } -/****************************************************** - *Implementations of flexran_agent_mac_internal.h functions - ******************************************************/ - -err_code_t flexran_agent_init_cont_mac_stats_update(mid_t mod_id) { - - /*Initialize the Mac stats update structure*/ - /*Initially the continuous update is set to false*/ - mac_stats_context[mod_id].cont_update = 0; - mac_stats_context[mod_id].is_initialized = 1; - mac_stats_context[mod_id].stats_req = NULL; - mac_stats_context[mod_id].prev_stats_reply = NULL; - mac_stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t)); - if (mac_stats_context[mod_id].mutex == NULL) - goto error; - if (pthread_mutex_init(mac_stats_context[mod_id].mutex, NULL)) - goto error;; - - return 0; - - error: - return -1; -} - -err_code_t flexran_agent_destroy_cont_mac_stats_update(mid_t mod_id) { - /*Disable the continuous updates for the MAC*/ - mac_stats_context[mod_id].cont_update = 0; - mac_stats_context[mod_id].is_initialized = 0; - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].stats_req); - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].prev_stats_reply); - free(mac_stats_context[mod_id].mutex); - - mac_agent_registered[mod_id] = 0; - return 1; -} - - -err_code_t flexran_agent_enable_cont_mac_stats_update(mid_t mod_id, - xid_t xid, stats_request_config_t *stats_req) { - /*Enable the continuous updates for the MAC*/ - if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) { - goto error; - } - - Protocol__FlexranMessage *req_msg; - - flexran_agent_mac_stats_request(mod_id, xid, stats_req, &req_msg); - mac_stats_context[mod_id].stats_req = req_msg; - mac_stats_context[mod_id].prev_stats_reply = NULL; - - mac_stats_context[mod_id].cont_update = 1; - mac_stats_context[mod_id].xid = xid; - - if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) { - goto error; - } - return 0; - error: - LOG_E(FLEXRAN_AGENT, "mac_stats_context for eNB %d is not initialized\n", mod_id); - return -1; -} -err_code_t flexran_agent_disable_cont_mac_stats_update(mid_t mod_id) { - /*Disable the continuous updates for the MAC*/ - if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) { - goto error; - } - mac_stats_context[mod_id].cont_update = 0; - mac_stats_context[mod_id].xid = 0; - if (mac_stats_context[mod_id].stats_req != NULL) { - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].stats_req); - } - if (mac_stats_context[mod_id].prev_stats_reply != NULL) { - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].prev_stats_reply); - } - if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) { - goto error; - } - return 0; - error: - LOG_E(FLEXRAN_AGENT, "mac_stats_context for eNB %d is not initialized\n", mod_id); - return -1; -} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 090a599abef7bbdf81176013ddb4292b6fbcd1ca..03e7def95e04610e57503917c38dbafe9e6fb3d4 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -37,50 +37,10 @@ #include "flexran_agent_common.h" #include "flexran_agent_extern.h" -/* These types will be used to give - instructions for the type of stats reports - we need to create */ -typedef struct { - uint16_t ue_rnti; - uint32_t ue_report_flags; /* Indicates the report elements - required for this UE id. See - FlexRAN specification 1.2.4.2 */ -} ue_report_type_t; - -typedef struct { - uint16_t cc_id; - uint32_t cc_report_flags; /* Indicates the report elements - required for this CC index. See - FlexRAN specification 1.2.4.3 */ -} cc_report_type_t; - -typedef struct { - int nr_ue; - ue_report_type_t *ue_report_type; - int nr_cc; - cc_report_type_t *cc_report_type; -} report_config_t; - -typedef struct stats_request_config_s{ - uint8_t report_type; - uint8_t report_frequency; - uint16_t period; /*In number of subframes*/ - report_config_t *config; -} stats_request_config_t; /* Initialization function for the agent structures etc */ void flexran_agent_init_mac_agent(mid_t mod_id); -int flexran_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); - -/* Statistics request protocol message constructor and destructor */ -int flexran_agent_mac_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); -int flexran_agent_mac_destroy_stats_request(Protocol__FlexranMessage *msg); - -/* Statistics reply protocol message constructor and destructor */ -int flexran_agent_mac_stats_reply(mid_t mod_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg); -int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg); - /* Scheduling request information protocol message constructor and estructor */ int flexran_agent_mac_sr_info(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg); @@ -89,10 +49,18 @@ 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); int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg); +/* Statistics reply protocol message constructor and destructor */ +int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg); + /* DL MAC scheduling decision protocol message constructor (empty command) and destructor */ int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg); int flexran_agent_mac_destroy_dl_config(Protocol__FlexranMessage *msg); +/* UL MAC scheduling decision protocol message constructor (empty command) and destructor */ +int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMessage **msg); +int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg); + int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index 70254bd7ba4ed28154820443b8f31954ecae4447..5c1fc1379c6454406b22f2e7fde198433819e965 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -48,26 +48,20 @@ typedef struct { /// Send to the controller all the mac stat updates that occured during this subframe /// based on the stats request configuration - void (*flexran_agent_send_update_mac_stats)(mid_t mod_id); + // void (*flexran_agent_send_update_mac_stats)(mid_t mod_id); /// Provide to the scheduler a pending dl_mac_config message void (*flexran_agent_get_pending_dl_mac_config)(mid_t mod_id, Protocol__FlexranMessage **msg); - /// Run the UE DL scheduler and fill the Protocol__FlexranMessage. Assumes that - /// dl_info is already initialized as flex_dl_mac_config and fills the - /// flex_dl_data part of it - void (*flexran_agent_schedule_ue_spec)(mid_t mod_id, uint32_t frame, uint32_t subframe, - int *mbsfn_flag, Protocol__FlexranMessage **dl_info); - - /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) - int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, - uint8_t state_change); + // int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, + // uint8_t state_change); void *dl_scheduler_loaded_lib; + void *ul_scheduler_loaded_lib; /*TODO: Fill in with the rest of the MAC layer technology specific callbacks (UL/DL scheduling, RACH info etc)*/ } AGENT_MAC_xface; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 5c37ba81321076b1e6ec26d070b31285dfa7fd99..2acee0686f62165881d256e96eb09500274d0a30 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -101,7 +101,7 @@ Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol if (n_cell_report > 0 || n_ue_report > 0) { /*Create header*/ int xid = old_report->header->xid; - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) { goto error; } @@ -180,10 +180,12 @@ Protocol__FlexUeStatsReport * copy_ue_stats_report(Protocol__FlexUeStatsReport * } } - if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PRH) { - copy->has_phr = original->has_phr; - copy->phr = original->phr; - } + + + if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { + copy->has_phr = original->has_phr; + copy->phr = original->phr; + } if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { copy->n_rlc_report = original->n_rlc_report; @@ -605,7 +607,10 @@ int parse_mac_config(mid_t mod_id, yaml_parser_t *parser) { } else if (strcmp((char *) event.data.scalar.value, "ul_scheduler") == 0) { // Call the proper handler LOG_D(ENB_APP, "This is for the ul_scheduler subsystem\n"); - goto error; + if (parse_ul_scheduler_config(mod_id, parser) == -1) { + LOG_D(ENB_APP, "An error occured\n"); + goto error; + } // TODO } else if (strcmp((char *) event.data.scalar.value, "ra_scheduler") == 0) { // Call the proper handler @@ -698,6 +703,56 @@ int parse_dl_scheduler_config(mid_t mod_id, yaml_parser_t *parser) { return -1; } +int parse_ul_scheduler_config(mid_t mod_id, yaml_parser_t *parser) { + + yaml_event_t event; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping (behavior and parameters) + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the subsystem started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the subsystem ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + if (strcmp((char *) event.data.scalar.value, "parameters") == 0) { + LOG_D(ENB_APP, "Now it is time to set the parameters for this subsystem\n"); + if (parse_ul_scheduler_parameters(mod_id, parser) == -1) { + goto error; + } + } + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + + int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { yaml_event_t event; @@ -753,13 +808,68 @@ int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { return -1; } +int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { + yaml_event_t event; + + void *param; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping of parameters + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + if (mac_agent_registered[mod_id]) { + LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value); + param = dlsym(agent_mac_xface[mod_id]->ul_scheduler_loaded_lib, + (char *) event.data.scalar.value); + if (param == NULL) { + goto error; + } + apply_parameter_modification(param, parser); + } else { + goto error; + } + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { void *lib; char lib_name[120]; char target[512]; snprintf(lib_name, sizeof(lib_name), "/%s.so", function_name); - strcpy(target, local_cache); + strcpy(target, RC.flexran[mod_id]->cache_name); strcat(target, lib_name); LOG_I(FLEXRAN_AGENT, "Opening pushed code: %s\n", target); @@ -773,7 +883,6 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { void *loaded_scheduler = dlsym(lib, function_name); if (loaded_scheduler) { if (mac_agent_registered[mod_id]) { - agent_mac_xface[mod_id]->flexran_agent_schedule_ue_spec = loaded_scheduler; if (agent_mac_xface[mod_id]->dl_scheduler_loaded_lib != NULL) { dlclose(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib); } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index 263b85eb87fef9dfd70a13ba15d702ea14c06e5b..f69e2cde4098ad5d035a522c9815632bffb37312 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -101,6 +101,10 @@ int parse_dl_scheduler_config(mid_t mod_id, yaml_parser_t *parser); int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser); +int parse_ul_scheduler_config(mid_t mod_id, yaml_parser_t *parser); + +int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser); + int load_dl_scheduler_function(mid_t mod_id, const char *function_name); #endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/ diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c new file mode 100644 index 0000000000000000000000000000000000000000..b2723f718126973f96d972a3284b995c5e99c3e2 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -0,0 +1,171 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_pdcp.c + * \brief FlexRAN agent Control Module PDCP + * \author Navid Nikaein and shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include "flexran_agent_pdcp.h" + + +/*Trigger boolean for PDCP measurement*/ +bool triggered_pdcp = false; +/*Flags showing if a pdcp agent has already been registered*/ +unsigned int pdcp_agent_registered[NUM_MAX_ENB]; + +/*Array containing the Agent-PDCP interfaces*/ +AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB]; + +// MAX_MOBILES_PER_ENB + +void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, + const mid_t ue_id, + Protocol__FlexPdcpStats *pdcp_aggr_stats){ + + int lcid=0; + /* only calculate the DRBs */ + //LOG_I(FLEXRAN_AGENT, "enb %d ue %d \n", mod_id, ue_id); + + for (lcid=NUM_MAX_SRB ; lcid < NUM_MAX_SRB + NUM_MAX_DRB; lcid++){ + + pdcp_aggr_stats->pkt_tx += flexran_get_pdcp_tx(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_bytes += flexran_get_pdcp_tx_bytes(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_w += flexran_get_pdcp_tx_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_bytes_w += flexran_get_pdcp_tx_bytes_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_aiat += flexran_get_pdcp_tx_aiat(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_aiat_w += flexran_get_pdcp_tx_aiat_w(mod_id,ue_id,lcid); + + + pdcp_aggr_stats->pkt_rx += flexran_get_pdcp_rx(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_bytes += flexran_get_pdcp_rx_bytes(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_w += flexran_get_pdcp_rx_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_bytes_w += flexran_get_pdcp_rx_bytes_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_aiat += flexran_get_pdcp_rx_aiat(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_aiat_w += flexran_get_pdcp_rx_aiat_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_oo += flexran_get_pdcp_rx_oo(mod_id,ue_id,lcid); + + } + +} + + +int flexran_agent_pdcp_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report) { + + + // Protocol__FlexHeader *header; + int i; + // int cc_id = 0; + + + /* Allocate memory for list of UE reports */ + if (report_config->nr_ue > 0) { + + for (i = 0; i < report_config->nr_ue; i++) { + + /* Check flag for creation of buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) { + + Protocol__FlexPdcpStats *pdcp_aggr_stats; + pdcp_aggr_stats = malloc(sizeof(Protocol__FlexPdcpStats)); + if (pdcp_aggr_stats == NULL) + goto error; + protocol__flex_pdcp_stats__init(pdcp_aggr_stats); + + flexran_agent_pdcp_aggregate_stats(mod_id, i, pdcp_aggr_stats); + + pdcp_aggr_stats->has_pkt_tx=1; + pdcp_aggr_stats->has_pkt_tx_bytes =1; + pdcp_aggr_stats->has_pkt_tx_w=1; + pdcp_aggr_stats->has_pkt_tx_bytes_w =1; + pdcp_aggr_stats->has_pkt_tx_aiat =1; + pdcp_aggr_stats->has_pkt_tx_aiat_w =1; + + pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->has_pkt_tx_sn =1; + + pdcp_aggr_stats->has_pkt_rx =1; + pdcp_aggr_stats->has_pkt_rx_bytes =1; + pdcp_aggr_stats->has_pkt_rx_w =1; + pdcp_aggr_stats->has_pkt_rx_bytes_w =1; + pdcp_aggr_stats->has_pkt_rx_aiat =1; + pdcp_aggr_stats->has_pkt_rx_aiat_w =1; + pdcp_aggr_stats->has_pkt_rx_oo =1; + + pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->has_pkt_rx_sn =1; + + pdcp_aggr_stats->sfn = flexran_get_pdcp_sfn(mod_id); + pdcp_aggr_stats->has_sfn =1; + + ue_report[i]->pdcp_stats = pdcp_aggr_stats; + + } + } + } else { + LOG_D(FLEXRAN_AGENT, "no UE\n"); + } + + return 0; + + error: + LOG_W(FLEXRAN_AGENT, "Can't allocate PDCP stats\n"); + + /* if (cell_report != NULL) + free(cell_report); + if (ue_report != NULL) + free(ue_report); + */ + return -1; +} + + + +int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) { + if (pdcp_agent_registered[mod_id]) { + LOG_E(PDCP, "PDCP agent for eNB %d is already registered\n", mod_id); + return -1; + } + + //xface->flexran_pdcp_stats_measurement = NULL; + + pdcp_agent_registered[mod_id] = 1; + agent_pdcp_xface[mod_id] = xface; + + return 0; +} + +int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) { + + //xface->agent_ctxt = NULL; + //xface->flexran_pdcp_stats_measurement = NULL; + + + pdcp_agent_registered[mod_id] = 0; + agent_pdcp_xface[mod_id] = NULL; + + return 0; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h new file mode 100644 index 0000000000000000000000000000000000000000..83aac45406e17b5f5526898e45a5212475cd2e9b --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_pdcp.h + * \brief FlexRAN agent Control Module PDCP header + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#ifndef FLEXRAN_AGENT_PDCP_H_ +#define FLEXRAN_AGENT_PDCP_H_ + +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "stats_messages.pb-c.h" +#include "stats_common.pb-c.h" + + +#include "flexran_agent_common.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_pdcp_defs.h" +#include "flexran_agent_ran_api.h" + +/********************************** + * FlexRAN agent - technology PDCP API + **********************************/ + +/* Send to the controller all the pdcp stat updates that occured during this subframe*/ +int flexran_agent_pdcp_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report); + +/* Get the stats from RAN API and aggregate them per USER*/ +void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, + const mid_t ue_id, + Protocol__FlexPdcpStats *pdcp_aggr_stats); + +/*Register technology specific interface callbacks*/ +int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface); + +/*Unregister technology specific callbacks*/ +int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface*xface); + +#endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..f2da72545af810f801ff8d65b5b9f8579a5f8184 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#ifndef __FLEXRAN_AGENT_PDCP_PRIMITIVES_H__ +#define __FLEXRAN_AGENT_PDCP_PRIMITIVES_H__ + +#include "flexran_agent_defs.h" +#include "flexran.pb-c.h" +#include "header.pb-c.h" + + /*PDCP aggregated Packet stats */ +/* +typedef struct pdcp_aggr_stats_s { + int32_t rnti; + + int32_t pkt_tx; + int32_t pkt_tx_bytes; + int32_t pkt_tx_sn; + int32_t pkt_tx_rate_s; + int32_t pkt_tx_throughput_s; + int32_t pkt_tx_aiat; + int32_t pkt_tx_aiat_s; + + int32_t pkt_rx; + int32_t pkt_rx_bytes; + int32_t pkt_rx_sn; + int32_t pkt_rx_rate_s; + int32_t pkt_rx_goodput_s; + int32_t pkt_rx_aiat; + int32_t pkt_rx_aiat_s; + int32_t pkt_rx_oo; + + +} pdcp_aggr_stats_t; +*/ + +/* FLEXRAN AGENT-PDCP Interface */ +typedef struct { + + + // PDCP statistics + void (*flexran_pdcp_stats_measurement)(mid_t mod_id, uint16_t rnti, uint16_t seq_num, uint32_t size); + +} AGENT_PDCP_xface; + +#endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c new file mode 100644 index 0000000000000000000000000000000000000000..43951ee95afb6adfb2dfd8febb70aa4326198f5e --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -0,0 +1,673 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_mac.c + * \brief FlexRAN agent Control Module RRC + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include "flexran_agent_rrc.h" + + +#include "liblfds700.h" + +#include "log.h" + +/*Trigger boolean for RRC measurement*/ +bool triggered_rrc = false; + +/*Flags showing if an rrc agent has already been registered*/ +unsigned int rrc_agent_registered[NUM_MAX_ENB]; + +/*Array containing the Agent-RRC interfaces*/ +AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; + + +void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { + int size; + Protocol__FlexranMessage *msg = NULL; + Protocol__FlexHeader *header = NULL; + void *data; + int priority = 0; + err_code_t err_code; + + int xid = 0; + + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UE_STATE_CHANGE, &header) != 0) + goto error; + + Protocol__FlexUeStateChange *ue_state_change_msg; + ue_state_change_msg = malloc(sizeof(Protocol__FlexUeStateChange)); + if(ue_state_change_msg == NULL) { + goto error; + } + protocol__flex_ue_state_change__init(ue_state_change_msg); + ue_state_change_msg->has_type = 1; + ue_state_change_msg->type = state_change; + + Protocol__FlexUeConfig *config; + config = malloc(sizeof(Protocol__FlexUeConfig)); + if (config == NULL) { + goto error; + } + protocol__flex_ue_config__init(config); + if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED) { + // Simply set the rnti of the UE + config->has_rnti = 1; + config->rnti = rnti; + } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED + || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { + int i = find_UE_id(mod_id, rnti); + config->has_rnti = 1; + config->rnti = rnti; + if(flexran_get_time_alignment_timer(mod_id,i) != -1) { + config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); + config->has_time_alignment_timer = 1; + } + if(flexran_get_meas_gap_config(mod_id,i) != -1){ + config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); + config->has_meas_gap_config_pattern = 1; + } + if(config->has_meas_gap_config_pattern == 1 && + config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { + config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); + config->has_meas_gap_config_sf_offset = 1; + } + //TODO: Set the SPS configuration (Optional) + //Not supported for now, so we do not set it + + //TODO: Set the SR configuration (Optional) + //We do not set it for now + + //TODO: Set the CQI configuration (Optional) + //We do not set it for now + + if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { + config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); + config->has_transmission_mode = 1; + } + + config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); + config->has_ue_aggregated_max_bitrate_ul = 1; + + config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); + config->has_ue_aggregated_max_bitrate_dl = 1; + + //TODO: Set the UE capabilities + Protocol__FlexUeCapabilities *c_capabilities; + c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); + protocol__flex_ue_capabilities__init(c_capabilities); + //TODO: Set half duplex (FDD operation) + c_capabilities->has_half_duplex = 0; + c_capabilities->half_duplex = 1;//flexran_get_half_duplex(i); + //TODO: Set intra-frame hopping flag + c_capabilities->has_intra_sf_hopping = 0; + c_capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); + //TODO: Set support for type 2 hopping with n_sb > 1 + c_capabilities->has_type2_sb_1 = 0; + c_capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); + //TODO: Set ue category + c_capabilities->has_ue_category = 0; + c_capabilities->ue_category = 1;//flexran_get_ue_category(i); + //TODO: Set UE support for resource allocation type 1 + c_capabilities->has_res_alloc_type1 = 0; + c_capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); + //Set the capabilites to the message + config->capabilities = c_capabilities; + + if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { + config->has_ue_transmission_antenna = 1; + config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); + } + + if(flexran_get_tti_bundling(mod_id,i) != -1) { + config->has_tti_bundling = 1; + config->tti_bundling = flexran_get_tti_bundling(mod_id,i); + } + + if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ + config->has_max_harq_tx = 1; + config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); + } + + if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { + config->has_beta_offset_ack_index = 1; + config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); + } + + if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { + config->has_beta_offset_ri_index = 1; + config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); + } + + if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { + config->has_beta_offset_cqi_index = 1; + config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); + } + + /* assume primary carrier */ + if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) { + config->has_ack_nack_simultaneous_trans = 1; + config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0); + } + + if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { + config->has_simultaneous_ack_nack_cqi = 1; + config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); + } + + if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { + config->has_aperiodic_cqi_rep_mode = 1; + int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); + if (mode > 4) { + config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; + } else { + config->aperiodic_cqi_rep_mode = mode; + } + } + + if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { + config->has_tdd_ack_nack_feedback = 1; + config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); + } + + if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { + config->has_ack_nack_repetition_factor = 1; + config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); + } + + if(flexran_get_extended_bsr_size(mod_id, i) != -1) { + config->has_extended_bsr_size = 1; + config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); + } + + config->has_pcell_carrier_index = 1; + config->pcell_carrier_index = UE_PCCID(mod_id, i); + //TODO: Set carrier aggregation support (boolean) + config->has_ca_support = 0; + config->ca_support = 0; + if(config->has_ca_support){ + //TODO: Set cross carrier scheduling support (boolean) + config->has_cross_carrier_sched_support = 1; + config->cross_carrier_sched_support = 0; + //TODO: Set secondary cells configuration + // We do not set it for now. No carrier aggregation support + + //TODO: Set deactivation timer for secondary cell + config->has_scell_deactivation_timer = 0; + config->scell_deactivation_timer = 0; + } + } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) { + // TODO: Not supported for now. Leave blank + } + + ue_state_change_msg->config = config; + msg = malloc(sizeof(Protocol__FlexranMessage)); + if (msg == NULL) { + goto error; + } + protocol__flexran_message__init(msg); + msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG; + msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + msg->ue_state_change_msg = ue_state_change_msg; + + data = flexran_agent_pack_message(msg, &size); + /*Send sr info using the MAC channel of the eNB*/ + if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; + goto error; + } + + LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); + return; + error: + LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code); +} + + + +int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG) + goto error; + free(msg->ue_state_change_msg->header); + //TODO: Free the contents of the UE config structure + free(msg->ue_state_change_msg); + free(msg); + return 0; + + error: + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +/* this is called by RRC as a part of rrc xface . The controller previously requested this*/ +void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { + + int i; + // int priority = 0; // Warning Preventing + // void *data; + // int size; + // err_code_t err_code = -100; + triggered_rrc = true; + int num; + + num = flexran_get_num_ues (mod_id); + + meas_stats = malloc(sizeof(rrc_meas_stats) * num); + + for (i = 0; i < num; i++){ + meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, i); + meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id,i); + meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i) - 140; + // measResults->measResultPCell.rsrpResult - 140; + meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i)/2 - 20; + // (measResults->measResultPCell.rsrqResult)/2 - 20; + + } + // repl->neigh_meas = NULL; + + // if (meas->measResultNeighCells != NULL) { + // /* + // * Neighboring cells measurements performed by UE. + // */ + // NeighCellsMeasurements *neigh_meas; + // neigh_meas = malloc(sizeof(NeighCellsMeasurements)); + // if (neigh_meas == NULL) + // goto error; + // neigh_cells_measurements__init(neigh_meas); + + // /* EUTRAN RRC Measurements. */ + // if (meas->measResultNeighCells->present == + // MeasResults__measResultNeighCells_PR_measResultListEUTRA) { + + // MeasResultListEUTRA_t meas_list = meas->measResultNeighCells-> + // choice.measResultListEUTRA; + // /* Set the number of EUTRAN measurements present in report. */ + // neigh_meas->n_eutra_meas = meas_list.list.count; + // if (neigh_meas->n_eutra_meas > 0) { + // /* Initialize EUTRAN measurements. */ + // EUTRAMeasurements **eutra_meas; + // eutra_meas = malloc(sizeof(EUTRAMeasurements *) * + // neigh_meas->n_eutra_meas); + // for (i = 0; i < neigh_meas->n_eutra_meas; i++) { + // eutra_meas[i] = malloc(sizeof(EUTRAMeasurements)); + // eutra_measurements__init(eutra_meas[i]); + // /* Fill in the physical cell identifier. */ + // eutra_meas[i]->has_phys_cell_id = 1; + // eutra_meas[i]->phys_cell_id = meas_list.list.array[i]-> + // physCellId; + // // log_i(agent,"PCI of Target %d", eutra_meas[i]->phys_cell_id); + // /* Check for Reference signal measurements. */ + // if (&(meas_list.list.array[i]->measResult)) { + // /* Initialize Ref. signal measurements. */ + // EUTRARefSignalMeas *meas_result; + // meas_result = malloc(sizeof(EUTRARefSignalMeas)); + // eutra_ref_signal_meas__init(meas_result); + + // if (meas_list.list.array[i]->measResult.rsrpResult) { + // meas_result->has_rsrp = 1; + // meas_result->rsrp = RSRP_meas_mapping[*(meas_list. + // list.array[i]->measResult.rsrpResult)]; + // // log_i(agent,"RSRP of Target %d", meas_result->rsrp); + // } + + // if (meas_list.list.array[i]->measResult.rsrqResult) { + // meas_result->has_rsrq = 1; + // meas_result->rsrq = RSRQ_meas_mapping[*(meas_list. + // list.array[i]->measResult.rsrqResult)]; + // // log_i(agent,"RSRQ of Target %d", meas_result->rsrq); + // } + // eutra_meas[i]->meas_result = meas_result; + // } + // /* Check for CGI measurements. */ + // if (meas_list.list.array[i]->cgi_Info) { + // /* Initialize CGI measurements. */ + // EUTRACgiMeasurements *cgi_meas; + // cgi_meas = malloc(sizeof(EUTRACgiMeasurements)); + // eutra_cgi_measurements__init(cgi_meas); + + // /* EUTRA Cell Global Identity (CGI). */ + // CellGlobalIdEUTRA *cgi; + // cgi = malloc(sizeof(CellGlobalIdEUTRA)); + // cell_global_id__eutra__init(cgi); + + // cgi->has_cell_id = 1; + // CellIdentity_t cId = meas_list.list.array[i]-> + // cgi_Info->cellGlobalId.cellIdentity; + // cgi->cell_id = (cId.buf[0] << 20) + (cId.buf[1] << 12) + + // (cId.buf[2] << 4) + (cId.buf[3] >> 4); + + // /* Public land mobile network identifier of neighbor + // * cell. + // */ + // PlmnIdentity *plmn_id; + // plmn_id = malloc(sizeof(PlmnIdentity)); + // plmn_identity__init(plmn_id); + + // MNC_t mnc = meas_list.list.array[i]-> + // cgi_Info->cellGlobalId.plmn_Identity.mnc; + + // plmn_id->has_mnc = 1; + // plmn_id->mnc = 0; + // for (m = 0; m < mnc.list.count; m++) { + // plmn_id->mnc += *mnc.list.array[m] * + // ((uint32_t) pow(10, mnc.list.count - m - 1)); + // } + + // MCC_t *mcc = meas_list.list.array[i]-> + // cgi_Info->cellGlobalId.plmn_Identity.mcc; + + // plmn_id->has_mcc = 1; + // plmn_id->mcc = 0; + // for (m = 0; m < mcc->list.count; m++) { + // plmn_id->mcc += *mcc->list.array[m] * + // ((uint32_t) pow(10, mcc->list.count - m - 1)); + // } + + // TrackingAreaCode_t tac = meas_list.list.array[i]-> + // cgi_Info->trackingAreaCode; + + // cgi_meas->has_tracking_area_code = 1; + // cgi_meas->tracking_area_code = (tac.buf[0] << 8) + + // (tac.buf[1]); + + // PLMN_IdentityList2_t *plmn_l = meas_list.list.array[i]-> + // cgi_Info->plmn_IdentityList; + + // cgi_meas->n_plmn_id = plmn_l->list.count; + // /* Set the PLMN ID list in CGI measurements. */ + // PlmnIdentity **plmn_id_l; + // plmn_id_l = malloc(sizeof(PlmnIdentity *) * + // cgi_meas->n_plmn_id); + + // MNC_t mnc2; + // MCC_t *mcc2; + // for (m = 0; m < cgi_meas->n_plmn_id; m++) { + // plmn_id_l[m] = malloc(sizeof(PlmnIdentity)); + // plmn_identity__init(plmn_id_l[m]); + + // mnc2 = plmn_l->list.array[m]->mnc; + // plmn_id_l[m]->has_mnc = 1; + // plmn_id_l[m]->mnc = 0; + // for (k = 0; k < mnc2.list.count; k++) { + // plmn_id_l[m]->mnc += *mnc2.list.array[k] * + // ((uint32_t) pow(10, mnc2.list.count - k - 1)); + // } + + // mcc2 = plmn_l->list.array[m]->mcc; + // plmn_id_l[m]->has_mcc = 1; + // plmn_id_l[m]->mcc = 0; + // for (k = 0; k < mcc2->list.count; k++) { + // plmn_id_l[m]->mcc += *mcc2->list.array[k] * + // ((uint32_t) pow(10, mcc2->list.count - k - 1)); + // } + // } + // cgi_meas->plmn_id = plmn_id_l; + // eutra_meas[i]->cgi_meas = cgi_meas; + // } + // } + // neigh_meas->eutra_meas = eutra_meas; + // } + // } + // repl->neigh_meas = neigh_meas; + // } + /* Attach the RRC measurement reply message to RRC measurements message. */ + // mrrc_meas->repl = repl; + /* Attach RRC measurement message to triggered event message. */ + // te->mrrc_meas = mrrc_meas; + // te->has_action = 0; + /* Attach the triggered event message to main message. */ + // reply->te = te; + + /* Send the report to controller. */ + // if (flexran_agent_msg_send(b_id, reply) < 0) { + // goto error; + // } + + /* Free the measurement report received from UE. */ + // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); + /* Free the params. */ + // free(p); + + + // stats_reply_msg->cell_report = cell_report; + + // stats_reply_msg->ue_report = ue_report; + + // msg = malloc(sizeof(Protocol__FlexranMessage)); + // if(msg == NULL) + // goto error; + // protocol__flexran_message__init(msg); + // msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; + // msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; + // msg->stats_reply_msg = stats_reply_msg; + + // data = flexran_agent_pack_message(msg, &size); + + + // if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { + + // err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; + // goto error; + // } + + // LOG_I(FLEXRAN_AGENT,"RRC Trigger is done \n"); + + return; + + // error: + + // LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code); + /* Free the measurement report received from UE. */ + // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); + /* Free the params. */ + // free(p); + // return -1; +} + + +int flexran_agent_rrc_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report) { + + + // Protocol__FlexHeader *header; + int i,j; + + /* Allocate memory for list of UE reports */ + if (report_config->nr_ue > 0) { + + for (i = 0; i < report_config->nr_ue; i++) { + + /* Check flag for creation of buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) { + + /*Source Cell*/ + Protocol__FlexRrcMeasurements *rrc_measurements; + rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements)); + if (rrc_measurements == NULL) + goto error; + protocol__flex_rrc_measurements__init(rrc_measurements); + + rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i); + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i); + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i); + rrc_measurements->has_pcell_rsrq = 1 ; + + + /* Target Cell, Neghibouring*/ + Protocol__FlexNeighCellsMeasurements *neigh_meas; + neigh_meas = malloc(sizeof(Protocol__FlexNeighCellsMeasurements)); + if (neigh_meas == NULL) + goto error; + protocol__flex_neigh_cells_measurements__init(neigh_meas); + + + neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, i); + + Protocol__FlexEutraMeasurements **eutra_meas = NULL; + + if (neigh_meas->n_eutra_meas > 0){ + + eutra_meas = malloc(sizeof(Protocol__FlexEutraMeasurements) * neigh_meas->n_eutra_meas); + if (eutra_meas == NULL) + goto error; + + for (j = 0; j < neigh_meas->n_eutra_meas; j++ ){ + + eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements)); + if (eutra_meas[j] == NULL) + goto error; + + protocol__flex_eutra_measurements__init(eutra_meas[j]); + + eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, i, j); + eutra_meas[j]->has_phys_cell_id = 1; + + + /*TODO: Extend for CGI and PLMNID*/ + + Protocol__FlexEutraRefSignalMeas *meas_result; + meas_result = malloc(sizeof(Protocol__FlexEutraRefSignalMeas)); + + protocol__flex_eutra_ref_signal_meas__init(meas_result); + + meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->has_rsrp = 1; + + meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->has_rsrq = 1; + + eutra_meas[j]->meas_result = meas_result; + + } + + neigh_meas->eutra_meas = eutra_meas; + + rrc_measurements->neigh_meas = neigh_meas; + + } + + ue_report[i]->rrc_measurements = rrc_measurements; + + } + + } + + } + + /* To be considered for RRC signaling of cell*/ + // if (report_config->nr_cc > 0) { + + + // // Fill in the Cell reports + // for (i = 0; i < report_config->nr_cc; i++) { + + + // /* Check flag for creation of noise and interference report */ + // if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { + // // TODO: Fill in the actual noise and interference report for this cell + // Protocol__FlexNoiseInterferenceReport *ni_report; + // ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); + // if(ni_report == NULL) + // goto error; + // protocol__flex_noise_interference_report__init(ni_report); + // // Current frame and subframe number + // ni_report->sfn_sf = flexran_get_sfn_sf(enb_id); + // ni_report->has_sfn_sf = 1; + // //TODO:Received interference power in dbm + // ni_report->rip = 0; + // ni_report->has_rip = 1; + // //TODO:Thermal noise power in dbm + // ni_report->tnp = 0; + // ni_report->has_tnp = 1; + + // ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); + // ni_report->has_p0_nominal_pucch = 1; + // cell_report[i]->noise_inter_report = ni_report; + // } + // } + + + + + // } + + return 0; + + error: + + for (i = 0; i < report_config->nr_ue; i++){ + + if (ue_report[i]->rrc_measurements->neigh_meas != NULL){ + for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, i); j++){ + + free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]); + } + free(ue_report[i]->rrc_measurements->neigh_meas); + } + } + + if (cell_report != NULL) + free(cell_report); + if (ue_report != NULL) + free(ue_report); + + return -1; +} + + +int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { + if (rrc_agent_registered[mod_id]) { + LOG_E(RRC, "RRC agent for eNB %d is already registered\n", mod_id); + return -1; + } + +// xface->flexran_agent_send_update_rrc_stats = flexran_agent_send_update_rrc_stats; + + xface->flexran_agent_notify_ue_state_change = flexran_agent_ue_state_change; + xface->flexran_trigger_rrc_measurements = flexran_trigger_rrc_measurements; + + rrc_agent_registered[mod_id] = 1; + agent_rrc_xface[mod_id] = xface; + + return 0; +} + +int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { + + //xface->agent_ctxt = NULL; +// xface->flexran_agent_send_update_rrc_stats = NULL; + + xface->flexran_agent_notify_ue_state_change = NULL; + xface->flexran_trigger_rrc_measurements = NULL; + rrc_agent_registered[mod_id] = 0; + agent_rrc_xface[mod_id] = NULL; + + return 0; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h new file mode 100644 index 0000000000000000000000000000000000000000..780976893e575f32c22edcf8066191e47d981ed3 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -0,0 +1,70 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_rrc.h + * \brief FlexRAN agent Control Module RRC header + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#ifndef FLEXRAN_AGENT_RRC_H_ +#define FLEXRAN_AGENT_RRC_H_ + +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "stats_messages.pb-c.h" +#include "stats_common.pb-c.h" + + +#include "flexran_agent_common.h" +#include "flexran_agent_rrc_defs.h" + + +/* Initialization function for the agent structures etc */ +void flexran_agent_init_rrc_agent(mid_t mod_id); + +/* UE state change message constructor and destructor */ +void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change); +int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); + + +/********************************** + * FlexRAN agent - technology RRC API + **********************************/ + +/* Send to the controller all the rrc stat updates that occured during this subframe*/ +// void flexran_agent_send_update_rrc_stats(mid_t mod_id); + +/* this is called by RRC as a part of rrc xface . The controller previously requested this*/ +void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t *); + +/* Statistics reply protocol message constructor and destructor */ +int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexranMessage *msg); + +/*Register technology specific interface callbacks*/ +int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface); + +/*Unregister technology specific callbacks*/ +int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface*xface); + +#endif diff --git a/openair2/LAYER2/MAC/flexran_dci_conversions.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h similarity index 50% rename from openair2/LAYER2/MAC/flexran_dci_conversions.h rename to openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index 5c18b431043f47033b739f314c1ea98ea3ab20cb..8c336abef1a54e3acf3e2f571251d697a595a373 100644 --- a/openair2/LAYER2/MAC/flexran_dci_conversions.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -17,35 +17,53 @@ *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org - */ + */ + -/*! \file flexran_dci_conversions.h - * \brief Conversion helpers from flexran messages to OAI formats DCI - * \author Xenofon Foukas - * \date 2016 +/*! \file flexran_agent_rrc_defs.h + * \brief FlexRAN agent - RRC interface primitives + * \author shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 + * \mail */ -#ifndef LAYER2_MAC_FLEXRAN_DCI_CONVERISIONS_H__ -#define LAYER2_MAC_DCI_FLEXRAN_CONVERISIONS_H__ - -#define FILL_DCI_FDD_1(TYPE, DCI, FLEXRAN_DCI) \ - ((TYPE*)DCI)->harq_pid = FLEXRAN_DCI->harq_process; \ - ((TYPE*)DCI)->rv = FLEXRAN_DCI->rv[0]; \ - ((TYPE*)DCI)->rballoc = FLEXRAN_DCI->rb_bitmap; \ - ((TYPE*)DCI)->rah = FLEXRAN_DCI->res_alloc; \ - ((TYPE*)DCI)->mcs = FLEXRAN_DCI->mcs[0]; \ - ((TYPE*)DCI)->TPC = FLEXRAN_DCI->tpc; \ - ((TYPE*)DCI)->ndi = FLEXRAN_DCI->ndi[0]; - -#define FILL_DCI_TDD_1(TYPE, DCI, FLEXRAN_DCI) \ - ((TYPE*)DCI)->harq_pid = FLEXRAN_DCI->harq_process; \ - ((TYPE*)DCI)->rv = FLEXRAN_DCI->rv[0]; \ - ((TYPE*)DCI)->dai = FLEXRAN_DCI->dai; \ - ((TYPE*)DCI)->rballoc = FLEXRAN_DCI->rb_bitmap; \ - ((TYPE*)DCI)->rah = FLEXRAN_DCI->res_alloc; \ - ((TYPE*)DCI)->mcs = FLEXRAN_DCI->mcs[0]; \ - ((TYPE*)DCI)->TPC = FLEXRAN_DCI->tpc; \ - ((TYPE*)DCI)->ndi = FLEXRAN_DCI->ndi[0]; +#ifndef __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ +#define __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ + +#include "flexran_agent_defs.h" +#include "flexran.pb-c.h" +#include "header.pb-c.h" +#include "MeasResults.h" + +#define RINGBUFFER_SIZE 100 + + +typedef struct +{ + int32_t rnti; + int32_t meas_id; + int32_t rsrp; + int32_t rsrq; + + /*To Be Extended*/ +}rrc_meas_stats; + +/* RRC CMI statistics */ +rrc_meas_stats * meas_stats; + + +/* FLEXRAN AGENT-RRC Interface */ +typedef struct { + + + /// Notify the controller for a state change of a particular UE, by sending the proper + /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) + void (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, + uint8_t state_change); + + void (*flexran_trigger_rrc_measurements)(mid_t mod_id, MeasResults_t* measResults); + +} AGENT_RRC_xface; #endif diff --git a/openair2/ENB_APP/L1_paramdef.h b/openair2/ENB_APP/L1_paramdef.h new file mode 100644 index 0000000000000000000000000000000000000000..b062235ff69b6aaefb5cc40bff392419df524df3 --- /dev/null +++ b/openair2/ENB_APP/L1_paramdef.h @@ -0,0 +1,73 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 openair2/ENB_APP/L1_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/* L1 configuration parameters names */ +#define CONFIG_STRING_L1_CC "num_cc" +#define CONFIG_STRING_L1_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_L1_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_L1_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_L1_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_L1_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* L1 configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define L1PARAMS_DESC { \ +{CONFIG_STRING_L1_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ +} +#define L1_CC_IDX 0 +#define L1_TRANSPORT_N_PREFERENCE_IDX 1 +#define L1_LOCAL_N_IF_NAME_IDX 2 +#define L1_LOCAL_N_ADDRESS_IDX 3 +#define L1_REMOTE_N_ADDRESS_IDX 4 +#define L1_LOCAL_N_PORTC_IDX 5 +#define L1_REMOTE_N_PORTC_IDX 6 +#define L1_LOCAL_N_PORTD_IDX 7 +#define L1_REMOTE_N_PORTD_IDX 8 + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h new file mode 100644 index 0000000000000000000000000000000000000000..b006be82b9926f1a1178680de5938cefb94c2e38 --- /dev/null +++ b/openair2/ENB_APP/MACRLC_paramdef.h @@ -0,0 +1,103 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 openair2/ENB_APP/MACRLC_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/* MACRLC configuration parameters names */ +#define CONFIG_STRING_MACRLC_CC "num_cc" +#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference" +#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" +#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME "local_s_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" +#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" +#define CONFIG_STRING_MACRLC_SCHED_MODE "scheduler_mode" +#define CONFIG_STRING_MACRLC_PHY_TEST_MODE "phy_test_mode" + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* MacRLC configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define MACRLCPARAMS_DESC { \ +{CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_L1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_RRC", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_SCHED_MODE, NULL, 0, strptr:NULL, defstrval:"default", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_PHY_TEST_MODE, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +} +#define MACRLC_CC_IDX 0 +#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 +#define MACRLC_LOCAL_N_IF_NAME_IDX 2 +#define MACRLC_LOCAL_N_ADDRESS_IDX 3 +#define MACRLC_REMOTE_N_ADDRESS_IDX 4 +#define MACRLC_LOCAL_N_PORTC_IDX 5 +#define MACRLC_REMOTE_N_PORTC_IDX 6 +#define MACRLC_LOCAL_N_PORTD_IDX 7 +#define MACRLC_REMOTE_N_PORTD_IDX 8 +#define MACRLC_TRANSPORT_S_PREFERENCE_IDX 9 +#define MACRLC_LOCAL_S_IF_NAME_IDX 10 +#define MACRLC_LOCAL_S_ADDRESS_IDX 11 +#define MACRLC_REMOTE_S_ADDRESS_IDX 12 +#define MACRLC_LOCAL_S_PORTC_IDX 13 +#define MACRLC_REMOTE_S_PORTC_IDX 14 +#define MACRLC_LOCAL_S_PORTD_IDX 15 +#define MACRLC_REMOTE_S_PORTD_IDX 16 +#define MACRLC_SCHED_MODE_IDX 17 +#define MACRLC_PHY_TEST_IDX 18 +/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index ac939b828cc13399511a808a92159919285b7d39..f734686f011dcb1899a3bb95a52a92f4c6076572 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -38,6 +38,11 @@ message flex_cell_config { optional uint32 srs_mac_up_pts = 32; // Boolean value. See TS 36.211, section 5.5.3.2. TDD only optional uint32 enable_64QAM = 33; // One of the FLEQ_* enum values optional uint32 carrier_index = 34; // Carrier component index + optional uint32 dl_freq = 35; // operating downlink frequency + optional uint32 ul_freq = 36; // operating uplink frequency + optional uint32 eutra_band= 37; // operating band + optional int32 dl_pdsch_power = 38; // operating downlink power + optional int32 ul_pusch_power = 39; // operating uplink power } message flex_ue_config { @@ -76,6 +81,7 @@ message flex_ue_config { optional uint32 pcell_carrier_index = 27; // Index of primary cell repeated flex_scell_config scell_config = 28; // Secondary cells configuration optional uint32 scell_deactivation_timer = 29;// Deactivation timer for secondary cell + optional uint64 imsi = 30; } message flex_lc_ue_config { diff --git a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto index 0f7e34de156599a448265e2846b9b69c83aea5c6..ef0eea3bd2eb9ed7062ec11195e6856d246a806c 100644 --- a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto +++ b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto @@ -3,4 +3,4 @@ package protocol; enum flex_control_delegation_type { FLCDT_MAC_DL_UE_SCHEDULER = 1; // DL UE scheduler delegation -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto index c92f171b0ee9e21d163633b86c021e74aa47b641..29e072383550fce0fc6dbabc2265fd79e1e62ed5 100644 --- a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto +++ b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto @@ -16,6 +16,12 @@ message flex_dl_data { optional uint32 act_deact_ce = 6; //Hex content of MAC CE for Activation/Deactivation in CA } + +message flex_ul_data { + optional uint32 rnti = 1; + optional flex_ul_dci ul_dci = 2; +} + // // Body of the RAR scheduler configuration // @@ -56,4 +62,4 @@ message flex_pdcch_ofdm_sym_count { enum flex_broadcast_type { FLBT_BCCH = 0; FLBT_PCCH = 1; -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 8c0c300efea152c1b5a3943807504d5d1295bfaf..9255372340283d8ce89bb0c1c4cfc6c19a2710a9 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -8,6 +8,7 @@ import "config_messages.proto"; import "controller_commands.proto"; import "control_delegation.proto"; + message flexran_message { optional flexran_direction msg_dir = 100; oneof msg { @@ -28,6 +29,8 @@ message flexran_message { flex_ue_state_change ue_state_change_msg = 15; flex_control_delegation control_delegation_msg = 16; flex_agent_reconfiguration agent_reconfiguration_msg = 17; + flex_rrc_triggering rrc_triggering = 18; + flex_ul_mac_config ul_mac_config_msg = 19; } } @@ -128,8 +131,9 @@ message flex_enb_config_request { message flex_enb_config_reply { optional flex_header header = 1; - optional uint32 eNB_id = 2; // Unique id to distinguish the eNB + optional uint64 eNB_id = 2; // Unique id to distinguish the eNB repeated flex_cell_config cell_config = 3; + optional uint32 device_spec = 4; } message flex_ue_config_request { @@ -163,6 +167,18 @@ message flex_dl_mac_config { repeated flex_pdcch_ofdm_sym_count ofdm_sym = 6; // OFDM symbol count for each CC } +message flex_ul_mac_config { + optional flex_header header = 1; + optional uint32 sfn_sf = 2; + repeated flex_ul_data ul_ue_data = 3; +} + +message flex_rrc_triggering { + + optional flex_header header = 1; + optional string rrc_trigger = 2; +} + // // UE state change message // @@ -190,7 +206,7 @@ message flex_control_delegation { message flex_agent_reconfiguration { optional flex_header header = 1; - optional string policy = 2; // The policy changes using YAML syntax in string format + optional string policy = 2; // The policy changes using YAML syntax in string format } // Extensions of the echo request and reply diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index 939429f51fe134c644d14dce5097154bea17e280..8900b934920eca605cce1746c2aa014ef8564bce 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -40,5 +40,7 @@ enum flex_type { // Control delegation messages FLPT_DELEGATE_CONTROL = 15; FLPT_RECONFIGURE_AGENT = 16; + FLPT_RRC_TRIGGERING = 17; + FLPT_UL_MAC_CONFIG = 18; } diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto index 89b8f0e380605a12077aae640728b7fbf25fcc47..bd2b9cbe509a887b83f29fbfca13c2e29bf1bf2a 100644 --- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto +++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto @@ -36,6 +36,39 @@ message flex_dl_dci { optional uint32 cif = 27; // CIF for cross-carrier scheduling } +message flex_ul_dci { + optional uint32 rnti = 1; + optional uint32 rb_start = 2; // The start RB allocated to the UE + optional uint32 rb_len = 3; // The number of RBs allocated to the UE + optional uint32 mcs = 4; // Modulation and coding scheme + optional uint32 cyclic_shift2 = 5; // match DCI format 0/4 PDU + optional uint32 freq_hop_flag = 6; // 0 no hopping, 1 hoppping + optional uint32 freq_hop_map = 7; // Frequency hopping bits (0..4) + optional uint32 ndi = 8; // New data indicator + optional uint32 rv = 9; // Redundancy version + optional uint32 harq_pid = 10; // The harq process id + optional uint32 ultx_mode = 11; // A FLULM_* value + optional uint32 tbs_size = 12; // The size of each TBS + optional uint32 n_srs = 13; // Overlap indication with srs + optional uint32 res_alloc = 14; // Type of resource allocation + optional uint32 size = 15; // Size of the ULSCH PDU in bytes for UL Grant. + + optional uint32 dai = 16; // TDD only + +// optional uint32 tb_swap = 17; // Boolean. TB to codeword swap flag + +// optional uint32 pdcch_order = 19; +// optional uint32 preamble_index = 20; // Only valid if pdcch_order = 1 +// optional uint32 prach_mask_index = 21; // Only valid if pdcch_order = 1 + +// optional uint32 tbs_idx = 23; // The TBS index for Format 1A + + + + +} + + // // Messages related to the creation of RLC PDUs // @@ -74,4 +107,4 @@ enum flex_vrb_format { enum flex_ngap_val { FLNGV_1 = 0; FLNGV_2 = 1; -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index fa985bf9cc4af4cdfa8318d640239364aac58af2..ee286981f52f89bf4fe979d1b165fb220b7efa4e 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -182,3 +182,126 @@ message flex_noise_interference_report { optional int32 p0_nominal_pucch = 4; } +// +// RRC Measurements Primitives +// + + +message flex_rrc_measurements { + // Measurement identifier. + optional int32 measid = 1; + // Primary Cell Reference Signal Received Power (RSRP). + optional int32 pcell_rsrp = 2; + // Primary Cell Reference Signal Received Quality (RSRQ). + optional int32 pcell_rsrq = 3; + // Neighboring cells measurements performed by UE. + optional flex_neigh_cells_measurements neigh_meas = 4; +} + +message flex_neigh_cells_measurements { + // Neighboring EUTRA cells measurements. + repeated flex_eutra_measurements eutra_meas = 1; +} + +message flex_eutra_measurements { + // Physical Cell identifier. + optional int32 phys_cell_id = 1; + // EUTRA Cell Global Identity (CGI) measurement. + optional flex_eutra_cgi_measurements cgi_meas = 2; + // EUTRA nearby cell reference signal measurement. + optional flex_eutra_ref_signal_meas meas_result = 3; +} + +message flex_eutra_cgi_measurements { + // EUTRA Cell Global Identity (CGI). + optional flex_cell_global_eutra_id cgi = 1; + // Tracking area code of the neighbor cell. + optional uint32 tracking_area_code = 2; + // Public land mobile network identifiers of neighbor cell. + repeated flex_plmn_identity plmn_id = 3; +} + +message flex_cell_global_eutra_id { + // Public land mobile network identifier of neighbor cell. + optional flex_plmn_identity plmn_id = 1; + // Cell identifier of neighbor cell. + optional uint32 cell_id = 2; +} + +message flex_plmn_identity { + // Mobile Network Code (MNC). + repeated uint32 mnc = 1; + // Mobile Country Code (MCC). + repeated uint32 mcc = 2; + // tracking area code + repeated uint32 tac = 3; +} + +message flex_eutra_ref_signal_meas { + // Neighboring Cell RSRP + optional int32 rsrp = 1; + // Neighboring Cell RSRQ + optional int32 rsrq = 2; +} + +// +// PDCP Statistics +// + +message flex_pdcp_stats { + + optional uint32 pkt_tx = 1; + optional uint32 pkt_tx_bytes = 2; + optional uint32 pkt_tx_sn = 3; + optional uint32 pkt_tx_w = 4; + optional uint32 pkt_tx_bytes_w = 5; + optional uint32 pkt_tx_aiat = 7; + optional uint32 pkt_tx_aiat_w = 8; + + optional uint32 pkt_rx = 9; + optional uint32 pkt_rx_bytes = 10; + optional uint32 pkt_rx_sn = 11; + optional uint32 pkt_rx_w = 12; + optional uint32 pkt_rx_bytes_w = 13; + optional uint32 pkt_rx_aiat = 14; + optional uint32 pkt_rx_aiat_w = 15; + optional uint32 pkt_rx_oo = 16; + + optional uint64 sfn=17; +} + +// +// MAC Stats +// + +message flex_mac_stats { + + optional uint32 tbs_dl = 1; + optional uint32 tbs_ul = 2; + optional uint32 prb_retx_dl = 3; + optional uint32 prb_retx_ul = 4; + optional uint32 prb_dl = 5; + optional uint32 prb_ul = 6; + optional uint32 mcs1_dl = 7; + optional uint32 mcs2_dl = 8; + optional uint32 mcs1_ul = 9; + optional uint32 mcs2_ul = 10; + optional uint32 total_bytes_sdus_ul = 11; + optional uint32 total_bytes_sdus_dl = 12; + optional uint32 total_prb_retx_dl = 13; + optional uint32 total_prb_retx_ul = 14; + optional uint32 total_prb_dl = 15; + optional uint32 total_prb_ul = 16; + optional uint32 total_pdu_dl = 17; + optional uint32 total_pdu_ul = 18; + optional uint32 total_tbs_dl = 19; + optional uint32 total_tbs_ul = 20; + repeated flex_mac_sdus_dl mac_sdus_dl = 21; + optional uint32 harq_round = 22; +} + +message flex_mac_sdus_dl { + + optional uint32 sdu_length = 1; + optional uint32 lcid = 2; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto index d8c0651fa16962a0f26e9c2c922cf0e9dbbd02c9..8eb6510de3ca0c78a3a90bdec955616a29924875 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto @@ -47,6 +47,9 @@ message flex_ue_stats_report { optional flex_dl_cqi_report dl_cqi_report = 7; optional flex_paging_buffer_report pbr = 8; optional flex_ul_cqi_report ul_cqi_report = 9; + optional flex_rrc_measurements rrc_measurements = 10; + optional flex_pdcp_stats pdcp_stats = 11; + optional flex_mac_stats mac_stats = 12; } // @@ -77,11 +80,17 @@ enum flex_cell_stats_type { // Flags for UE-related statistics enum flex_ue_stats_type { FLUST_BSR = 1; - FLUST_PRH = 2; + FLUST_PHR = 2; FLUST_RLC_BS = 4; FLUST_MAC_CE_BS = 8; FLUST_DL_CQI = 16; FLUST_PBS = 32; FLUST_UL_CQI = 64; + FLUST_MAC_STATS = 128; + + FLUST_PDCP_STATS = 1024; + FLUST_RRC_MEASUREMENTS = 65536; // To be extended with more types of stats -} \ No newline at end of file + + +} diff --git a/openair2/ENB_APP/MESSAGES/V2/time_common.proto b/openair2/ENB_APP/MESSAGES/V2/time_common.proto index 8bd2497443daaed136dc55b39740c66776d95795..6c0affbe51e676a8b725de582098af960ad2ca87 100644 --- a/openair2/ENB_APP/MESSAGES/V2/time_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/time_common.proto @@ -25,6 +25,7 @@ message flex_ul_info { repeated uint32 ul_reception = 2; optional uint32 reception_status = 3; optional uint32 tpc = 4; - optional uint32 serv_cell_index = 5; + optional uint32 serv_cell_index = 5; + optional uint32 rssi = 6; } diff --git a/openair2/ENB_APP/NB_IoT_config.c b/openair2/ENB_APP/NB_IoT_config.c new file mode 100644 index 0000000000000000000000000000000000000000..09e22ef8457b17578be6f03b9a17e4d3b8988607 --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_config.c @@ -0,0 +1,286 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +/* + nbiot_config.c + ------------------- + AUTHOR : Francois Taburet + COMPANY : NOKIA + EMAIL : francois.taburet@nokia-bell-labs.com +*/ + +#include <string.h> +#include <inttypes.h> + +#include "log.h" +#include "log_extern.h" +#include "assertions.h" +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# if defined(ENABLE_USE_MME) +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# endif +#endif +#include "SystemInformationBlockType2.h" + +#include "PHY/extern.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "RRC_paramsvalues.h" +#include "NB_IoT_paramdef.h" +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" +#include "LAYER2/MAC/proto_NB_IoT.h" + + +void RCconfig_NbIoTL1(void) { + paramdef_t NbIoT_L1_Params[] = L1PARAMS_DESC; + paramlist_def_t NbIoT_L1_ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0}; + +/* No component carrier for NbIoT, ignore number of CC */ +// NbIoT_L1_Params[L1_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + + config_getlist( &NbIoT_L1_ParamList,NbIoT_L1_Params,sizeof(NbIoT_L1_Params)/sizeof(paramdef_t), NULL); + if (NbIoT_L1_ParamList.numelt > 0) { + if (RC.L1_NB_IoT == NULL) { + RC.L1_NB_IoT = (PHY_VARS_eNB_NB_IoT **)malloc(RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); + LOG_I(PHY,"RC.L1_NB_IoT = %p\n",RC.L1_NB_IoT); + memset(RC.L1_NB_IoT,0,RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); + } + + + for(int j = 0; j <NbIoT_L1_ParamList.numelt ; j++) { + if (RC.L1_NB_IoT[j] == NULL) { + RC.L1_NB_IoT[j] = (PHY_VARS_eNB_NB_IoT *)malloc(sizeof(PHY_VARS_eNB_NB_IoT)); + LOG_I(PHY,"RC.L1_NB_IoT[%d] = %p\n",j,RC.L1_NB_IoT[j]); + memset(RC.L1_NB_IoT[j],0,sizeof(PHY_VARS_eNB_NB_IoT)); + } + if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { + + } + else if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { + RC.L1_NB_IoT[j]->eth_params_n.local_if_name = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.remote_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.my_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + } + + else { // other midhaul + } + }// j=0..num_inst + printf("Initializing northbound interface for NB-IoT L1\n"); + l1_north_init_NB_IoT(); + } else { + LOG_I(PHY,"No " NBIOT_L1LIST_CONFIG_STRING " configuration found"); + } +} + +void RCconfig_NbIoTmacrlc(void) { + + + + paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC; + paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; + + +/* No component carrier for NbIoT, ignore number of CC */ +// NbIoT_MacRLC_Params[MACRLC_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + + config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params,sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), NULL); + + + if ( NbIoT_MacRLC_ParamList.numelt > 0) { + mac_top_init_eNB_NB_IoT(); + for (int j=0;j<RC.nb_nb_iot_macrlc_inst;j++) { + + if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { + // check number of instances is same as RRC/PDCP + + } else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) { + RC.nb_iot_mac[j]->eth_params_n.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; + RC.nb_iot_mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + } else { // other midhaul + AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); + } + + if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) { + + + } else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) { + RC.nb_iot_mac[j]->eth_params_s.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; + } else { // other midhaul + AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); + } + }// j=0..num_inst */ + } else {// MacRLC_ParamList.numelt > 0 + AssertFatal (0, + "No " NBIOT_MACRLCLIST_CONFIG_STRING " configuration found"); + } +} + + + + +int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc) { + + + char instprefix[MAX_OPTNAME_SIZE*3 + 32]; + + + checkedparam_t NBIoTCheckParams[] = NBIOT_RRCPARAMS_CHECK_DESC; + paramdef_t NBIoTParams[] = NBIOTRRCPARAMS_DESC; + + paramdef_t NBIoTPrachParams[] = NBIOTRRC_NPRACH_PARAMS_DESC; + checkedparam_t NBIoTPrachCheckParams[] = NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC; + + paramdef_t NBIoTRRCRefParams[] = NBIOTRRCPARAMS_RRCREF_DESC; + + paramdef_t NBIoTLteCCParams[] = NBIOT_LTECCPARAMS_DESC; + checkedparam_t NBIoTLteCCCheckParams[] = NBIOT_LTECCPARAMS_CHECK_DESC; +/* map parameter checking array instances to parameter definition array instances */ + for (int i=0; (i<sizeof(NBIoTParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTCheckParams)/sizeof(checkedparam_t)); i++ ) { + NBIoTParams[i].chkPptr = &(NBIoTCheckParams[i]); + } + for (int i=0; (i<sizeof(NBIoTPrachParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTPrachCheckParams)/sizeof(checkedparam_t)); i++ ) { + NBIoTPrachParams[i].chkPptr = &(NBIoTPrachCheckParams[i]); + } + +/* brut force itti message fields assignment, to be redesigned with itti replacement */ + NBIoTParams[NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize_NB); + NBIoTParams[NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer_NB); + NBIoTParams[NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep_NB); + NBIoTParams[NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower_NB); + NBIoTParams[NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax_CE_NB); + NBIoTParams[NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff_NB); + NBIoTParams[NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle_NB); + NBIoTParams[NBIOT_NPRACH_CP_LENGTH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_CP_Length); + NBIoTParams[NBIOT_NPRACH_RSRP_RANGE_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_rsrp_range); + + + + NBIoTParams[NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).maxNumPreambleAttemptCE_NB); + + NBIoTParams[NBIOT_NPDSCH_NRS_POWER_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdsch_nrs_Power); + NBIoTParams[NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_ack_nack_numRepetitions_NB); + NBIoTParams[NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_srs_SubframeConfig_NB); + NBIoTParams[NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_threeTone_CyclicShift_r13); + NBIoTParams[NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_sixTone_CyclicShift_r13); + + NBIoTParams[NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupAssignmentNPUSCH_r13); + NBIoTParams[NBIOT_DL_GAPTHRESHOLD_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapThreshold_NB); + NBIoTParams[NBIOT_DL_GAPPERIODICITY_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapPeriodicity_NB); + + NBIoTParams[NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_p0_NominalNPUSCH); + + NBIoTParams[NBIOT_DELTAPREAMBLEMSG3_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).deltaPreambleMsg3); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311_NB); + + sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]",nbiotrrc_id); + config_get( NBIoTParams,sizeof(NBIoTParams)/sizeof(paramdef_t),instprefix); + + NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierMSG3_RangeStart = config_get_processedint( &(NBIoTParams[NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX]) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupHoppingEnabled = config_get_processedint( &(NBIoTParams[NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX] ) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapDurationCoeff_NB = config_get_processedint( &(NBIoTParams[NBIOT_DL_GAPDURATIONCOEFF_NB_IDX] ) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_alpha = config_get_processedint( &(NBIoTParams[NBIOT_NPUSCH_ALPHA_IDX] ) ); + for (int i=0; i<MAX_NUM_NBIOT_CELEVELS; i++) { + char *tmpptr=NULL; + NBIoTPrachParams[NBIOT_NPRACH_PERIODICITY_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_Periodicity[i]); + NBIoTPrachParams[NBIOT_NPRACH_STARTTIME_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_StartTime[i]); + NBIoTPrachParams[NBIOT_NPRACH_SUBCARRIEROFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierOffset[i]); + NBIoTPrachParams[NBIOT_NPRACH_NUMSUBCARRIERS_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_NumSubcarriers[i]); + NBIoTPrachParams[NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).numRepetitionsPerPreambleAttempt_NB[i]); + NBIoTParams[NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_NumRepetitions_RA[i]); + NBIoTParams[NBIOT_NPDCCH_STARTSF_CSS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_StartSF_CSS_RA[i]); + NBIoTParams[NBIOT_NPDCCH_OFFSET_RA_IDX].strptr = &tmpptr; + sprintf(instprefix, "%s.[%i].%s.[%i]",NBIOT_RRCLIST_CONFIG_STRING, nbiotrrc_id,NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING,i); + config_get( NBIoTPrachParams,sizeof(NBIoTPrachParams)/sizeof(paramdef_t),instprefix); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_Offset_RA[i] = config_get_processedint( &(NBIoTPrachParams[NBIOT_NPDCCH_OFFSET_RA_IDX]) ); + } +/* get the LTE RRC and CC this NB-IoT RRC instance is attached to */ + sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]." NBIOT_LTERRCREF_CONFIG_STRING, nbiotrrc_id ); + config_get( NBIoTRRCRefParams,sizeof(NBIoTRRCRefParams)/sizeof(paramdef_t),instprefix); + +/* read SIB1 parameters in the LTE RRC and CC sections */ + sprintf(instprefix, ENB_CONFIG_STRING_ENB_LIST ".[%i]." ENB_CONFIG_STRING_COMPONENT_CARRIERS ".[%i]", + *(NBIoTRRCRefParams[NBIOT_RRCINST_IDX].uptr), *(NBIoTRRCRefParams[NBIOT_CCINST_IDX].uptr)); + + NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config); + NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_S_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config_s); + NBIoTLteCCParams[LTECCPARAMS_EUTRA_BAND_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).eutra_band); + NBIoTLteCCParams[LTECCPARAMS_DOWNLINK_FREQUENCY_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).downlink_frequency); + NBIoTLteCCParams[LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset); + NBIoTLteCCParams[LTECCPARAMS_NID_CELL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).Nid_cell); + NBIoTLteCCParams[LTECCPARAMS_N_RB_DL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).N_RB_DL); + + for (int i=0; (i<sizeof(NBIoTLteCCParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTLteCCCheckParams)/sizeof(checkedparam_t)); i++ ) { + NBIoTLteCCParams[i].chkPptr = &(NBIoTLteCCCheckParams[i]); + } + config_get( NBIoTLteCCParams,sizeof(NBIoTLteCCParams)/sizeof(paramdef_t),instprefix); + NBIOTRRC_CONFIGURATION_REQ (msg_p).frame_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_FRAME_TYPE_IDX]) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_IDX]) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_UL_IDX]) ); +return 0; +} + +void RCConfig_NbIoT(RAN_CONTEXT_t *RC) { + + paramlist_def_t NbIoT_MACRLCParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; + paramlist_def_t NbIoT_L1ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0}; + paramlist_def_t NbIoT_ParamList = {NBIOT_RRCLIST_CONFIG_STRING,NULL,0}; + + + config_getlist( &NbIoT_ParamList,NULL,0,NULL); + RC->nb_nb_iot_rrc_inst = NbIoT_ParamList.numelt; + + + + + config_getlist( &NbIoT_MACRLCParamList,NULL,0, NULL); + RC->nb_nb_iot_macrlc_inst = NbIoT_MACRLCParamList.numelt; + // Get num L1 instances + config_getlist( &NbIoT_L1ParamList,NULL,0, NULL); + RC->nb_nb_iot_L1_inst = NbIoT_L1ParamList.numelt; + +} diff --git a/openair2/ENB_APP/NB_IoT_config.h b/openair2/ENB_APP/NB_IoT_config.h new file mode 100644 index 0000000000000000000000000000000000000000..314fca81802124b8258e99af1616e1455a840607 --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_config.h @@ -0,0 +1,37 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +/* + nbiot_config.h + ------------------- + AUTHOR : Francois Taburet + COMPANY : NOKIA + EMAIL : francois.taburet@nokia-bell-labs.com +*/ +#ifndef INCLUDE_NBIOT_CONFIG_H +#define INCLUDE_NBIOT_CONFIG_H + + +extern void RCconfig_NbIoTL1(void) ; +extern void RCconfig_NbIoTmacrlc(void); +extern int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc); +extern void RCConfig_NbIoT(RAN_CONTEXT_t *RC); +#endif diff --git a/openair2/ENB_APP/NB_IoT_interface.c b/openair2/ENB_APP/NB_IoT_interface.c new file mode 100644 index 0000000000000000000000000000000000000000..c4884453c2e9cc03d62f5c4e454bd3a3dd3f57fb --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_interface.c @@ -0,0 +1,58 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 openair2/ENB_APP/NB_IoT_interface.c + * \brief: load library implementing coding/decoding algorithms + * \date 2018 + * \version 0.1 + * \note + * \warning + */ +#define _GNU_SOURCE +#include <sys/types.h> + + +#include "openair1/PHY/phy_extern.h" +#include "common/utils/load_module_shlib.h" +#define NBIOT_INTERFACE_SOURCE +#include "NB_IoT_interface.h" + + + + +int load_NB_IoT(void) { + int ret; + RCConfig_NbIoT_f_t RCConfig; + loader_shlibfunc_t shlib_fdesc[]=NBIOT_INTERFACE_FLIST; + + ret=load_module_shlib(NBIOT_MODULENAME,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t)); + if (ret) { + return ret; + } + RCConfig = get_shlibmodule_fptr(NBIOT_MODULENAME,NBIOT_RCCONFIG_FNAME ); + if (RCConfig == NULL) { + return -1; + } + + RCConfig(&RC); +return 0; +} + diff --git a/openair2/ENB_APP/NB_IoT_interface.h b/openair2/ENB_APP/NB_IoT_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..b3454b077bc1cc64aa514c5abed78c7a8c53138e --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_interface.h @@ -0,0 +1,50 @@ +/* + *Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 openair2/ENB_APP/NB_IoT_interface.h + * \brief: api interface for nb-iot application + * \date 2018 + * \version 0.1 + * \note + * \warning + */ +#ifndef NBIOT_INTERFACE_H +#define NBIOT_INTERFACE_H + + +#define NBIOT_MODULENAME "NB_IoT" + +typedef void(*RCConfig_NbIoT_f_t)(RAN_CONTEXT_t *RC); +#define NBIOT_RCCONFIG_FNAME "RCConfig_NbIoT" + +#ifdef NBIOT_INTERFACE_SOURCE + +#define NBIOT_INTERFACE_FLIST {\ +{NBIOT_RCCONFIG_FNAME,NULL},\ +} + +#else /* NBIOT_INTERFACE_SOURCE */ + +extern int load_NB_IoT(void); + +#endif + +#endif diff --git a/openair2/ENB_APP/NB_IoT_paramdef.h b/openair2/ENB_APP/NB_IoT_paramdef.h new file mode 100644 index 0000000000000000000000000000000000000000..6409fe63ee56479b9cc1fca486b9d63bd77f8bda --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_paramdef.h @@ -0,0 +1,400 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 openair2/ENB_APP/enb_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + +#include "common/config/config_paramdesc.h" +#include "SystemInformationBlockType2.h" +#include "DL-GapConfig-NB-r13.h" +#include "NPRACH-Parameters-NB-r13.h" +#include "PowerRampingParameters.h" +#include "BCCH-Config-NB-r13.h" +#include "PCCH-Config-NB-r13.h" +#include "ACK-NACK-NumRepetitions-NB-r13.h" +#include "TDD-Config.h" + + + + + +/* + int16_t eutra_band; + uint32_t downlink_frequency; + int32_t uplink_frequency_offset; + int16_t Nid_cell;// for testing, change later + int16_t N_RB_DL;// for testing, change later +*/ +/*-------------------------------------------------------------------------------------------------------------------*/ +/* SIB1 parameters possibly coming from LTE RRC (in band deployment) */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* component carriers configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOT_LTECCPARAMS_CHECK_DESC { \ + { .s3a= { config_checkstr_assign_integer, FRAMETYPE_OKVALUES, FRAMETYPE_MODVALUES,2}} , \ + { .s2= { config_check_intrange, TDDCONFIG_OKRANGE}}, \ + { .s2= { config_check_intrange, TDDCONFIGS_OKRANGE}}, \ + { .s3a= { config_checkstr_assign_integer, PREFIX_OKVALUES, PREFIX_MODVALUES,2}} , \ + { .s3a= { config_checkstr_assign_integer, PREFIXUL_OKVALUES, PREFIXUL_MODVALUES,2}} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s1= { config_check_intval, NRBDL_OKVALUES,6}} , \ +} + + +#define NBIOT_LTECCPARAMS_DESC { \ +{ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:NULL, defstrval:"FDD", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:NULL, defintval:3, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_PREFIX_TYPE, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_PREFIX_TYPE_UL, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:NULL, defintval:7, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:NULL, defint64val:2680000000, TYPE_UINT64, 0}, \ +{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:NULL, defintval:-120000000, TYPE_INT, 0}, \ +{ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:NULL, defintval:25, TYPE_UINT, 0}, \ +} +#define LTECCPARAMS_FRAME_TYPE_IDX 0 +#define LTECCPARAMS_TDD_CONFIG_IDX 1 +#define LTECCPARAMS_TDD_CONFIG_S_IDX 2 +#define LTECCPARAMS_PREFIX_TYPE_IDX 3 +#define LTECCPARAMS_PREFIX_TYPE_UL_IDX 4 +#define LTECCPARAMS_EUTRA_BAND_IDX 5 +#define LTECCPARAMS_DOWNLINK_FREQUENCY_IDX 6 +#define LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX 7 +#define LTECCPARAMS_NID_CELL_IDX 8 +#define LTECCPARAMS_N_RB_DL_IDX 9 + + +/*-------------------------------------------------------------------------------------------------------------------*/ + +/* NB-Iot RRC list section name */ +#define NBIOT_RRCLIST_CONFIG_STRING "NB-IoT_RRCs" + + +#define RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES {20,50,80,120,180,240,320,400} +#define PREF1(A) RACH_CE_LevelInfo_r13__ra_ResponseWindowSize_r13_ ## A +#define RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES { PREF1(sf20),PREF1(sf50),PREF1(sf80),PREF1(sf120), \ + PREF1(sf180),PREF1(sf240),PREF1(sf320),PREF1(sf400) } + + +#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES {80,100,120,160,200,240,480,960} +#define PREF2(A) RACH_CE_LevelInfo_r13__mac_ContentionResolutionTimer_r13_ ## A +#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES { PREF2(sf80),PREF2(sf100),PREF2(sf120),PREF2(sf160), \ + PREF2(sf200),PREF2(sf240),PREF2(sf480),PREF2(sf960) } + + +#define RACH_POWERRAMPINGSTEP_NB_OKVALUES {0,2,4,6} +#define PREF3(A) PowerRampingParameters__powerRampingStep_ ## A +#define RACH_POWERRAMPINGSTEP_NB_MODVALUES { PREF3(dB0),PREF3(dB2),PREF3(dB4),PREF3(dB6) } + + +#define RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE {-120, -90} + +#define RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES {3,4,5,6,7,8,10,20,50,100,200} +#define PREF4(A) PreambleTransMax_ ## A +#define RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES { PREF4(n3), PREF4(n4), PREF4(n5), PREF4(n6), PREF4(n7), PREF4(n8), \ + PREF4(n10),PREF4(n20),PREF4(n50),PREF4(n100),PREF4(n200) } + +#define BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES {16,32,64,128} +#define PREF5(A) BCCH_Config_NB_r13__modificationPeriodCoeff_r13_ ## A +#define BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES { PREF5(n16), PREF5(n32), PREF5(n64),PREF5(n128) } + +#define PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES {128,256,512,1024} +#define PREF6(A) PCCH_Config_NB_r13__defaultPagingCycle_r13_ ## A +#define PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES { PREF6(rf128), PREF6(rf256), PREF6(rf512), PREF6(rf1024) } + +#define NPRACH_CP_LENGTH_OKVALUES {0,1} +#define NPRACH_RSRP_RANGE_OKVALUES {0,96} + +#define MSG3RANGESTART_OKVALUES {"zero","oneThird","twoThird","one"} +#define MSG3RANGESTART_MODVALUES {NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_zero, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_oneThird, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_twoThird, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_one} + + +#define MAXNUMPREAMBLEATTEMPTCE_OKVALUES {3,4,5,6,7,8,10} +#define MAXNUMPREAMBLEATTEMPTCE_MODVALUES { NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n3, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n4, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n5, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n6, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n7, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n8, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n10 } + +#define NPDSCH_NRS_POWER_OKRANGE {-60,50} + +#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES {1,2,4,8,16,32,64,128} +#define PREF9(A) ACK_NACK_NumRepetitions_NB_r13_ ## A +#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES { PREF9(r1), PREF9(r2), PREF9(r4), PREF9(r8), \ + PREF9(r16), PREF9(r32), PREF9(r64), PREF9(r128) } + +#define NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE {0,15} +#define NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE {0,2} +#define NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE {0,3} + +#define NPUSCH_GROUPHOPPINGENABLED_OKVALUES {"enable","disable"} +#define NPUSCH_GROUPHOPPINGENABLED_MODVALUES {1,0} + +#define NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE {0,29} + +#define DLGAPTHRESHOLD_OKVALUES {32,64,128,256} +#define DLGAPTHRESHOLD_MODVALUES { DL_GapConfig_NB_r13__dl_GapThreshold_r13_n32, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n64, \ + DL_GapConfig_NB_r13__dl_GapThreshold_r13_n128, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n256} \ + +#define DLGAPPERIODICITY_OKVALUES {64,128,256,512} +#define DLGAPPERIODICITY_MODVALUES { DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf64, DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf128, \ + DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf256,DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf512} + +#define DLGAPDURATION_OKVALUES {"oneEighth","oneFourth","threeEighth","oneHalf"} +#define DLGAPDURATION_MODVALUES {DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneFourth, \ + DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_threeEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneHalf} + +#define NPUSCH_P0_NOMINALNPUSCH_OKRANGE {-126,24} + +#define NPUSCH_ALPHA_OKVALUES {"AL0","AL04","AL05","AL06","AL07","AL08","AL09","AL1"} +#define NPUSCH_ALPHA_MODVALUES { Alpha_r12_al0, Alpha_r12_al04, Alpha_r12_al05, Alpha_r12_al06, \ + Alpha_r12_al07, Alpha_r12_al08, Alpha_r12_al09, Alpha_r12_al1} + +#define DELTAPREAMBLEMSG3_OKRANGE {-1,6} + + + + + +#define NBIOT_RRCPARAMS_CHECK_DESC { \ + { .s1a= { config_check_modify_integer, RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES, RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES, 8}}, \ + { .s1a= { config_check_modify_integer, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES, 8}}, \ + { .s1a= { config_check_modify_integer, RACH_POWERRAMPINGSTEP_NB_OKVALUES, RACH_POWERRAMPINGSTEP_NB_MODVALUES, 4}} , \ + { .s2= { config_check_intrange, RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE}}, \ + { .s1a= { config_check_modify_integer, RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES, RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES, 11}} , \ + { .s1a= { config_check_modify_integer, BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES, BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES, PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES, 4}} , \ + { .s1= { NULL, NPRACH_CP_LENGTH_OKVALUES ,4}} , \ + { .s2= { config_check_intrange, NPRACH_RSRP_RANGE_OKVALUES}} , \ + { .s3a= { config_checkstr_assign_integer, MSG3RANGESTART_OKVALUES, MSG3RANGESTART_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, MAXNUMPREAMBLEATTEMPTCE_OKVALUES, MAXNUMPREAMBLEATTEMPTCE_MODVALUES, 7}} , \ + { .s1= { config_check_intval, NPDSCH_NRS_POWER_OKRANGE,4}} , \ + { .s1a= { config_check_modify_integer, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES, 8}} , \ + { .s2= { config_check_intrange, NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE}} , \ + { .s2= { config_check_intrange, NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE}} , \ + { .s2= { config_check_intrange, NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE}} , \ + { .s3a= { config_checkstr_assign_integer, NPUSCH_GROUPHOPPINGENABLED_OKVALUES, NPUSCH_GROUPHOPPINGENABLED_MODVALUES, 2}} , \ + { .s2= { config_check_intrange, NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE}} , \ + { .s1a= { config_check_modify_integer, DLGAPTHRESHOLD_OKVALUES, DLGAPTHRESHOLD_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, DLGAPPERIODICITY_OKVALUES, DLGAPPERIODICITY_MODVALUES, 4}} , \ + { .s3a= { config_checkstr_assign_integer, DLGAPDURATION_OKVALUES, DLGAPDURATION_MODVALUES , 4}} , \ + { .s2= { config_check_intrange, NPUSCH_P0_NOMINALNPUSCH_OKRANGE}} , \ + { .s3a= { config_checkstr_assign_integer, NPUSCH_ALPHA_OKVALUES, NPUSCH_ALPHA_MODVALUES, 8}} , \ + { .s2= { config_check_intrange, DELTAPREAMBLEMSG3_OKRANGE}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \ +} +/*-----------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT RRC configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-----------------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRCPARAMS_DESC { \ +{"rach_raResponseWindowSize_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \ +{"rach_macContentionResolutionTimer_NB", NULL, 0, uptr:NULL, defintval:80, TYPE_UINT, 0}, \ +{"rach_powerRampingStep_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"rach_preambleInitialReceivedTargetPower_NB", NULL, 0, iptr:NULL, defintval:-112, TYPE_INT32, 0}, \ +{"rach_preambleTransMax_CE_NB", NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0}, \ +{"bcch_modificationPeriodCoeff_NB", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \ +{"pcch_defaultPagingCycle_NB", NULL, 0, uptr:NULL, defintval:256, TYPE_UINT, 0}, \ +{"nprach_CP_Length", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_rsrp_range", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_SubcarrierMSG3_RangeStart", NULL, 0, strptr:NULL, defstrval:"one", TYPE_STRING, 0}, \ +{"maxNumPreambleAttemptCE_NB", NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \ +{"npdsch_nrs_Power", NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ +{"npusch_ack_nack_numRepetitions_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +{"npusch_srs_SubframeConfig_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_threeTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_sixTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_groupHoppingEnabled", NULL, 0, strptr:NULL, defstrval:"disable", TYPE_STRING, 0}, \ +{"npusch_groupAssignmentNPUSCH_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"dl_GapThreshold_NB", NULL, 0, uptr:NULL, defintval:32, TYPE_UINT, 0}, \ +{"dl_GapPeriodicity_NB", NULL, 0, uptr:NULL, defintval:64, TYPE_UINT, 0}, \ +{"dl_GapDurationCoeff_NB", NULL, 0, strptr:NULL, defstrval:"oneEighth", TYPE_STRING, 0}, \ +{"npusch_p0_NominalNPUSCH", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \ +{"npusch_alpha", NULL, 0, strptr:NULL, defstrval:"AL0", TYPE_STRING, 0}, \ +{"deltaPreambleMsg3", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \ +{"ue_TimersAndConstants_t300_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t301_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t310_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t311_NB", NULL, 0, uptr:NULL, defintval:10000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_n310_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_n311_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +} + +#define NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX 0 +#define NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX 1 +#define NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX 2 +#define NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX 3 +#define NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX 4 +#define NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX 5 +#define NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX 6 +#define NBIOT_NPRACH_CP_LENGTH_IDX 7 +#define NBIOT_NPRACH_RSRP_RANGE_IDX 8 +#define NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX 9 +#define NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX 10 +#define NBIOT_NPDSCH_NRS_POWER_IDX 11 +#define NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX 12 +#define NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX 13 +#define NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX 14 +#define NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX 15 +#define NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX 16 +#define NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX 17 +#define NBIOT_DL_GAPTHRESHOLD_NB_IDX 18 +#define NBIOT_DL_GAPPERIODICITY_NB_IDX 19 +#define NBIOT_DL_GAPDURATIONCOEFF_NB_IDX 20 +#define NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX 21 +#define NBIOT_NPUSCH_ALPHA_IDX 22 +#define NBIOT_DELTAPREAMBLEMSG3_IDX 23 +#define NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX 24 +#define NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX 25 +#define NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX 26 +#define NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX 27 +#define NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX 28 +#define NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX 29 + +/* NB-Iot RRC: link to LTE RRC section name */ +#define NBIOT_LTERRCREF_CONFIG_STRING "LTERRC_Ref" +/*---------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT RRC configuration parameters to link to a LTE RRC instance (in-guard, in-band) */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRCPARAMS_RRCREF_DESC { \ +{"RRC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"CC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +} +/*--------------------------------------------------------------------------------------------------------------*/ +#define NBIOT_RRCINST_IDX 0 +#define NBIOT_CCINST_IDX 1 + +#define NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING "NPRACH-NB-r13" + + +#define NPRACH_PERIODICITY_OKVALUES {40,80,160,240,320,640,1280,2560} +#define NPRACH_PERIODICITY_MODVALUES { NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms40, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms80, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms160, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms240, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms320, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms640, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms1280, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms2560 } + +#define NPRACH_STARTTIME_OKVALUES {8,16,32,64,128,256,512,1024} +#define NPRACH_STARTTIME_MODVALUES { NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms8, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms16, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms32, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms64, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms128, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms256, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms512, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms1024 } + +#define NPRACH_SUBCARRIEROFFSET_OKVALUES {0,12,24,36,2,18,34} +#define NPRACH_SUBCARRIEROFFSET_MODVALUES { NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n0, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n12, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n24, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n36, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n2, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n18, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n34 } + +#define NPRACH_NUMSUBCARRIERS_OKVALUES {12,24,36,48} +#define NPRACH_NUMSUBCARRIERS_MODVALUES { NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n12, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n24, \ + NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n36, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n48 } + + +#define NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES {1,2,4,8,16,32,64,128} +#define NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES { NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n1, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n2, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n4, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n8, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n16, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n32, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n64, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n128} + +#define NPDCCHNUMREPETITIONSRA_OKVALUES {1,2,4,8,16,32,64,128,256,512,1024,2048} +#define NPDCCHNUMREPETITIONSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r4, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r8, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r16, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r32, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r64, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r128, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r256, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r512, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1024,NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2048} + +#define NPDCCHSTARTSFCSSRA_OKVALUES {1,2,4,8,16,32,48,64} +#define NPDCCHSTARTSFCSSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v1dot5, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v2, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v4, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v8, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v16, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v32, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v48, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v64} + +#define NPDCCHOFFSETRA_OKVALUES {"zero","oneEighth","oneFourth","threeEighth"} +#define NPDCCHOFFSETRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_zero, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneEighth, \ + NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneFourth, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_threeEighth} + + + +#define NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC { \ + { .s1a= { config_check_modify_integer, NPRACH_PERIODICITY_OKVALUES, NPRACH_PERIODICITY_MODVALUES, 8 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_STARTTIME_OKVALUES, NPRACH_STARTTIME_MODVALUES, 8 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_SUBCARRIEROFFSET_OKVALUES, NPRACH_SUBCARRIEROFFSET_MODVALUES, 7 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_NUMSUBCARRIERS_OKVALUES, NPRACH_NUMSUBCARRIERS_MODVALUES, 4 }}, \ + { .s1a= { config_check_modify_integer, NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES, NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES,8 }}, \ + { .s1a= { config_check_modify_integer, NPDCCHNUMREPETITIONSRA_OKVALUES, NPDCCHNUMREPETITIONSRA_MODVALUES, 12}}, \ + { .s1a= { config_check_modify_integer, NPDCCHSTARTSFCSSRA_OKVALUES, NPDCCHSTARTSFCSSRA_MODVALUES, 8 }}, \ + { .s3a= { config_checkstr_assign_integer, NPDCCHOFFSETRA_OKVALUES, NPDCCHOFFSETRA_MODVALUES, 4 }}, \ +} + + + +/*------------------------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT NPrach parameters, there will be three ocuurences of these parameters in each RRC instance */ + /* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRC_NPRACH_PARAMS_DESC { \ +{"nprach_Periodicity", NULL, 0, uptr:NULL, defintval:320, TYPE_UINT, 0}, \ +{"nprach_StartTime", NULL, 0, uptr:NULL, defintval:8, TYPE_UINT, 0}, \ +{"nprach_SubcarrierOffset", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_NumSubcarriers", NULL, 0, uptr:NULL, defintval:12, TYPE_UINT, 0}, \ +{"numRepetitionsPerPreambleAttempt", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \ +{"npdcch_NumRepetitions_RA", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \ +{"npdcch_StartSF_CSS_RA", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \ +{"npdcch_Offset_RA", NULL, 0, strptr:NULL, defstrval:"zero", TYPE_STRING, 0}, \ +} + +#define NBIOT_NPRACH_PERIODICITY_IDX 0 +#define NBIOT_NPRACH_STARTTIME_IDX 1 +#define NBIOT_NPRACH_SUBCARRIEROFFSET_IDX 2 +#define NBIOT_NPRACH_NUMSUBCARRIERS_IDX 3 +#define NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX 4 +#define NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX 5 +#define NBIOT_NPDCCH_STARTSF_CSS_RA_IDX 6 +#define NBIOT_NPDCCH_OFFSET_RA_IDX 7 + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB IoT MACRLC configuration list section name */ +#define NBIOT_MACRLCLIST_CONFIG_STRING "NB-IoT_MACRLCs" + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB IoT L1 configuration list section name */ +#define NBIOT_L1LIST_CONFIG_STRING "NB-IoT_L1s" diff --git a/openair2/ENB_APP/RRC_config_tools.c b/openair2/ENB_APP/RRC_config_tools.c new file mode 100644 index 0000000000000000000000000000000000000000..17fbad1e18c542a38fe72c0b8f68f4a7078116c0 --- /dev/null +++ b/openair2/ENB_APP/RRC_config_tools.c @@ -0,0 +1,123 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +/* + RRC_config_tools.c + ------------------- + AUTHOR : Francois TABURET + COMPANY : NOKIA BellLabs France + EMAIL : francois.taburet@nokia-bell-labs.com + +*/ + +#include <string.h> +#include <inttypes.h> + +#include "log.h" +#include "log_extern.h" +#include "assertions.h" +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# if defined(ENABLE_USE_MME) +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# endif +#endif +#include "SystemInformationBlockType2.h" +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "DL-GapConfig-NB-r13.h" +#include "NPRACH-Parameters-NB-r13.h" + +static const eutra_band_t eutra_bands[] = { + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, +}; + + +int config_check_band_frequencies( int ind, + int16_t band, + uint32_t downlink_frequency, + int32_t uplink_frequency_offset, + uint32_t frame_type) +{ + int errors = 0; + + if (band > 0) { + int band_index; + + for (band_index = 0; band_index < sizeof (eutra_bands) / sizeof (eutra_bands[0]); band_index++) { + if (band == eutra_bands[band_index].band) { + uint32_t uplink_frequency = downlink_frequency + uplink_frequency_offset; + + AssertError (eutra_bands[band_index].dl_min < downlink_frequency, errors ++, + "enb %d downlink frequency %u too low (%u) for band %d!", + ind, downlink_frequency, eutra_bands[band_index].dl_min, band); + AssertError (downlink_frequency < eutra_bands[band_index].dl_max, errors ++, + "enb %d downlink frequency %u too high (%u) for band %d!", + ind, downlink_frequency, eutra_bands[band_index].dl_max, band); + + AssertError (eutra_bands[band_index].ul_min < uplink_frequency, errors ++, + "enb %d uplink frequency %u too low (%u) for band %d!", + ind, uplink_frequency, eutra_bands[band_index].ul_min, band); + AssertError (uplink_frequency < eutra_bands[band_index].ul_max, errors ++, + "enb %d uplink frequency %u too high (%u) for band %d!", + ind, uplink_frequency, eutra_bands[band_index].ul_max, band); + + AssertError (eutra_bands[band_index].frame_type == frame_type, errors ++, + "enb %d invalid frame type (%d/%d) for band %d!", + ind, eutra_bands[band_index].frame_type, frame_type, band); + } + } + } + + + return errors; +} + diff --git a/openair2/ENB_APP/RRC_config_tools.h b/openair2/ENB_APP/RRC_config_tools.h new file mode 100644 index 0000000000000000000000000000000000000000..a44da1f90c5d93a706f7a29e575cedd2989645ff --- /dev/null +++ b/openair2/ENB_APP/RRC_config_tools.h @@ -0,0 +1,50 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +/* + RRC_config_tools.h + ------------------- + AUTHOR : Francois TABURET + COMPANY : NOKIA BellLabs France + EMAIL : francois.taburet@nokia-bell-labs.com +*/ +#ifndef RRC_CONFIG_TOOLS_H_ +#define RRC_CONFIG_TOOLS_H_ + +#define KHz (1000UL) +#define MHz (1000 * KHz) + +typedef struct eutra_band_s { + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; +} eutra_band_t; + + +extern int config_check_band_frequencies(int ind, int16_t band, uint32_t downlink_frequency, + int32_t uplink_frequency_offset, uint32_t frame_type); + +extern int config_check_assign_DLGap_NB(paramdef_t *param); +extern int config_check_assign_rach_NB(paramdef_t *param); +#endif diff --git a/openair2/ENB_APP/RRC_paramsvalues.h b/openair2/ENB_APP/RRC_paramsvalues.h new file mode 100644 index 0000000000000000000000000000000000000000..06fee0e172515ed105adb6dc54fa5d808af07491 --- /dev/null +++ b/openair2/ENB_APP/RRC_paramsvalues.h @@ -0,0 +1,94 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 openair2/ENB_APP/RRC_paramsvalues.h + * \brief macro definitions for RRC authorized and asn1 parameters values, to be used in paramdef_t/chechedparam_t structure initializations + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#ifndef __RRC_PARAMSVALUES__H__ +#define __RRC_PARAMSVALUES__H__ +/* cell configuration section name */ +#define ENB_CONFIG_STRING_ENB_LIST "eNBs" +/* component carriers configuration section name */ +#define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" + +#define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" +#define ENB_CONFIG_STRING_PBCH_REPETITION "pbch_repetition" +#define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" +#define ENB_CONFIG_STRING_TDD_CONFIG_S "tdd_config_s" +#define ENB_CONFIG_STRING_PREFIX_TYPE "prefix_type" +#define ENB_CONFIG_STRING_PREFIX_TYPE_UL "prefix_type_UL" +#define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" +#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" +#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" +#define ENB_CONFIG_STRING_NID_CELL "Nid_cell" +#define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" +#define ENB_CONFIG_STRING_CELL_MBSFN "Nid_cell_mbsfn" + + +#define FRAMETYPE_OKVALUES {"FDD","TDD"} +#define FRAMETYPE_MODVALUES { FDD, TDD} + +#define TDDCFG(A) TDD_Config__subframeAssignment_ ## A +#define TDDCONFIG_OKRANGE { TDDCFG(sa0), TDDCFG(sa6)} + +#define TDDCFGS(A) TDD_Config__specialSubframePatterns_ ## A +#define TDDCONFIGS_OKRANGE { TDDCFGS(ssp0), TDDCFGS(ssp8)} + +#define PREFIX_OKVALUES {"NORMAL","EXTENDED"} +#define PREFIX_MODVALUES { NORMAL, EXTENDED} + +#define PREFIXUL_OKVALUES {"NORMAL","EXTENDED"} +#define PREFIXUL_MODVALUES { NORMAL, EXTENDED} + +#define NRBDL_OKVALUES {6,15,25,50,75,100} + +#define UETIMER_T300_OKVALUES {100,200,300,400,600,1000,1500,2000} +#define UETT300(A) UE_TimersAndConstants__t300_ ## A +#define UETIMER_T300_MODVALUES { UETT300(ms100), UETT300(ms200),UETT300(ms300),UETT300(ms400),UETT300(ms600),UETT300(ms1000),UETT300(ms1500),UETT300(ms2000)} + +#define UETIMER_T301_OKVALUES {100,200,300,400,600,1000,1500,2000} +#define UETT301(A) UE_TimersAndConstants__t301_ ## A +#define UETIMER_T301_MODVALUES { UETT301(ms100), UETT301(ms200),UETT301(ms300),UETT301(ms400),UETT301(ms600),UETT301(ms1000),UETT301(ms1500),UETT301(ms2000)} + +#define UETIMER_T310_OKVALUES {0,50,100,200,500,1000,2000} +#define UETT310(A) UE_TimersAndConstants__t310_ ## A +#define UETIMER_T310_MODVALUES { UETT310(ms0), UETT310(ms50),UETT310(ms100),UETT310(ms200),UETT310(ms500),UETT310(ms1000),UETT310(ms2000)} + +#define UETIMER_T311_OKVALUES {1000,3110,5000,10000,15000,20000,31100} +#define UETT311(A) UE_TimersAndConstants__t311_ ## A +#define UETIMER_T311_MODVALUES { UETT311(ms1000), UETT311(ms3000),UETT311(ms5000),UETT311(ms10000),UETT311(ms15000),UETT311(ms20000),UETT311(ms30000)} + +#define UETIMER_N310_OKVALUES {1,2,3,4,6,8,10,20} +#define UETN310(A) UE_TimersAndConstants__n310_ ## A +#define UETIMER_N310_MODVALUES { UETN310(n1), UETN310(n2),UETN310(n3),UETN310(n4),UETN310(n6),UETN310(n8),UETN310(n10),UETN310(n20)} + +#define UETIMER_N311_OKVALUES {1,2,3,4,5,6,8,10} +#define UETN311(A) UE_TimersAndConstants__n311_ ## A +#define UETIMER_N311_MODVALUES { UETN311(n1), UETN311(n2),UETN311(n3),UETN311(n4),UETN311(n5),UETN311(n6),UETN311(n8),UETN311(n10)} + +#endif diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index ca404ddc23cb8ef2b6eba5aee687b9d4258cdbed..b3471d2637193b5be594ede68816fecf78cb5dc6 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -46,10 +46,7 @@ # include "gtpv1u_eNB_task.h" # endif -#if defined(FLEXRAN_AGENT_SB_IF) -# include "flexran_agent.h" -#endif - +#include "openair1/PHY/INIT/phy_init.h" extern unsigned char NB_eNB_INST; #endif @@ -98,102 +95,6 @@ static void configure_rrc(uint32_t enb_id) if (RC.rrc[enb_id]) { RCconfig_RRC(msg_p,enb_id, RC.rrc[enb_id]); - /* - RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_properties->properties[enb_id]->eNB_id; - RRC_CONFIGURATION_REQ (msg_p).tac = enb_properties->properties[enb_id]->tac; - RRC_CONFIGURATION_REQ (msg_p).mcc = enb_properties->properties[enb_id]->mcc; - RRC_CONFIGURATION_REQ (msg_p).mnc = enb_properties->properties[enb_id]->mnc; - RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length; - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - RRC_CONFIGURATION_REQ (msg_p).frame_type[CC_id] = enb_properties->properties[enb_id]->frame_type[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).tdd_config[CC_id] = enb_properties->properties[enb_id]->tdd_config[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[CC_id] = enb_properties->properties[enb_id]->tdd_config_s[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).eutra_band[CC_id] = enb_properties->properties[enb_id]->eutra_band[CC_id]; - - // RACH-Config - RRC_CONFIGURATION_REQ (msg_p).rach_numberOfRA_Preambles[CC_id] = enb_properties->properties[enb_id]->rach_numberOfRA_Preambles[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[CC_id] = enb_properties->properties[enb_id]->rach_preamblesGroupAConfig[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_sizeOfRA_PreamblesGroupA[CC_id] = enb_properties->properties[enb_id]->rach_sizeOfRA_PreamblesGroupA[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[CC_id] = enb_properties->properties[enb_id]->rach_messageSizeGroupA[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[CC_id] = enb_properties->properties[enb_id]->rach_messagePowerOffsetGroupB[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep[CC_id] = enb_properties->properties[enb_id]->rach_powerRampingStep[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower[CC_id] = enb_properties->properties[enb_id]->rach_preambleInitialReceivedTargetPower[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[CC_id] = enb_properties->properties[enb_id]->rach_preambleTransMax[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize[CC_id] = enb_properties->properties[enb_id]->rach_raResponseWindowSize[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer[CC_id] = enb_properties->properties[enb_id]->rach_macContentionResolutionTimer[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_maxHARQ_Msg3Tx[CC_id] = enb_properties->properties[enb_id]->rach_maxHARQ_Msg3Tx[CC_id]; - - // BCCH-Config - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[CC_id] = enb_properties->properties[enb_id]->bcch_modificationPeriodCoeff[CC_id]; - - // PCCH-Config - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[CC_id] = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[CC_id] = enb_properties->properties[enb_id]->pcch_nB[CC_id]; - - // PRACH-Config - RRC_CONFIGURATION_REQ (msg_p).prach_root[CC_id] = enb_properties->properties[enb_id]->prach_root[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_config_index[CC_id] = enb_properties->properties[enb_id]->prach_config_index[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[CC_id] = enb_properties->properties[enb_id]->prach_high_speed[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_zero_correlation[CC_id] = enb_properties->properties[enb_id]->prach_zero_correlation[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[CC_id] = enb_properties->properties[enb_id]->prach_freq_offset[CC_id]; - - // PDSCH-Config - RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[CC_id] = enb_properties->properties[enb_id]->pdsch_referenceSignalPower[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pdsch_p_b[CC_id] = enb_properties->properties[enb_id]->pdsch_p_b[CC_id]; - - // PUSCH-Config - RRC_CONFIGURATION_REQ (msg_p).pusch_n_SB[CC_id] = enb_properties->properties[enb_id]->pusch_n_SB[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingMode[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingOffset[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingOffset[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[CC_id] = enb_properties->properties[enb_id]->pusch_enable64QAM[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_groupHoppingEnabled[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_groupAssignment[CC_id] = enb_properties->properties[enb_id]->pusch_groupAssignment[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_sequenceHoppingEnabled[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_nDMRS1[CC_id] = enb_properties->properties[enb_id]->pusch_nDMRS1[CC_id]; - - // PUCCH-Config - - RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[CC_id] = enb_properties->properties[enb_id]->pucch_delta_shift[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[CC_id] = enb_properties->properties[enb_id]->pucch_nRB_CQI[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[CC_id] = enb_properties->properties[enb_id]->pucch_nCS_AN[CC_id]; -#if !defined(Rel10) && !defined(Rel14) - RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[CC_id] = enb_properties->properties[enb_id]->pucch_n1_AN[CC_id]; -#endif - - // SRS Config - RRC_CONFIGURATION_REQ (msg_p).srs_enable[CC_id] = enb_properties->properties[enb_id]->srs_enable[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[CC_id] = enb_properties->properties[enb_id]->srs_BandwidthConfig[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_SubframeConfig[CC_id] = enb_properties->properties[enb_id]->srs_SubframeConfig[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[CC_id] = enb_properties->properties[enb_id]->srs_ackNackST[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[CC_id] = enb_properties->properties[enb_id]->srs_MaxUpPts[CC_id]; - - // uplinkPowerControlCommon - - RRC_CONFIGURATION_REQ (msg_p).pusch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pusch_p0_Nominal[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pucch_p0_Nominal[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[CC_id] = enb_properties->properties[enb_id]->pusch_alpha[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1b[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2a[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2b[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).msg3_delta_Preamble[CC_id] = enb_properties->properties[enb_id]->msg3_delta_Preamble[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ul_CyclicPrefixLength[CC_id] = enb_properties->properties[enb_id]->ul_CyclicPrefixLength[CC_id]; - - // UE Timers and Constants - - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t300[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t301[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t310[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n310[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t311[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n311[CC_id]; - - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[CC_id] = enb_properties->properties[enb_id]->ue_TransmissionMode[CC_id]; - - } - */ LOG_I(ENB_APP,"Sending configuration message to RRC task\n"); itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); @@ -224,44 +125,6 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//, s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p); LOG_I(ENB_APP,"default drx %d\n",s1ap_register_eNB->default_drx); - /* - - s1ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id; - s1ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type; - s1ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name; - s1ap_register_eNB->tac = enb_properties->properties[enb_id]->tac; - s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc; - s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc; - s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length; - s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0]; - - s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme; - - AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme, - S1AP_MAX_NB_MME_IP_ADDRESS); - - for (mme_id = 0; mme_id < s1ap_register_eNB->nb_mme; mme_id++) { - s1ap_register_eNB->mme_ip_address[mme_id].ipv4 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4; - s1ap_register_eNB->mme_ip_address[mme_id].ipv6 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6; - strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv4_address, - enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4_address, - sizeof(s1ap_register_eNB->mme_ip_address[0].ipv4_address)); - strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv6_address, - enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6_address, - sizeof(s1ap_register_eNB->mme_ip_address[0].ipv6_address)); - } - - s1ap_register_eNB->sctp_in_streams = enb_properties->properties[enb_id]->sctp_in_streams; - s1ap_register_eNB->sctp_out_streams = enb_properties->properties[enb_id]->sctp_out_streams; - - - s1ap_register_eNB->enb_ip_address.ipv6 = 0; - s1ap_register_eNB->enb_ip_address.ipv4 = 1; - addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_S1_MME; - str = inet_ntoa(addr); - strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str); - - */ LOG_I(ENB_APP,"[eNB %d] eNB_app_register for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); @@ -288,8 +151,8 @@ void *eNB_app_task(void *args_p) long enb_register_retry_timer_id; # endif uint32_t enb_id; - MessageDef *msg_p = NULL; - const char *msg_name = NULL; + MessageDef *msg_p = NULL; + const char *msg_name = NULL; instance_t instance; int result; /* for no gcc warnings */ @@ -322,16 +185,6 @@ void *eNB_app_task(void *args_p) memset((void *)RC.rrc[enb_id],0,sizeof(eNB_RRC_INST)); configure_rrc(enb_id); } - -#if defined (FLEXRAN_AGENT_SB_IF) - - for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - printf("\n start enb agent %d\n", enb_id); - flexran_agent_start(enb_id, enb_properties_p); - } -#endif - - # if defined(ENABLE_USE_MME) /* Try to register each eNB */ @@ -352,6 +205,7 @@ void *eNB_app_task(void *args_p) switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(ENB_APP, " *** Exiting ENB_APP thread\n"); itti_exit_task (); break; diff --git a/openair2/ENB_APP/enb_app.h b/openair2/ENB_APP/enb_app.h index 52f63806e8e9a27fd042b759ff12ace41f23c892..4dfea72eefbbbf6bc951f562b17f91b869e3ed4a 100644 --- a/openair2/ENB_APP/enb_app.h +++ b/openair2/ENB_APP/enb_app.h @@ -30,8 +30,12 @@ #ifndef ENB_APP_H_ #define ENB_APP_H_ +#include <stdint.h> void *eNB_app_task(void *args_p); +/* needed for flexran: start PHY and RRC when restarting */ +void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end); + #endif /* ENB_APP_H_ */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 4d37307faea8946b60b3a1f6a8272bf362f77bd2..a56db1161e69518eca0cb8ced96e6f7fdd8d9819 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -45,192 +45,231 @@ #endif #include "sctp_default_values.h" #include "SystemInformationBlockType2.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/proto.h" -#include "PHY/extern.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "PHY/phy_extern.h" +#include "PHY/INIT/phy_init.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "nfapi_vnf.h" #include "nfapi_pnf.h" -#include "enb_paramdef.h" +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" #include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "enb_paramdef.h" extern uint16_t sf_ahead; -static int enb_check_band_frequencies(char* lib_config_file_name_pP, - int ind, - int16_t band, - uint32_t downlink_frequency, - int32_t uplink_frequency_offset, - lte_frame_type_t frame_type) +void RCconfig_flexran() { - int errors = 0; - - if (band > 0) { - int band_index; - - for (band_index = 0; band_index < sizeof (eutra_bands) / sizeof (eutra_bands[0]); band_index++) { - if (band == eutra_bands[band_index].band) { - uint32_t uplink_frequency = downlink_frequency + uplink_frequency_offset; - - AssertError (eutra_bands[band_index].dl_min < downlink_frequency, errors ++, - "Failed to parse eNB configuration file %s, enb %d downlink frequency %u too low (%u) for band %d!", - lib_config_file_name_pP, ind, downlink_frequency, eutra_bands[band_index].dl_min, band); - AssertError (downlink_frequency < eutra_bands[band_index].dl_max, errors ++, - "Failed to parse eNB configuration file %s, enb %d downlink frequency %u too high (%u) for band %d!", - lib_config_file_name_pP, ind, downlink_frequency, eutra_bands[band_index].dl_max, band); - - AssertError (eutra_bands[band_index].ul_min < uplink_frequency, errors ++, - "Failed to parse eNB configuration file %s, enb %d uplink frequency %u too low (%u) for band %d!", - lib_config_file_name_pP, ind, uplink_frequency, eutra_bands[band_index].ul_min, band); - AssertError (uplink_frequency < eutra_bands[band_index].ul_max, errors ++, - "Failed to parse eNB configuration file %s, enb %d uplink frequency %u too high (%u) for band %d!", - lib_config_file_name_pP, ind, uplink_frequency, eutra_bands[band_index].ul_max, band); - - AssertError (eutra_bands[band_index].frame_type == frame_type, errors ++, - "Failed to parse eNB configuration file %s, enb %d invalid frame type (%d/%d) for band %d!", - lib_config_file_name_pP, ind, eutra_bands[band_index].frame_type, frame_type, band); - } - } - } - - - return errors; -} - - -/* --------------------------------------------------------*/ -/* from here function to use configuration module */ -void RCconfig_RU(void) { - - int j = 0; - int i = 0; - - - paramdef_t RUParams[] = RUPARAMS_DESC; - paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; - - - config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL); + uint16_t i; + uint16_t num_enbs; + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + /* this will possibly truncate the cell id (RRC assumes int32_t). + * Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for + * the bitshifting to work properly */ + int32_t Nid_cell = 0; + uint16_t Nid_cell_tr = 0; + uint32_t enb_id = 0; + + /* + * the only reason for all these variables is, that they are "hard-encoded" + * into the CCPARAMS_DESC macro and we need it for the Nid_cell variable ... + */ + char *frame_type, *prefix_type, *pbch_repetition, *prach_high_speed, + *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled, + *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource, + *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha, + *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2, + *pucch_deltaF_Format2a, *pucch_deltaF_Format2b, + *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB; + long long int downlink_frequency; + int32_t tdd_config, tdd_config_s, eutra_band, uplink_frequency_offset, + Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index, + prach_zero_correlation, prach_freq_offset, pucch_delta_shift, + pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower, + pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment, + pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal, + pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles, + rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA, + rach_powerRampingStep, rach_preambleInitialReceivedTargetPower, + rach_preambleTransMax, rach_raResponseWindowSize, + rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx, + pcch_defaultPagingCycle, bcch_modificationPeriodCoeff, + ue_TimersAndConstants_t300, ue_TimersAndConstants_t301, + ue_TimersAndConstants_t310, ue_TimersAndConstants_t311, + ue_TimersAndConstants_n310, ue_TimersAndConstants_n311, + ue_TransmissionMode; + + int32_t ue_multiple_max = 0; + + e_SL_CP_Len_r12 rxPool_sc_CP_Len; + e_SL_PeriodComm_r12 rxPool_sc_Period; + e_SL_CP_Len_r12 rxPool_data_CP_Len; + long rxPool_ResourceConfig_prb_Num; + long rxPool_ResourceConfig_prb_Start; + long rxPool_ResourceConfig_prb_End; + SL_OffsetIndicator_r12_PR rxPool_ResourceConfig_offsetIndicator_present; + long rxPool_ResourceConfig_offsetIndicator_choice; + SubframeBitmapSL_r12_PR rxPool_ResourceConfig_subframeBitmap_present; + char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + long rxPool_ResourceConfig_subframeBitmap_choice_bs_size; + long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + + //SIB19 + //for discRxPool + SL_CP_Len_r12_t discRxPool_cp_Len; + e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPool_discPeriod; + long discRxPool_numRetx; + long discRxPool_numRepetition; + long discRxPool_ResourceConfig_prb_Num; + long discRxPool_ResourceConfig_prb_Start; + long discRxPool_ResourceConfig_prb_End; + SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present; + long discRxPool_ResourceConfig_offsetIndicator_choice; + SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present; + char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; + long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + //for discRxPoolPS + SL_CP_Len_r12_t discRxPoolPS_cp_Len; + e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPoolPS_discPeriod; + long discRxPoolPS_numRetx; + long discRxPoolPS_numRepetition; + long discRxPoolPS_ResourceConfig_prb_Num; + long discRxPoolPS_ResourceConfig_prb_Start; + long discRxPoolPS_ResourceConfig_prb_End; + SL_OffsetIndicator_r12_PR discRxPoolPS_ResourceConfig_offsetIndicator_present; + long discRxPoolPS_ResourceConfig_offsetIndicator_choice; + SubframeBitmapSL_r12_PR discRxPoolPS_ResourceConfig_subframeBitmap_present; + char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; + long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; + long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + + + + /* get number of eNBs */ + paramdef_t ENBSParams[] = ENBSPARAMS_DESC; + config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL); + num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; - - if ( RUParamList.numelt > 0) { + /* for eNB ID */ + paramdef_t ENBParams[] = ENBPARAMS_DESC; + paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0}; - RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*)); - + /* for Nid_cell */ + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; + paramdef_t CCsParams[] = CCPARAMS_DESC; + paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) { + CCsParams[I].chkPptr = &(config_check_CCparams[I]); + } + paramdef_t flexranParams[] = FLEXRANPARAMS_DESC; + config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); + if (!RC.flexran) { + RC.flexran = calloc(num_enbs, sizeof(flexran_agent_info_t*)); + AssertFatal(RC.flexran, + "can't ALLOCATE %zu Bytes for %d flexran agent info with size %zu\n", + num_enbs * sizeof(flexran_agent_info_t*), + num_enbs, sizeof(flexran_agent_info_t*)); + } - RC.ru_mask=(1<<NB_RU) - 1; - printf("Set RU mask to %lx\n",RC.ru_mask); + for (i = 0; i < num_enbs; i++) { + RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t)); + AssertFatal(RC.flexran[i], + "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n", + sizeof(flexran_agent_info_t), i + 1, num_enbs); + /* if config says "yes", enable Agent, in all other cases it's like "no" */ + RC.flexran[i]->enabled = strcasecmp(*(flexranParams[FLEXRAN_ENABLED].strptr), "yes") == 0; + /* if not enabled, simply skip the rest, it is not needed anyway */ + if (!RC.flexran[i]->enabled) + continue; + RC.flexran[i]->interface_name = strdup(*(flexranParams[FLEXRAN_INTERFACE_NAME_IDX].strptr)); + //inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN); + RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr)); + RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); + RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); + RC.flexran[i]->node_ctrl_state = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION; + + config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t),NULL); + /* eNB ID from configuration, as read in by RCconfig_RRC() */ + if (!ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr) { + // Calculate a default eNB ID +# if defined(ENABLE_USE_MME) + enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8); +# else + enb_id = i; +# endif + } else { + enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); + } - for (j = 0; j < RC.nb_RU; j++) { + /* cell ID */ + sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i); + config_getlist(&CCsParamList, NULL, 0, aprefix); + if (CCsParamList.numelt > 0) { + sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0); + config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + Nid_cell_tr = (uint16_t) Nid_cell; + } - RC.ru[j] = (RU_t*)malloc(sizeof(RU_t)); - memset((void*)RC.ru[j],0,sizeof(RU_t)); - RC.ru[j]->idx = j; + RC.flexran[i]->mod_id = i; + RC.flexran[i]->agent_id = (((uint64_t)i) << 48) | (((uint64_t)enb_id) << 16) | ((uint64_t)Nid_cell_tr); - printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]); + /* assume for the moment the monolithic case, i.e. agent can provide + * information for all layers */ + RC.flexran[i]->capability_mask = FLEXRAN_CAP_LOPHY | FLEXRAN_CAP_HIPHY + | FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC + | FLEXRAN_CAP_RLC | FLEXRAN_CAP_PDCP + | FLEXRAN_CAP_SDAP | FLEXRAN_CAP_RRC; + } +} - RC.ru[j]->if_timing = synch_to_ext_device; - if (RC.nb_L1_inst >0) - RC.ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; - else - RC.ru[j]->num_eNB = 0; - for (i=0;i<RC.ru[j]->num_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; +/*void UE_config_stub_pnf(void) { + int j; + paramdef_t L1_Params[] = L1PARAMS_DESC; + paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0}; - if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = eNodeB_3GPP; - printf("Setting function for RU %d to eNodeB_3GPP\n",j); - } - else { - RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); - - if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); + config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); + if (L1_ParamList.numelt > 0) { + for (j=0; j<L1_ParamList.numelt; j++){ + //nb_L1_CC = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); // Number of component carriers is of no use for the + // phy_stub mode UE pnf. Maybe we can completely skip it. + + if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { + sf_ahead = 4; // Need 4 subframe gap between RX and TX + } + // Panos: Right now that we have only one UE (thread) it is ok to put the eth_params in the UE_mac_inst. + // Later I think we have to change that to attribute eth_params to a global element for all the UEs. + else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { + stub_eth_params.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + stub_eth_params.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + stub_eth_params.remote_addr = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + stub_eth_params.my_portc = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + stub_eth_params.remote_portc = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + stub_eth_params.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + stub_eth_params.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + stub_eth_params.transp_preference = ETH_UDP_MODE; + + + sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 + //configure_nfapi_pnf(UE_mac_inst[0].eth_params_n.remote_addr, UE_mac_inst[0].eth_params_n.remote_portc, UE_mac_inst[0].eth_params_n.my_addr, UE_mac_inst[0].eth_params_n.my_portd, UE_mac_inst[0].eth_params_n.remote_portd); + configure_nfapi_pnf(stub_eth_params.remote_addr, stub_eth_params.remote_portc, stub_eth_params.my_addr, stub_eth_params.my_portd, stub_eth_params.remote_portd); + } + else { // other midhaul + } } - } - RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; - RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); - RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; - RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); - RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); - for (i=0;i<RC.ru[j]->num_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; - } //strcmp(local_rf, "yes") == 0 - else { - printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); - - RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); - if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->if_timing = synch_to_other; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS; - } - RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); - RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); - } /* strcmp(local_rf, "yes") != 0 */ + } + else { - RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); - RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); - - }// j=0..num_rus - } else { - RC.nb_RU = 0; - } // setting != NULL + } +}*/ - return; - -} void RCconfig_L1(void) { int i,j; @@ -247,7 +286,6 @@ void RCconfig_L1(void) { config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); if (L1_ParamList.numelt > 0) { - for (j = 0; j < RC.nb_L1_inst; j++) { RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); @@ -300,6 +338,7 @@ void RCconfig_L1(void) { configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n .remote_portd); } else { // other midhaul + //printf("Panos-D: RCconfig_L1 12 \n"); } }// j=0..num_inst printf("Initializing northbound interface for L1\n"); @@ -346,7 +385,12 @@ void RCconfig_macrlc() { RC.nb_macrlc_inst=MacRLC_ParamList.numelt; mac_top_init_eNB(); + RC.nb_mac_CC = (int*)malloc(RC.nb_macrlc_inst*sizeof(int)); + for (j=0;j<RC.nb_macrlc_inst;j++) { + RC.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr); + //RC.mac[j]->phy_test = *(MacRLC_ParamList.paramarray[j][MACRLC_PHY_TEST_IDX].iptr); + //printf("PHY_TEST = %d,%d\n", RC.mac[j]->phy_test, j); if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { // check number of instances is same as RRC/PDCP @@ -435,7 +479,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int32_t pucch_delta_shift = 0; int32_t pucch_nRB_CQI = 0; int32_t pucch_nCS_AN = 0; -//#if !defined(Rel10) && !defined(Rel14) +//#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int32_t pucch_n1_AN = 0; //#endif int32_t pdsch_referenceSignalPower = 0; @@ -490,6 +534,52 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int32_t ue_multiple_max = 0; + //TTN - for D2D + //SIB18 + const char* rxPool_sc_CP_Len = NULL; + const char* rxPool_sc_Period = NULL; + const char* rxPool_data_CP_Len = NULL; + libconfig_int rxPool_ResourceConfig_prb_Num = 0; + libconfig_int rxPool_ResourceConfig_prb_Start = 0; + libconfig_int rxPool_ResourceConfig_prb_End = 0; + const char* rxPool_ResourceConfig_offsetIndicator_present = NULL; + libconfig_int rxPool_ResourceConfig_offsetIndicator_choice = 0; + const char* rxPool_ResourceConfig_subframeBitmap_present = NULL; + char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + //SIB19 + //For discRxPool + const char* discRxPool_cp_Len = NULL; + const char* discRxPool_discPeriod = NULL; + libconfig_int discRxPool_numRetx = 0; + libconfig_int discRxPool_numRepetition = 0; + + libconfig_int discRxPool_ResourceConfig_prb_Num = 0; + libconfig_int discRxPool_ResourceConfig_prb_Start = 0; + libconfig_int discRxPool_ResourceConfig_prb_End = 0; + const char* discRxPool_ResourceConfig_offsetIndicator_present = NULL; + libconfig_int discRxPool_ResourceConfig_offsetIndicator_choice = 0; + const char* discRxPool_ResourceConfig_subframeBitmap_present = NULL; + char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + //For discRxPoolPS + const char* discRxPoolPS_cp_Len = NULL; + const char* discRxPoolPS_discPeriod = NULL; + libconfig_int discRxPoolPS_numRetx = 0; + libconfig_int discRxPoolPS_numRepetition = 0; + + libconfig_int discRxPoolPS_ResourceConfig_prb_Num = 0; + libconfig_int discRxPoolPS_ResourceConfig_prb_Start = 0; + libconfig_int discRxPoolPS_ResourceConfig_prb_End = 0; + const char* discRxPoolPS_ResourceConfig_offsetIndicator_present = NULL; + libconfig_int discRxPoolPS_ResourceConfig_offsetIndicator_choice = 0; + const char* discRxPoolPS_ResourceConfig_subframeBitmap_present = NULL; + char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size = 0; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + int32_t srb1_timer_poll_retransmit = 0; int32_t srb1_timer_reordering = 0; int32_t srb1_timer_status_prohibit = 0; @@ -502,10 +592,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { /* - char* flexran_agent_interface_name = NULL; - char* flexran_agent_ipv4_address = NULL; - int32_t flexran_agent_port = 0; - char* flexran_agent_cache = NULL; int32_t otg_ue_id = 0; char* otg_app_type = NULL; char* otg_bg_traffic = NULL; @@ -536,14 +622,16 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { paramdef_t ENBParams[] = ENBPARAMS_DESC; paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; paramdef_t CCsParams[] = CCPARAMS_DESC; paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0}; paramdef_t SRB1Params[] = SRB1PARAMS_DESC; - - - +/* map parameter checking array instances to parameter definition array instances */ + for (int I=0; I< ( sizeof(CCsParams)/ sizeof(paramdef_t) ) ; I++) { + CCsParams[I].chkPptr = &(config_check_CCparams[I]); + } /* get global parameters, defined outside any section in the config file */ config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); @@ -670,6 +758,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { for (j = 0; j < CCsParamList.numelt ;j++) { sprintf(ccspath,"%s.%s.[%i]",enbpath,ENB_CONFIG_STRING_COMPONENT_CARRIERS,j); + LOG_I(RRC, "enb_config::RCconfig_RRC() parameter number: %d, total number of parameters: %zd, ccspath: %s \n \n", j, sizeof(CCsParams)/sizeof(paramdef_t), ccspath); config_get( CCsParams,sizeof(CCsParams)/sizeof(paramdef_t),ccspath); @@ -678,43 +767,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { nb_cc++; - /* - if (strcmp(cc_node_function, "eNodeB_3GPP") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP; - } else if (strcmp(cc_node_function, "eNodeB_3GPP_BBU") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP_BBU; - } else if (strcmp(cc_node_function, "NGFI_RCC_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RCC_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RAU_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RAU_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RRU_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RRU_IF5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF5; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: eNodeB_3GPP or eNodeB_3GPP_BBU or NGFI_IF4_RCC or NGFI_IF4_RRU or NGFI_IF5_RRU !\n", - lib_config_file_name_pP, i, cc_node_function); - } - - if (strcmp(cc_node_timing, "synch_to_ext_device") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_ext_device; - } else if (strcmp(cc_node_timing, "synch_to_other") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_other; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: SYNCH_TO_DEVICE or SYNCH_TO_OTHER !\n", - lib_config_file_name_pP, i, cc_node_timing); - } - - if ((cc_node_synch_ref >= -1) && (cc_node_synch_ref < num_component_carriers)) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_synch_ref[j] = (int16_t) cc_node_synch_ref; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for node_synch_ref choice: valid CC_id or -1 !\n", - lib_config_file_name_pP, i, cc_node_synch_ref); - } - */ + RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; @@ -740,7 +793,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", RC.config_file_name, i, prefix_type); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (!pbch_repetition) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", @@ -826,8 +879,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset; - if (enb_check_band_frequencies(RC.config_file_name, - j, + if (config_check_band_frequencies(j, RRC_CONFIGURATION_REQ (msg_p).eutra_band[j], RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j], RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j], @@ -904,7 +956,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", RC.config_file_name, i, pucch_nCS_AN); -//#if !defined(Rel10) && !defined(Rel14) +//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[j] = pucch_n1_AN; if ((pucch_n1_AN <0) || (pucch_n1_AN > 2047)) @@ -1084,7 +1136,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", RC.config_file_name, i, pusch_p0_Nominal); -#ifndef Rel14 +#if (RRC_VERSION <= MAKE_VERSION(12, 0, 0)) if (strcmp(pusch_alpha,"AL0")==0) { RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al0; } else if (strcmp(pusch_alpha,"AL04")==0) { @@ -1102,7 +1154,9 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { } else if (strcmp(pusch_alpha,"AL1")==0) { RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al1; } -#else +#endif + +#if (RRC_VERSION >= MAKE_VERSION(12, 0, 0)) if (strcmp(pusch_alpha,"AL0")==0) { RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al0; } else if (strcmp(pusch_alpha,"AL04")==0) { @@ -1305,7 +1359,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (rach_preambleTransMax) { -#ifndef Rel14 +#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) case 3: RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; break; @@ -1499,244 +1553,13 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { break; } - - switch (ue_TimersAndConstants_t300) { - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms200; - break; - - case 300: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms300; - break; - - case 400: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms400; - break; - - case 600: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms600; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms1000; - break; - - case 1500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms1500; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t300 choice: 100,200,300,400,600,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t300); - break; - - } - - switch (ue_TimersAndConstants_t301) { - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms200; - break; - - case 300: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms300; - break; - - case 400: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms400; - break; - - case 600: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms600; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms1000; - break; - - case 1500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms1500; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t301 choice: 100,200,300,400,600,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t301); - break; - - } - - switch (ue_TimersAndConstants_t310) { - case 0: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms0; - break; - - case 50: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms50; - break; - - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms200; - break; - - case 500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms500; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms1000; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t310 choice: 0,50,100,200,500,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t310); - break; - - } - - switch (ue_TimersAndConstants_t311) { - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms1000; - break; - - case 3110: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms3000; - break; - - case 5000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms5000; - break; - - case 10000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms10000; - break; - - case 15000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms15000; - break; - - case 20000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms20000; - break; - - case 31100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms30000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t311 choice: 1000,3000,5000,10000,150000,20000,30000", - RC.config_file_name, i, ue_TimersAndConstants_t311); - break; - - } - - switch (ue_TimersAndConstants_n310) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n1; - break; - - case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n2; - break; - - case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n3; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n4; - break; - - case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n6; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n8; - break; - - case 10: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n10; - break; - - case 20: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n20; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_n310 choice: 1,2,3,4,6,6,8,10,20", - RC.config_file_name, i, ue_TimersAndConstants_n311); - break; - - } - - switch (ue_TimersAndConstants_n311) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n1; - break; - - case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n2; - break; - - case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n3; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n4; - break; - - case 5: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n5; - break; - - case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n6; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n8; - break; - - case 10: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n10; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t311 choice: 1,2,3,4,5,6,8,10", - RC.config_file_name, i, ue_TimersAndConstants_t311); - break; - - } + + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = ue_TimersAndConstants_t300; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = ue_TimersAndConstants_t301; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = ue_TimersAndConstants_t310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = ue_TimersAndConstants_t311; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = ue_TimersAndConstants_n310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = ue_TimersAndConstants_n311; switch (ue_TransmissionMode) { case 1: @@ -1794,6 +1617,267 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RC.config_file_name, i, N_RB_DL); break; } + + //TTN - for D2D + //SIB18 + if (strcmp(rxPool_sc_CP_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(rxPool_sc_CP_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_CP_Len choice: normal,extended!\n", + RC.config_file_name, i, rxPool_sc_CP_Len); + + if (strcmp(rxPool_sc_Period,"sf40")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf40; + } else if (strcmp(rxPool_sc_Period,"sf60")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf60; + } else if (strcmp(rxPool_sc_Period,"sf70")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf70; + } else if (strcmp(rxPool_sc_Period,"sf80")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf80; + } else if (strcmp(rxPool_sc_Period,"sf120")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf120; + } else if (strcmp(rxPool_sc_Period,"sf140")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf140; + } else if (strcmp(rxPool_sc_Period,"sf160")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf160; + } else if (strcmp(rxPool_sc_Period,"sf240")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf240; + } else if (strcmp(rxPool_sc_Period,"sf280")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf280; + } else if (strcmp(rxPool_sc_Period,"sf320")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf320; + } else if (strcmp(rxPool_sc_Period,"spare6")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare6; + } else if (strcmp(rxPool_sc_Period,"spare5")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare5; + } else if (strcmp(rxPool_sc_Period,"spare4")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare4; + } else if (strcmp(rxPool_sc_Period,"spare3")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare3; + } else if (strcmp(rxPool_sc_Period,"spare2")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare2; + } else if (strcmp(rxPool_sc_Period,"spare")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_Period choice: sf40,sf60,sf70,sf80,sf120,sf140,sf160,sf240,sf280,sf320,spare6,spare5,spare4,spare3,spare2,spare!\n", + RC.config_file_name, i, rxPool_sc_Period); + + if (strcmp(rxPool_data_CP_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(rxPool_data_CP_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_data_CP_Len choice: normal,extended!\n", + RC.config_file_name, i, rxPool_data_CP_Len); + + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Num[j] = rxPool_ResourceConfig_prb_Num; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Start[j] = rxPool_ResourceConfig_prb_Start; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_End[j] = rxPool_ResourceConfig_prb_End; + + if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", + RC.config_file_name, i, rxPool_ResourceConfig_offsetIndicator_present); + + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_choice[j] = rxPool_ResourceConfig_offsetIndicator_choice; + + if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", + RC.config_file_name, i, rxPool_ResourceConfig_subframeBitmap_present); + + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_size[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_size; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + + //SIB19 - for discRxPool + if (strcmp(discRxPool_cp_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(discRxPool_cp_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_cp_Len choice: normal,extended!\n", + RC.config_file_name, i, discRxPool_cp_Len); + + + if (strcmp(discRxPool_discPeriod,"rf32")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; + } else if (strcmp(discRxPool_discPeriod,"rf64")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; + } else if (strcmp(discRxPool_discPeriod,"rf128")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; + } else if (strcmp(discRxPool_discPeriod,"rf256")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; + } else if (strcmp(discRxPool_discPeriod,"rf512")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; + } else if (strcmp(discRxPool_discPeriod,"rf1024")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; + } else if (strcmp(discRxPool_discPeriod,"rf16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; + } else if (strcmp(discRxPool_discPeriod,"spare")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", + RC.config_file_name, i, discRxPool_discPeriod); + + + + RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRetx[j] = discRxPool_numRetx; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRepetition[j] = discRxPool_numRepetition; + + + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Num[j] = discRxPool_ResourceConfig_prb_Num; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Start[j] = discRxPool_ResourceConfig_prb_Start; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_End[j] = discRxPool_ResourceConfig_prb_End; + + if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", + RC.config_file_name, i, discRxPool_ResourceConfig_offsetIndicator_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_choice[j] = discRxPool_ResourceConfig_offsetIndicator_choice; + + if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", + RC.config_file_name, i, discRxPool_ResourceConfig_subframeBitmap_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + + //SIB19 - For discRxPoolPS + if (strcmp(discRxPoolPS_cp_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(discRxPoolPS_cp_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_cp_Len choice: normal,extended!\n", + RC.config_file_name, i, discRxPoolPS_cp_Len); + + + if (strcmp(discRxPoolPS_discPeriod,"rf32")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; + } else if (strcmp(discRxPoolPS_discPeriod,"rf64")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; + } else if (strcmp(discRxPoolPS_discPeriod,"rf128")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; + } else if (strcmp(discRxPoolPS_discPeriod,"rf256")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; + } else if (strcmp(discRxPoolPS_discPeriod,"rf512")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; + } else if (strcmp(discRxPoolPS_discPeriod,"rf1024")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; + } else if (strcmp(discRxPoolPS_discPeriod,"rf16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; + } else if (strcmp(discRxPoolPS_discPeriod,"spare")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", + RC.config_file_name, i, discRxPoolPS_discPeriod); + + + + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRetx[j] = discRxPoolPS_numRetx; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRepetition[j] = discRxPoolPS_numRepetition; + + + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Num[j] = discRxPoolPS_ResourceConfig_prb_Num; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Start[j] = discRxPoolPS_ResourceConfig_prb_Start; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_End[j] = discRxPoolPS_ResourceConfig_prb_End; + + if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prSmall")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prLarge")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", + RC.config_file_name, i, discRxPoolPS_ResourceConfig_offsetIndicator_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_choice[j] = discRxPoolPS_ResourceConfig_offsetIndicator_choice; + + if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs4")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs8")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs12")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs30")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs40")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs42")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", + RC.config_file_name, i, discRxPoolPS_ResourceConfig_subframeBitmap_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + + } } char srb1path[MAX_OPTNAME_SIZE*2 + 8]; @@ -2105,6 +2189,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { rrc->srb1_poll_byte = PollByte_kBinfinity; rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; } + /* // Network Controller subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); @@ -2133,279 +2218,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache); } } - */ - - /* - // OTG _CONFIG - setting_otg = config_setting_get_member (setting_enb, ENB_CONF_STRING_OTG_CONFIG); - - if (setting_otg != NULL) { - num_otg_elements = config_setting_length(setting_otg); - printf("num otg elements %d \n", num_otg_elements); - enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements = 0; - - for (j = 0; j < num_otg_elements; j++) { - subsetting_otg=config_setting_get_elem(setting_otg, j); - - if (config_setting_lookup_int(subsetting_otg, ENB_CONF_STRING_OTG_UE_ID, &otg_ue_id)) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = otg_ue_id; - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = 1; - } - - if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_APP_TYPE, (const char **)&otg_app_type)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = map_str_to_int(otg_app_type_names,otg_app_type))== -1) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = BCBR; - } - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = NO_PREDEFINED_TRAFFIC; // 0 - } - - if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_BG_TRAFFIC, (const char **)&otg_bg_traffic)) { - - if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = map_str_to_int(switch_names,otg_bg_traffic)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j]=0; - } - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = 0; - printf("otg bg %s\n", otg_bg_traffic); - } - - enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements+=1; - - } - } - - // log_config - subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_LOG_CONFIG); - - if (subsetting != NULL) { - // global - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL, (const char **) &glog_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_level = map_str_to_int(log_level_names, glog_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; - } - - //printf( "\tGlobal log level :\t%s->%d\n",glog_level, enb_properties_loc.properties[enb_properties_loc_index]->glog_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY,(const char **) &glog_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = map_str_to_int(log_verbosity_names, glog_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - } - - //printf( "\tGlobal log verbosity:\t%s->%d\n",glog_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - } - - // HW - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_LEVEL, (const char **) &hw_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = map_str_to_int(log_level_names,hw_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - } - - //printf( "\tHW log level :\t%s->%d\n",hw_log_level,enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_VERBOSITY, (const char **) &hw_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = map_str_to_int(log_verbosity_names,hw_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - } - - //printf( "\tHW log verbosity:\t%s->%d\n",hw_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - } - - // phy - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_LEVEL,(const char **) &phy_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = map_str_to_int(log_level_names,phy_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - } - - //printf( "\tPHY log level :\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_VERBOSITY, (const char **)&phy_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = map_str_to_int(log_verbosity_names,phy_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - } - - //printf( "\tPHY log verbosity:\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - } - - //mac - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_LEVEL, (const char **)&mac_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = map_str_to_int(log_level_names,mac_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - } - - //printf( "\tMAC log level :\t%s->%d\n",mac_log_level,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_VERBOSITY, (const char **)&mac_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = map_str_to_int(log_verbosity_names,mac_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - } - - //printf( "\tMAC log verbosity:\t%s->%d\n",mac_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - } - - //rlc - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_LEVEL, (const char **)&rlc_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = map_str_to_int(log_level_names,rlc_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - } - - //printf( "\tRLC log level :\t%s->%d\n",rlc_log_level, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_VERBOSITY, (const char **)&rlc_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = map_str_to_int(log_verbosity_names,rlc_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - } - - //printf( "\tRLC log verbosity:\t%s->%d\n",rlc_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - } - - //pdcp - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_LEVEL, (const char **)&pdcp_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = map_str_to_int(log_level_names,pdcp_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - } - - //printf( "\tPDCP log level :\t%s->%d\n",pdcp_log_level, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY, (const char **)&pdcp_log_verbosity)) { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = map_str_to_int(log_verbosity_names,pdcp_log_verbosity); - //printf( "\tPDCP log verbosity:\t%s->%d\n",pdcp_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED; - } - - //rrc - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_LEVEL, (const char **)&rrc_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = map_str_to_int(log_level_names,rrc_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - } - - //printf( "\tRRC log level :\t%s->%d\n",rrc_log_level,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_VERBOSITY, (const char **)&rrc_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = map_str_to_int(log_verbosity_names,rrc_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - } - - //printf( "\tRRC log verbosity:\t%s->%d\n",rrc_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_LEVEL, (const char **)>pu_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = map_str_to_int(log_level_names,gtpu_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - } - - //printf( "\tGTPU log level :\t%s->%d\n",gtpu_log_level,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY, (const char **)>pu_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = map_str_to_int(log_verbosity_names,gtpu_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - } - - //printf( "\tGTPU log verbosity:\t%s->%d\n",gtpu_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_LEVEL, (const char **)&udp_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = map_str_to_int(log_level_names,udp_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - } - - //printf( "\tUDP log level :\t%s->%d\n",udp_log_level,enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_VERBOSITY, (const char **)&udp_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = map_str_to_int(log_verbosity_names,udp_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - } - - //printf( "\tUDP log verbosity:\t%s->%d\n",udp_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_LEVEL, (const char **)&osa_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = map_str_to_int(log_level_names,osa_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - } - - //printf( "\tOSA log level :\t%s->%d\n",osa_log_level,enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_VERBOSITY, (const char **)&osa_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = map_str_to_int(log_verbosity_names,osa_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; - } - - //printf( "\tOSA log verbosity:\t%s->%d\n",osa_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gosa_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; - } - - } else { // not configuration is given - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; - } */ break; } diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 0406e11e4cd04608df0b494596595ee4af89314c..aeac43ee1c7d9e52f80364dc3c7ddf544b257ec8 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -38,7 +38,7 @@ #include "platform_types.h" #include "platform_constants.h" #include "PHY/impl_defs_lte.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" #include "s1ap_messages_types.h" #ifdef CMAKER #include "SystemInformationBlockType2.h" @@ -47,7 +47,7 @@ #include "RRC/LITE/MESSAGES/SystemInformationBlockType2.h" #endif #include "intertask_interface_types.h" -#include "RRC/LITE/defs.h" +#include "RRC/LTE/rrc_defs.h" #define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ struct in_addr inp;\ @@ -94,8 +94,10 @@ typedef struct ru_config_s { } ru_config_t; extern void RCconfig_RU(void); +extern void RCconfig_flexran(void); extern void RCconfig_L1(void); extern void RCconfig_macrlc(void); +extern void UE_config_stub_pnf(void); extern int RCconfig_gtpu(void ); extern void RCConfig(void); diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index a9441dc24508f7ba45f22a67aa440a4abd27571c..89343f6f4bb936561b6ad96e93af455adab4446c 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -31,12 +31,7 @@ */ #include "common/config/config_paramdesc.h" - - - - - - +#include "RRC_paramsvalues.h" @@ -56,52 +51,6 @@ -#define KHz (1000UL) -#define MHz (1000 * KHz) - -typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; -} eutra_band_t; - -static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, -}; - - @@ -152,7 +101,7 @@ typedef enum { #define CONFIG_STRING_RU_MAX_RS_EPRE "max_pdschReferenceSignalPower" #define CONFIG_STRING_RU_MAX_RXGAIN "max_rxgain" #define CONFIG_STRING_RU_IF_COMPRESSION "if_compression" - +#define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -171,14 +120,10 @@ typedef enum { #define RU_ENB_LIST_IDX 14 #define RU_ATT_TX_IDX 15 #define RU_ATT_RX_IDX 16 +#define RU_NBIOTRRC_LIST_IDX 17 - -static int DEFBANDS[] = {7}; -static int DEFENBS[] = {0}; - - /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -200,7 +145,8 @@ static int DEFENBS[] = {0}; {CONFIG_STRING_RU_BAND_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFBANDS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ENB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0} \ +{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -237,8 +183,7 @@ static int DEFENBS[] = {0}; /*------------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------*/ -/* cell configuration section name */ -#define ENB_CONFIG_STRING_ENB_LIST "eNBs" + /* cell configuration parameters names */ #define ENB_CONFIG_STRING_ENB_ID "eNB_ID" @@ -293,21 +238,9 @@ static int DEFENBS[] = {0}; /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* component carriers configuration section name */ -#define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" /* component carries configuration parameters name */ -#define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" -#define ENB_CONFIG_STRING_PBCH_REPETITION "pbch_repetition" -#define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" -#define ENB_CONFIG_STRING_TDD_CONFIG_S "tdd_config_s" -#define ENB_CONFIG_STRING_PREFIX_TYPE "prefix_type" -#define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" -#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" -#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" -#define ENB_CONFIG_STRING_NID_CELL "Nid_cell" -#define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" -#define ENB_CONFIG_STRING_CELL_MBSFN "Nid_cell_mbsfn" + #define ENB_CONFIG_STRING_NB_ANT_PORTS "nb_antenna_ports" #define ENB_CONFIG_STRING_NB_ANT_TX "nb_antennas_tx" #define ENB_CONFIG_STRING_NB_ANT_RX "nb_antennas_rx" @@ -321,7 +254,7 @@ static int DEFENBS[] = {0}; #define ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT "pucch_delta_shift" #define ENB_CONFIG_STRING_PUCCH_NRB_CQI "pucch_nRB_CQI" #define ENB_CONFIG_STRING_PUCCH_NCS_AN "pucch_nCS_AN" -//#if !defined(Rel10) && !defined(Rel14) +//#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #define ENB_CONFIG_STRING_PUCCH_N1_AN "pucch_n1_AN" //#endif #define ENB_CONFIG_STRING_PDSCH_RS_EPRE "pdsch_referenceSignalPower" @@ -372,11 +305,171 @@ static int DEFENBS[] = {0}; #define ENB_CONFIG_STRING_UETIMERS_N311 "ue_TimersAndConstants_n311" #define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE "ue_TransmissionMode" #define ENB_CONFIG_STRING_UE_MULTIPLE_MAX "ue_multiple_max" - + +//TTN - for D2D +//SIB18 +#define ENB_CONFIG_STRING_RXPOOL_SC_CP_LEN "rxPool_sc_CP_Len" +#define ENB_CONFIG_STRING_RXPOOL_SC_PRIOD "rxPool_sc_Period" +#define ENB_CONFIG_STRING_RXPOOL_DATA_CP_LEN "rxPool_data_CP_Len" +#define ENB_CONFIG_STRING_RXPOOL_RC_PRB_NUM "rxPool_ResourceConfig_prb_Num" +#define ENB_CONFIG_STRING_RXPOOL_RC_PRB_START "rxPool_ResourceConfig_prb_Start" +#define ENB_CONFIG_STRING_RXPOOL_RC_PRB_END "rxPool_ResourceConfig_prb_End" +#define ENB_CONFIG_STRING_RXPOOL_RC_OFFSETIND_PRESENT "rxPool_ResourceConfig_offsetIndicator_present" +#define ENB_CONFIG_STRING_RXPOOL_RC_OFFSETIND_CHOICE "rxPool_ResourceConfig_offsetIndicator_choice" +#define ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_PRESENT "rxPool_ResourceConfig_subframeBitmap_present" +#define ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_CHOICE_BS_BUF "rxPool_ResourceConfig_subframeBitmap_choice_bs_buf" +#define ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_CHOICE_BS_SIZE "rxPool_ResourceConfig_subframeBitmap_choice_bs_size" +#define ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED "rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused" +//SIB19 for DiscRxPool +#define ENB_CONFIG_STRING_DISCRXPOOL_CP_LEN "discRxPool_cp_Len" +#define ENB_CONFIG_STRING_DISCRXPOOL_DISCPERIOD "discRxPool_discPeriod" +#define ENB_CONFIG_STRING_DISCRXPOOL_NUMRETX "discRxPool_numRetx" +#define ENB_CONFIG_STRING_DISCRXPOOL_NUMREPETITION "discRxPool_numRepetition" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_PRB_NUM "discRxPool_ResourceConfig_prb_Num" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_PRB_START "discRxPool_ResourceConfig_prb_Start" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_PRB_END "discRxPool_ResourceConfig_prb_End" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_OFFSETIND_PRESENT "discRxPool_ResourceConfig_offsetIndicator_present" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_OFFSETIND_CHOICE "discRxPool_ResourceConfig_offsetIndicator_choice" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_PRESENT "discRxPool_ResourceConfig_subframeBitmap_present" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_CHOICE_BS_BUF "discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_CHOICE_BS_SIZE "discRxPool_ResourceConfig_subframeBitmap_choice_bs_size" +#define ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED "discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused" + +//SIB19 for DiscRxPoolPS +#define ENB_CONFIG_STRING_DISCRXPOOLPS_CP_LEN "DISCRXPOOLPS_cp_Len" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_DISCPERIOD "DISCRXPOOLPS_discPeriod" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_NUMRETX "DISCRXPOOLPS_numRetx" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_NUMREPETITION "DISCRXPOOLPS_numRepetition" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_PRB_NUM "DISCRXPOOLPS_ResourceConfig_prb_Num" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_PRB_START "DISCRXPOOLPS_ResourceConfig_prb_Start" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_PRB_END "DISCRXPOOLPS_ResourceConfig_prb_End" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_OFFSETIND_PRESENT "DISCRXPOOLPS_ResourceConfig_offsetIndicator_present" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_OFFSETIND_CHOICE "DISCRXPOOLPS_ResourceConfig_offsetIndicator_choice" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_PRESENT "DISCRXPOOLPS_ResourceConfig_subframeBitmap_present" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_BUF "DISCRXPOOLPS_ResourceConfig_subframeBitmap_choice_bs_buf" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_SIZE "DISCRXPOOLPS_ResourceConfig_subframeBitmap_choice_bs_size" +#define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED "DISCRXPOOLPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused" + /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* component carriers configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* init for checkedparam_t structure */ + +#define CCPARAMS_CHECK { \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ +} +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* component carriers configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + #define CCPARAMS_DESC { \ {ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&frame_type, defstrval:"FDD", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&tdd_config, defintval:3, TYPE_UINT, 0}, \ @@ -446,9 +539,116 @@ static int DEFENBS[] = {0}; {ENB_CONFIG_STRING_UETIMERS_N310, NULL, 0, iptr:&ue_TimersAndConstants_n310, defintval:20, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UETIMERS_N311, NULL, 0, iptr:&ue_TimersAndConstants_n311, defintval:1, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ue_TransmissionMode, defintval:1, TYPE_UINT, 0}, \ -{ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ue_multiple_max, defintval:4, TYPE_UINT, 0} \ +{ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ue_multiple_max, defintval:4, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_SC_CP_LEN, NULL, 0, strptr:(char **)&rxPool_sc_CP_Len, defstrval:"normal", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_SC_PRIOD, NULL, 0, strptr:(char **)&rxPool_sc_Period, defstrval:"sf40", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_DATA_CP_LEN, NULL, 0, strptr:(char **)&rxPool_data_CP_Len, defstrval:"normal", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_PRB_NUM, NULL, 0, iptr:(int32_t *)&rxPool_ResourceConfig_prb_Num, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_PRB_START, NULL, 0, iptr:(int32_t *)&rxPool_ResourceConfig_prb_Start, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_PRB_END, NULL, 0, iptr:(int32_t *)&rxPool_ResourceConfig_prb_End, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_OFFSETIND_PRESENT, NULL, 0, strptr:(char **)&rxPool_ResourceConfig_offsetIndicator_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_OFFSETIND_CHOICE, NULL, 0, iptr:(int32_t *)&rxPool_ResourceConfig_offsetIndicator_choice, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_PRESENT, NULL, 0, strptr:(char **)&rxPool_ResourceConfig_subframeBitmap_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_CHOICE_BS_BUF, NULL, 0, strptr:(char **)&rxPool_ResourceConfig_subframeBitmap_choice_bs_buf, defstrval:"001001", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_CHOICE_BS_SIZE, NULL, 0, iptr:(int32_t *)&rxPool_ResourceConfig_subframeBitmap_choice_bs_size, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_RXPOOL_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED, NULL, 0, iptr:(int32_t *)&rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_CP_LEN, NULL, 0, strptr:(char **)&discRxPool_cp_Len, defstrval:"normal", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_DISCPERIOD, NULL, 0, strptr:(char **)&discRxPool_discPeriod, defstrval:"rf32", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_NUMRETX, NULL, 0, iptr:(int32_t *)&discRxPool_numRetx, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_NUMREPETITION, NULL, 0, iptr:(int32_t *)&discRxPool_numRepetition, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_PRB_NUM, NULL, 0, iptr:(int32_t *)&discRxPool_ResourceConfig_prb_Num, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_PRB_START, NULL, 0, iptr:(int32_t *)&discRxPool_ResourceConfig_prb_Start, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_PRB_END, NULL, 0, iptr:(int32_t *)&discRxPool_ResourceConfig_prb_End, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_OFFSETIND_PRESENT, NULL, 0, strptr:(char **)&discRxPool_ResourceConfig_offsetIndicator_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_OFFSETIND_CHOICE, NULL, 0, iptr:(int32_t *)&discRxPool_ResourceConfig_offsetIndicator_choice, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_PRESENT, NULL, 0, strptr:(char **)&discRxPool_ResourceConfig_subframeBitmap_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_CHOICE_BS_BUF, NULL, 0, strptr:(char **)&discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf, defstrval:"001001", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_CHOICE_BS_SIZE, NULL, 0, iptr:(int32_t *)&discRxPool_ResourceConfig_subframeBitmap_choice_bs_size, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOL_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED,NULL, 0, iptr:(int32_t *)&discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_CP_LEN, NULL, 0, strptr:(char **)&discRxPoolPS_cp_Len, defstrval:"normal", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_DISCPERIOD, NULL, 0, strptr:(char **)&discRxPoolPS_discPeriod, defstrval:"rf32", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_NUMRETX, NULL, 0, iptr:(int32_t *)&discRxPoolPS_numRetx, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_NUMREPETITION, NULL, 0, iptr:(int32_t *)&discRxPoolPS_numRepetition, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_PRB_NUM, NULL, 0, iptr:(int32_t *)&discRxPoolPS_ResourceConfig_prb_Num, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_PRB_START, NULL, 0, iptr:(int32_t *)&discRxPoolPS_ResourceConfig_prb_Start, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_PRB_END, NULL, 0, iptr:(int32_t *)&discRxPoolPS_ResourceConfig_prb_End, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_OFFSETIND_PRESENT, NULL, 0, strptr:(char **)&discRxPoolPS_ResourceConfig_offsetIndicator_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_OFFSETIND_CHOICE, NULL, 0, iptr:(int32_t *)&discRxPoolPS_ResourceConfig_offsetIndicator_choice, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_PRESENT, NULL, 0, strptr:(char **)&discRxPoolPS_ResourceConfig_subframeBitmap_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_BUF, NULL, 0, strptr:(char **)&discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf, defstrval:"001001", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_SIZE, NULL, 0, iptr:(int32_t *)&discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size, defintval:1, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED,NULL, 0, iptr:(int32_t *)&discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused, defintval:1, TYPE_UINT, 0} \ } +#define ENB_CONFIG_FRAME_TYPE_IDX 0 +#define ENB_CONFIG_TDD_CONFIG_IDX 1 +#define ENB_CONFIG_TDD_CONFIG_S_IDX 2 +#define ENB_CONFIG_PREFIX_TYPE_IDX 3 +#define ENB_CONFIG_PBCH_REPETITION_IDX 4 +#define ENB_CONFIG_EUTRA_BAND_IDX 5 +#define ENB_CONFIG_DOWNLINK_FREQUENCY_IDX 6 +#define ENB_CONFIG_UPLINK_FREQUENCY_OFFSET_IDX 7 +#define ENB_CONFIG_NID_CELL_IDX 8 +#define ENB_CONFIG_N_RB_DL_IDX 9 +#define ENB_CONFIG_CELL_MBSFN_IDX 10 +#define ENB_CONFIG_NB_ANT_PORTS_IDX 11 +#define ENB_CONFIG_PRACH_ROOT_IDX 12 +#define ENB_CONFIG_PRACH_CONFIG_INDEX_IDX 13 +#define ENB_CONFIG_PRACH_HIGH_SPEED_IDX 14 +#define ENB_CONFIG_PRACH_ZERO_CORRELATION_IDX 15 +#define ENB_CONFIG_PRACH_FREQ_OFFSET_IDX 16 +#define ENB_CONFIG_PUCCH_DELTA_SHIFT_IDX 17 +#define ENB_CONFIG_PUCCH_NRB_CQI_IDX 18 +#define ENB_CONFIG_PUCCH_NCS_AN_IDX 19 +#define ENB_CONFIG_PUCCH_N1_AN_IDX 20 +#define ENB_CONFIG_PDSCH_RS_EPRE_IDX 21 +#define ENB_CONFIG_PDSCH_PB_IDX 22 +#define ENB_CONFIG_PUSCH_N_SB_IDX 23 +#define ENB_CONFIG_PUSCH_HOPPINGMODE_IDX 24 +#define ENB_CONFIG_PUSCH_HOPPINGOFFSET_IDX 25 +#define ENB_CONFIG_PUSCH_ENABLE64QAM_IDX 26 +#define ENB_CONFIG_PUSCH_GROUP_HOPPING_EN_IDX 27 +#define ENB_CONFIG_PUSCH_GROUP_ASSIGNMENT_IDX 28 +#define ENB_CONFIG_PUSCH_SEQUENCE_HOPPING_EN_IDX 29 +#define ENB_CONFIG_PUSCH_NDMRS1_IDX 30 +#define ENB_CONFIG_PHICH_DURATION_IDX 31 +#define ENB_CONFIG_PHICH_RESOURCE_IDX 32 +#define ENB_CONFIG_SRS_ENABLE_IDX 33 +#define ENB_CONFIG_SRS_BANDWIDTH_CONFIG_IDX 34 +#define ENB_CONFIG_SRS_SUBFRAME_CONFIG_IDX 35 +#define ENB_CONFIG_SRS_ACKNACKST_CONFIG_IDX 36 +#define ENB_CONFIG_SRS_MAXUPPTS_IDX 37 +#define ENB_CONFIG_PUSCH_PO_NOMINAL_IDX 38 +#define ENB_CONFIG_PUSCH_ALPHA_IDX 39 +#define ENB_CONFIG_PUCCH_PO_NOMINAL_IDX 40 +#define ENB_CONFIG_MSG3_DELTA_PREAMBLE_IDX 41 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1_IDX 42 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1b_IDX 43 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2_IDX 44 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2A_IDX 45 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2B_IDX 46 +#define ENB_CONFIG_RACH_NUM_RA_PREAMBLES_IDX 47 +#define ENB_CONFIG_RACH_PREAMBLESGROUPACONFIG_IDX 48 +#define ENB_CONFIG_RACH_SIZEOFRA_PREAMBLESGROUPA_IDX 49 +#define ENB_CONFIG_RACH_MESSAGESIZEGROUPA_IDX 50 +#define ENB_CONFIG_RACH_MESSAGEPOWEROFFSETGROUPB_IDX 51 +#define ENB_CONFIG_RACH_POWERRAMPINGSTEP_IDX 52 +#define ENB_CONFIG_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_IDX 53 +#define ENB_CONFIG_RACH_PREAMBLETRANSMAX_IDX 54 +#define ENB_CONFIG_RACH_RARESPONSEWINDOWSIZE_IDX 55 +#define ENB_CONFIG_RACH_MACCONTENTIONRESOLUTIONTIMER_IDX 56 +#define ENB_CONFIG_RACH_MAXHARQMSG3TX_IDX 57 +#define ENB_CONFIG_PCCH_DEFAULT_PAGING_CYCLE_IDX 58 +#define ENB_CONFIG_PCCH_NB_IDX 59 +#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 60 +#define ENB_CONFIG_UETIMERS_T300_IDX 61 +#define ENB_CONFIG_UETIMERS_T301_IDX 62 +#define ENB_CONFIG_UETIMERS_T310_IDX 63 +#define ENB_CONFIG_UETIMERS_T311_IDX 64 +#define ENB_CONFIG_UETIMERS_N310_IDX 65 +#define ENB_CONFIG_UETIMERS_N311_IDX 66 +#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 67 + /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* SRB1 configuration parameters section name */ @@ -575,56 +775,32 @@ static int DEFENBS[] = {0}; -/* L1 configuration parameters names */ -#define CONFIG_STRING_L1_CC "num_cc" -#define CONFIG_STRING_L1_LOCAL_N_IF_NAME "local_n_if_name" -#define CONFIG_STRING_L1_LOCAL_N_ADDRESS "local_n_address" -#define CONFIG_STRING_L1_REMOTE_N_ADDRESS "remote_n_address" -#define CONFIG_STRING_L1_LOCAL_N_PORTC "local_n_portc" -#define CONFIG_STRING_L1_REMOTE_N_PORTC "remote_n_portc" -#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" -#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" -#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" - -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* L1 configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define L1PARAMS_DESC { \ -{CONFIG_STRING_L1_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -} -#define L1_CC_IDX 0 -#define L1_TRANSPORT_N_PREFERENCE_IDX 1 -#define L1_LOCAL_N_IF_NAME_IDX 2 -#define L1_LOCAL_N_ADDRESS_IDX 3 -#define L1_REMOTE_N_ADDRESS_IDX 4 -#define L1_LOCAL_N_PORTC_IDX 5 -#define L1_REMOTE_N_PORTC_IDX 6 -#define L1_LOCAL_N_PORTD_IDX 7 -#define L1_REMOTE_N_PORTD_IDX 8 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" - -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME "FLEXRAN_AGENT_INTERFACE_NAME" -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS "FLEXRAN_AGENT_IPV4_ADDRESS" -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT "FLEXRAN_AGENT_PORT" -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE "FLEXRAN_AGENT_CACHE" +#define CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" + +#define CONFIG_STRING_FLEXRAN_ENABLED "FLEXRAN_ENABLED" +#define CONFIG_STRING_FLEXRAN_INTERFACE_NAME "FLEXRAN_INTERFACE_NAME" +#define CONFIG_STRING_FLEXRAN_IPV4_ADDRESS "FLEXRAN_IPV4_ADDRESS" +#define CONFIG_STRING_FLEXRAN_PORT "FLEXRAN_PORT" +#define CONFIG_STRING_FLEXRAN_CACHE "FLEXRAN_CACHE" +#define CONFIG_STRING_FLEXRAN_AWAIT_RECONF "FLEXRAN_AWAIT_RECONF" + +#define FLEXRAN_ENABLED 0 +#define FLEXRAN_INTERFACE_NAME_IDX 1 +#define FLEXRAN_IPV4_ADDRESS_IDX 2 +#define FLEXRAN_PORT_IDX 3 +#define FLEXRAN_CACHE_IDX 4 +#define FLEXRAN_AWAIT_RECONF_IDX 5 #define FLEXRANPARAMS_DESC { \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0} \ +{CONFIG_STRING_FLEXRAN_ENABLED, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_INTERFACE_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_IPV4_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_PORT, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ +{CONFIG_STRING_FLEXRAN_CACHE, NULL, 0, strptr:NULL, defstrval:"/mnt/oai_agent_cache", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_AWAIT_RECONF, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0} \ } /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -653,32 +829,8 @@ static int DEFENBS[] = {0}; #define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" #define CONFIG_STRING_MACRLC_SCHED_MODE "scheduler_mode" +#define CONFIG_STRING_MACRLC_PHY_TEST_MODE "phy_test_mode" - -/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* MacRLC configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define MACRLCPARAMS_DESC { \ -{CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_L1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_RRC", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_SCHED_MODE, NULL, 0, strptr:NULL, defintval:"default", TYPE_STRING, 0}, \ -} #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 #define MACRLC_LOCAL_N_IF_NAME_IDX 2 @@ -697,4 +849,5 @@ static int DEFENBS[] = {0}; #define MACRLC_LOCAL_S_PORTD_IDX 15 #define MACRLC_REMOTE_S_PORTD_IDX 16 #define MACRLC_SCHED_MODE_IDX 17 +#define MACRLC_PHY_TEST_IDX 18 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 4faa1f36243353aa7faf6e070e2aa8319a79e8f9..8d5cdbc06bd396b68e1e7c43fa11bfdabcf9476a 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -21,35 +21,15 @@ /*! \file flexran_agent.h * \brief top level flexran agent receive thread and itti task - * \author Xenofon Foukas and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas and Navid Nikaein and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ -#include "flexran_agent_common.h" -#include "log.h" #include "flexran_agent.h" -#include "flexran_agent_mac_defs.h" -#include "flexran_agent_mac.h" -#include "flexran_agent_mac_internal.h" - -#include "flexran_agent_extern.h" - -#include "assertions.h" - -#include "flexran_agent_net_comm.h" -#include "flexran_agent_async.h" #include <arpa/inet.h> -//#define TEST_TIMER - -flexran_agent_instance_t flexran_agent[NUM_MAX_ENB]; - -char in_ip[40]; -static uint16_t in_port; -char local_cache[40]; - void *send_thread(void *args); void *receive_thread(void *args); pthread_t new_thread(void *(*f)(void *), void *b); @@ -63,7 +43,7 @@ int agent_task_created = 0; */ void *flexran_agent_task(void *args){ - //flexran_agent_instance_t *d = (flexran_agent_instance_t *) args; + //flexran_agent_info_t *d = (flexran_agent_info_t *) args; Protocol__FlexranMessage *msg; void *data; int size; @@ -85,6 +65,7 @@ void *flexran_agent_task(void *args){ switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(FLEXRAN_AGENT, " *** Exiting FLEXRAN thread\n"); itti_exit_task (); break; @@ -123,7 +104,7 @@ void *flexran_agent_task(void *args){ void *receive_thread(void *args) { - flexran_agent_instance_t *d = args; + flexran_agent_info_t *d = args; void *data; int size; int priority; @@ -133,12 +114,12 @@ void *receive_thread(void *args) { while (1) { - while (flexran_agent_msg_recv(d->enb_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) { + while (flexran_agent_msg_recv(d->mod_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) { LOG_D(FLEXRAN_AGENT,"received message with size %d\n", size); // Invoke the message handler - msg=flexran_agent_handle_message(d->enb_id, data, size); + msg=flexran_agent_handle_message(d->mod_id, data, size); free(data); @@ -146,7 +127,7 @@ void *receive_thread(void *args) { if (msg != NULL){ data=flexran_agent_pack_message(msg,&size); - if (flexran_agent_msg_send(d->enb_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { + if (flexran_agent_msg_send(d->mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; goto error; } @@ -197,38 +178,18 @@ pthread_t new_thread(void *(*f)(void *), void *b) { } int channel_container_init = 0; -int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){ - +int flexran_agent_start(mid_t mod_id) +{ + flexran_agent_info_t *flexran = RC.flexran[mod_id]; int channel_id; - - flexran_set_enb_vars(mod_id, RAN_LTE_OAI); - flexran_agent[mod_id].enb_id = mod_id; - - /* - * check the configuration - */ - if (enb_properties->properties[mod_id]->flexran_agent_cache != NULL) { - strncpy(local_cache, enb_properties->properties[mod_id]->flexran_agent_cache, sizeof(local_cache)); - local_cache[sizeof(local_cache) - 1] = 0; - } else { - strcpy(local_cache, DEFAULT_FLEXRAN_AGENT_CACHE); - } - - if (enb_properties->properties[mod_id]->flexran_agent_ipv4_address != 0) { - inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN); - } else { - strcpy(in_ip, DEFAULT_FLEXRAN_AGENT_IPv4_ADDRESS ); - } - - if (enb_properties->properties[mod_id]->flexran_agent_port != 0 ) { - in_port = enb_properties->properties[mod_id]->flexran_agent_port; - } else { - in_port = DEFAULT_FLEXRAN_AGENT_PORT ; + char *in_ip = flexran->remote_ipv4_addr; + uint16_t in_port = flexran->remote_port; + + /* if this agent is disabled, return and don't do anything */ + if (!flexran->enabled) { + LOG_I(FLEXRAN_AGENT, "FlexRAN Agent for eNB %d is DISABLED\n", mod_id); + return 100; } - LOG_I(FLEXRAN_AGENT,"starting enb agent client for module id %d on ipv4 %s, port %d\n", - flexran_agent[mod_id].enb_id, - in_ip, - in_port); /* * Initialize the channel container @@ -264,10 +225,10 @@ int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properti *flexran_agent_register_channel(mod_id, channel, FLEXRAN_AGENT_MAC); */ - /*Initialize the continuous MAC stats update mechanism*/ - flexran_agent_init_cont_mac_stats_update(mod_id); + /*Initialize the continuous stats update mechanism*/ + flexran_agent_init_cont_stats_update(mod_id); - new_thread(receive_thread, &flexran_agent[mod_id]); + new_thread(receive_thread, flexran); /*Initialize and register the mac xface. Must be modified later *for more flexibility in agent management */ @@ -275,6 +236,12 @@ int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properti AGENT_MAC_xface *mac_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface)); flexran_agent_register_mac_xface(mod_id, mac_agent_xface); + AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface)); + flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface); + + AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface)); + flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); + /* * initilize a timer */ @@ -290,14 +257,34 @@ int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properti * start the enb agent task for tx and interaction with the underlying network function */ if (!agent_task_created) { - if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, (void *) &flexran_agent[mod_id]) < 0) { + if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, flexran) < 0) { LOG_E(FLEXRAN_AGENT, "Create task for FlexRAN Agent failed\n"); return -1; } agent_task_created = 1; } - - LOG_I(FLEXRAN_AGENT,"client ends\n"); + + pthread_mutex_init(&flexran->mutex_node_ctrl, NULL); + pthread_cond_init(&flexran->cond_node_ctrl, NULL); + + if (flexran->node_ctrl_state == ENB_WAIT) { + /* wait three seconds before showing message and waiting "for real". + * This way, the message is (hopefully...) the last one and the user knows + * what is happening. If the controller sends a reconfiguration message in + * the meantime, the softmodem will never wait */ + sleep(3); + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + pthread_mutex_lock(&flexran->mutex_node_ctrl); + while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) + pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + + /* reconfigure RRC again, the agent might have changed the configuration */ + MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[mod_id]->configuration; + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg_p); + } + return 0; error: diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index 579bf3be2357b4a0ad7d942194fc5690d3eec978..aed8f9eb60dc386700e74fbd1eeb7e7fddd5f96b 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -22,20 +22,28 @@ /*! \file flexran_agent.h * \brief top level flexran agent * \author Navid Nikaein and Xenofon Foukas - * \date 2016 + * \date 2017 * \version 0.1 */ #ifndef FLEXRAN_AGENT_H_ #define FLEXRAN_AGENT_H_ -#include "enb_config.h" // for enb properties #include "flexran_agent_common.h" +#include "flexran_agent_async.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_timer.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_net_comm.h" +#include "flexran_agent_ran_api.h" +#include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" +#include "flexran_agent_pdcp.h" +#include "log.h" +#include "assertions.h" - -/* Initiation and termination of the eNodeB agent */ -int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties); -int flexran_agent_stop(mid_t mod_id); +/* Initiation of the eNodeB agent */ +int flexran_agent_start(mid_t mod_id); /* * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller diff --git a/openair2/ENB_APP/flexran_agent_async.c b/openair2/ENB_APP/flexran_agent_async.c index f1edc291c9cfab179ab46e5f932578e08ad85357..9e099fc21c31dd1b2ecaf39fc389f46e5770c90f 100644 --- a/openair2/ENB_APP/flexran_agent_async.c +++ b/openair2/ENB_APP/flexran_agent_async.c @@ -68,12 +68,12 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c error: LOG_I(FLEXRAN_AGENT,"there was an error\n"); - return 1; + return NULL; } int flexran_agent_async_msg_send(void *data, int size, int priority, void *channel_info) { flexran_agent_async_channel_t *channel; - channel = (flexran_agent_channel_t *)channel_info; + channel = (flexran_agent_async_channel_t *)channel_info; return message_put(channel->send_queue, data, size, priority); } diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 69c786edb333e33f0d12679bd5f711e6dbaa0799..3bbea167d37dfacf1e8e2ca6cc0c576a2918f18d 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -21,30 +21,28 @@ /*! \file flexran_agent_common.c * \brief common primitives for all agents - * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein, shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ -#include<stdio.h> +#include <stdio.h> #include <time.h> +#include <sys/stat.h> #include "flexran_agent_common.h" #include "flexran_agent_common_internal.h" #include "flexran_agent_extern.h" #include "flexran_agent_net_comm.h" -#include "PHY/extern.h" +#include "flexran_agent_ran_api.h" +//#include "PHY/extern.h" #include "log.h" -#include "SCHED/defs.h" -#include "RRC/LITE/extern.h" +//#include "SCHED/defs.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "rrc_eNB_UE_context.h" -void * enb[NUM_MAX_ENB]; -void * enb_ue[NUM_MAX_ENB]; -void * enb_rrc[NUM_MAX_ENB]; - /* * message primitives */ @@ -108,7 +106,7 @@ int flexran_create_header(xid_t xid, Protocol__FlexType type, Protocol__FlexHea int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; /*TODO: Need to set random xid or xid from received hello message*/ xid_t xid = 1; @@ -163,7 +161,7 @@ int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) { int flexran_agent_echo_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; /*TODO: Need to set a random xid*/ xid_t xid = 1; @@ -218,6 +216,7 @@ int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) { int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEchoRequest *echo_req = input->echo_request_msg; xid = (echo_req->header)->xid; @@ -228,7 +227,6 @@ int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__Flexran goto error; protocol__flex_echo_reply__init(echo_reply_msg); - Protocol__FlexHeader *header; if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REPLY, &header) != 0) goto error; @@ -344,19 +342,6 @@ int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) { return -1; } -int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { - if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG) - goto error; - free(msg->ue_state_change_msg->header); - //TODO: Free the contents of the UE config structure - free(msg->ue_state_change_msg); - free(msg); - return 0; - - error: - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; -} int flexran_agent_destroy_enb_config_request(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG) @@ -402,14 +387,13 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg; // struct timespec vartime = timer_start(); - //Write the payload lib into a file in the cache and load the lib char lib_name[120]; char target[512]; snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name); - strcpy(target, local_cache); + strcpy(target, RC.flexran[mod_id]->cache_name); strcat(target, lib_name); - + FILE *f; f = fopen(target, "wb"); fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); @@ -442,1088 +426,10 @@ int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) { } -/* - * get generic info from RAN - */ - -void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ - - switch (ran){ - case RAN_LTE_OAI : - enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; - enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; - enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; - break; - default : - goto error; - } - - return; - - error: - LOG_E(FLEXRAN_AGENT, "unknown RAN name %d\n", ran); -} - -int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){ - - if (subframe_flag == 1){ - return ((eNB_MAC_INST *)enb[mod_id])->frame*10 + ((eNB_MAC_INST *)enb[mod_id])->subframe; - }else { - return ((eNB_MAC_INST *)enb[mod_id])->frame*10; - } - -} - -unsigned int flexran_get_current_frame (mid_t mod_id) { - - // #warning "SFN will not be in [0-1023] when oaisim is used" - return ((eNB_MAC_INST *)enb[mod_id])->frame; - -} - -unsigned int flexran_get_current_system_frame_num(mid_t mod_id) { - return (flexran_get_current_frame(mod_id) %1024); -} - -unsigned int flexran_get_current_subframe (mid_t mod_id) { - - return ((eNB_MAC_INST *)enb[mod_id])->subframe; - -} - -uint16_t flexran_get_sfn_sf (mid_t mod_id) { - - frame_t frame; - sub_frame_t subframe; - uint16_t sfn_sf, frame_mask, sf_mask; - - frame = (frame_t) flexran_get_current_system_frame_num(mod_id); - subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); - frame_mask = ((1<<12) - 1); - sf_mask = ((1<<4) - 1); - sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); - - return sfn_sf; -} - -uint16_t flexran_get_future_sfn_sf (mid_t mod_id, int ahead_of_time) { - - frame_t frame; - sub_frame_t subframe; - uint16_t sfn_sf, frame_mask, sf_mask; - - 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); - - if (subframe < flexran_get_current_subframe(mod_id)) { - 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); - - return sfn_sf; -} - -int flexran_get_num_ues (mid_t mod_id){ - - return ((UE_list_t *)enb_ue[mod_id])->num_UEs; -} - -int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id) { - - return UE_RNTI(mod_id, ue_id); -} - -int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid) { - - return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; -} - -int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id) { - - return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].phr_info; -} - -int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { - 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); - uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,subframe,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); - return rlc_status.bytes_in_buffer; -} - -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); - uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, 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; - int rnti; - - 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); - //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 { - ue_sched_ctl->ta_timer--; - ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command - } -} - -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; - - 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); - - if (eNB_UE_stats == NULL) { - return 0; - } - - if (flexran_get_TA(mod_id, ue_id, CC_id) != 0) { - return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; - } else { - return 0; - } - -} - -int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) { - return ((UE_list_t *)enb_ue[mod_id])->numactiveCCs[ue_id]; -} - -int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - - rnti_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 0; - } - - return eNB_UE_stats[CC_id].rank; -} - -int flexran_get_tpc(mid_t mod_id, mid_t ue_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - int32_t normalized_rx_power, target_rx_power; - int tpc = 1; - - int pCCid = UE_PCCID(mod_id,ue_id); - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, pCCid, rnti); - - target_rx_power = mac_xface->get_target_pusch_rx_power(mod_id,pCCid); - - if (eNB_UE_stats == NULL) { - normalized_rx_power = target_rx_power; - } else if (eNB_UE_stats->UL_rssi != NULL) { - normalized_rx_power = eNB_UE_stats->UL_rssi[0]; - } else { - normalized_rx_power = target_rx_power; - } - - if (normalized_rx_power>(target_rx_power+1)) { - tpc = 0; //-1 - } else if (normalized_rx_power<(target_rx_power-1)) { - tpc = 2; //+1 - } else { - tpc = 1; //0 - } - 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, - 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];*/ - - uint8_t harq_pid; - uint8_t harq_round; - - - uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); - - *id = harq_pid; - *round = harq_round; - /* if (round > 0) { */ - /* *status = 1; */ - /* } else { */ - /* *status = 0; */ - /* } */ - - /* return 0; */ - return *round; -} - -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; -} - -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; -} - -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; -} - -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; -} - - -/* - * ************************************ - * Get Messages for eNB Configuration Reply - * ************************************ - */ - -int flexran_get_hopping_offset(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.pusch_HoppingOffset; -} - -int flexran_get_hopping_mode(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.hoppingMode; -} - -int flexran_get_n_SB(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.n_SB; -} - -int flexran_get_enable64QAM(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.enable64QAM; -} - -int flexran_get_phich_duration(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->phich_config_common.phich_duration; -} - -int flexran_get_phich_resource(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - if(frame_parms->phich_config_common.phich_resource == oneSixth) - return 0; - else if(frame_parms->phich_config_common.phich_resource == half) - return 1; - else if(frame_parms->phich_config_common.phich_resource == one) - return 2; - else if(frame_parms->phich_config_common.phich_resource == two) - return 3; - - return -1; -} - -int flexran_get_n1pucch_an(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.n1PUCCH_AN; -} - -int flexran_get_nRB_CQI(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.nRB_CQI; -} - -int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.deltaPUCCH_Shift; -} - -int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; -} - -int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; -} - -int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->maxHARQ_Msg3Tx; -} - -int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Ncp_UL; -} - -int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Ncp; -} - -int flexran_get_cell_id(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Nid_cell; -} - -int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig; -} - -int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; -} - -int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_MaxUpPts; -} - -int flexran_get_N_RB_DL(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RB_DL; -} - -int flexran_get_N_RB_UL(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RB_UL; -} - -int flexran_get_N_RBG(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RBG; -} - -int flexran_get_subframe_assignment(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->tdd_config; -} - -int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->tdd_config_S; -} - -int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id) { - return enb_config_get()->properties[mod_id]->rach_raResponseWindowSize[CC_id]; -} - -int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id) { - return enb_config_get()->properties[mod_id]->rach_macContentionResolutionTimer[CC_id]; -} - -int flexran_get_duplex_mode(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - if(frame_parms->frame_type == TDD) - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; - else if (frame_parms->frame_type == FDD) - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; - - return -1; -} - -long flexran_get_si_window_length(mid_t mod_id, int CC_id) { - return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sib1->si_WindowLength; -} - -int flexran_get_sib1_length(mid_t mod_id, int CC_id) { - return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sizeof_SIB1; -} - -int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id) { - /* TODO: This should return the number of PDCCH symbols initially used by the cell CC_id */ - return 0; - //(PHY_vars_UE_g[mod_id][CC_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols); -} - - - -/* - * ************************************ - * Get Messages for UE Configuration Reply - * ************************************ - */ - - -int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL) { - return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measGapConfig != NULL) { - if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { - if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; - } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; - } else { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; - } - } - } - } - return -1; -} - - -int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measGapConfig != NULL){ - if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { - if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - } - } - } - } - return -1; -} - -int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id) { - return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; -} - -int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id) { - return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; -} - -int flexran_get_half_duplex(mid_t ue_id) { - // TODO - //int halfduplex = 0; - //int bands_to_scan = ((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; - //for (int i =0; i < bands_to_scan; i++){ - //if(((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->halfDuplex > 0) - // halfduplex = 1; - //} - //return halfduplex; - return 0; -} - -int flexran_get_intra_sf_hopping(mid_t ue_id) { - //TODO:Get proper value - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (0 & ( 1 << (31))); - return 0; -} - -int flexran_get_type2_sb_1(mid_t ue_id) { - //TODO:Get proper value - //uint8_t temp = 0; - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (temp & ( 1 << (11))); - return 0; -} - -int flexran_get_ue_category(mid_t ue_id) { - //TODO:Get proper value - //return (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->ue_Category); - return 0; -} - -int flexran_get_res_alloc_type1(mid_t ue_id) { - //TODO:Get proper value - //uint8_t temp = 0; - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (temp & ( 1 << (30))); - return 0; -} - -int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; - } else { - return -1; - } - } - else { - return -1; - } -} - -int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - return *ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; - } - } - return -1; -} - -int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - } else { - return -1; - } - } - else { - return -1; - } -} - -int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - if (ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { - return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; - } - } - } - return -1; -} - -int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id) { - return (&eNB_rrc_inst[mod_id])->carrier[0].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; -} - -int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; - } - } - return -1; -} - -int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id) { - // TODO: This needs fixing - return -1; - - /* struct rrc_eNB_ue_context_s* ue_context_p = NULL; */ - /* uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); */ - - /* ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); */ - - /* if(ue_context_p != NULL) { */ - /* if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ */ - /* return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; */ - /* } else { */ - /* return -1; */ - /* } */ - /* } else { */ - /* return -1; */ - /* } */ -} - -int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) { - //TODO: need to double check - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - if(ue_context_p->ue_context.mac_MainConfig->ext2 != NULL){ - long val = (*(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10)); - if (val > 0) { - return 1; - } - } - } - } - return -1; -} - -int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop) { - return 2; - } else if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_lcg(mid_t ue_id, mid_t lc_id) { - if (UE_mac_inst == NULL) { - return -1; - } - if(UE_mac_inst[ue_id].logicalChannelConfig[lc_id] != NULL) { - return *UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup; - } else { - return -1; - } -} - -int flexran_get_direction(mid_t ue_id, mid_t lc_id) { - /*TODO: fill with the value for the rest of LCID*/ - if(lc_id == DCCH || lc_id == DCCH1) { - return 2; - } else if(lc_id == DTCH) { - return 1; - } else { - return -1; - } -} - -int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { - int size; - Protocol__FlexranMessage *msg; - Protocol__FlexHeader *header; - void *data; - int priority = 0; - - int xid = 0; - - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UE_STATE_CHANGE, &header) != 0) - goto error; - - Protocol__FlexUeStateChange *ue_state_change_msg; - ue_state_change_msg = malloc(sizeof(Protocol__FlexUeStateChange)); - if(ue_state_change_msg == NULL) { - goto error; - } - protocol__flex_ue_state_change__init(ue_state_change_msg); - ue_state_change_msg->has_type = 1; - ue_state_change_msg->type = state_change; - - Protocol__FlexUeConfig *config; - config = malloc(sizeof(Protocol__FlexUeConfig)); - if (config == NULL) { - goto error; - } - protocol__flex_ue_config__init(config); - if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED) { - // Simply set the rnti of the UE - config->has_rnti = 1; - config->rnti = rnti; - } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED - || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { - int i = find_UE_id(mod_id, rnti); - config->has_rnti = 1; - config->rnti = rnti; - if(flexran_get_time_alignment_timer(mod_id,i) != -1) { - config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); - config->has_time_alignment_timer = 1; - } - if(flexran_get_meas_gap_config(mod_id,i) != -1){ - config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); - config->has_meas_gap_config_pattern = 1; - } - if(config->has_meas_gap_config_pattern == 1 && - config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); - config->has_meas_gap_config_sf_offset = 1; - } - //TODO: Set the SPS configuration (Optional) - //Not supported for now, so we do not set it - - //TODO: Set the SR configuration (Optional) - //We do not set it for now - - //TODO: Set the CQI configuration (Optional) - //We do not set it for now - - if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { - config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); - config->has_transmission_mode = 1; - } - - config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); - config->has_ue_aggregated_max_bitrate_ul = 1; - - config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); - config->has_ue_aggregated_max_bitrate_dl = 1; - - //TODO: Set the UE capabilities - Protocol__FlexUeCapabilities *c_capabilities; - c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); - protocol__flex_ue_capabilities__init(c_capabilities); - //TODO: Set half duplex (FDD operation) - c_capabilities->has_half_duplex = 0; - c_capabilities->half_duplex = 1;//flexran_get_half_duplex(i); - //TODO: Set intra-frame hopping flag - c_capabilities->has_intra_sf_hopping = 0; - c_capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); - //TODO: Set support for type 2 hopping with n_sb > 1 - c_capabilities->has_type2_sb_1 = 0; - c_capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); - //TODO: Set ue category - c_capabilities->has_ue_category = 0; - c_capabilities->ue_category = 1;//flexran_get_ue_category(i); - //TODO: Set UE support for resource allocation type 1 - c_capabilities->has_res_alloc_type1 = 0; - c_capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); - //Set the capabilites to the message - config->capabilities = c_capabilities; - - if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { - config->has_ue_transmission_antenna = 1; - config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); - } - - if(flexran_get_tti_bundling(mod_id,i) != -1) { - config->has_tti_bundling = 1; - config->tti_bundling = flexran_get_tti_bundling(mod_id,i); - } - - if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ - config->has_max_harq_tx = 1; - config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); - } - - if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { - config->has_beta_offset_ack_index = 1; - config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); - } - - if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { - config->has_beta_offset_ri_index = 1; - config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); - } - - if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { - config->has_beta_offset_cqi_index = 1; - config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); - } - - if(flexran_get_ack_nack_simultaneous_trans(mod_id,i) != -1) { - config->has_ack_nack_simultaneous_trans = 1; - config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i); - } - - if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { - config->has_simultaneous_ack_nack_cqi = 1; - config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); - } - - if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { - config->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); - if (mode > 4) { - config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; - } else { - config->aperiodic_cqi_rep_mode = mode; - } - } - - if(flexran_get_tdd_ack_nack_feedback(mod_id, i) != -1) { - config->has_tdd_ack_nack_feedback = 1; - config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback(mod_id,i); - } - - if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { - config->has_ack_nack_repetition_factor = 1; - config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); - } - - if(flexran_get_extended_bsr_size(mod_id, i) != -1) { - config->has_extended_bsr_size = 1; - config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); - } - - config->has_pcell_carrier_index = 1; - config->pcell_carrier_index = UE_PCCID(mod_id, i); - //TODO: Set carrier aggregation support (boolean) - config->has_ca_support = 0; - config->ca_support = 0; - if(config->has_ca_support){ - //TODO: Set cross carrier scheduling support (boolean) - config->has_cross_carrier_sched_support = 1; - config->cross_carrier_sched_support = 0; - //TODO: Set secondary cells configuration - // We do not set it for now. No carrier aggregation support - - //TODO: Set deactivation timer for secondary cell - config->has_scell_deactivation_timer = 0; - config->scell_deactivation_timer = 0; - } - } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) { - // TODO: Not supported for now. Leave blank - } - - ue_state_change_msg->config = config; - msg = malloc(sizeof(Protocol__FlexranMessage)); - if (msg == NULL) { - goto error; - } - protocol__flexran_message__init(msg); - msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG; - msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; - msg->ue_state_change_msg = ue_state_change_msg; - - data = flexran_agent_pack_message(msg, &size); - /*Send sr info using the MAC channel of the eNB*/ - if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { - goto error; - } - - LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); - return 0; - error: - LOG_D(FLEXRAN_AGENT, "Could not send UE state message\n"); - return -1; -} - - - int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexLcConfigRequest *lc_config_request_msg = input->lc_config_request_msg; xid = (lc_config_request_msg->header)->xid; @@ -1536,7 +442,6 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl goto error; protocol__flex_lc_config_reply__init(lc_config_reply_msg); - Protocol__FlexHeader *header; if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_LC_CONFIG_REPLY, &header) != 0) goto error; @@ -1562,6 +467,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl //Set this according to the current state of the UE. This is only a temporary fix int status = 0; status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, i)); + /* TODO needs to be revised and appropriate API to be implemented */ if (status < RRC_CONNECTED) { lc_ue_config[i]->n_lc_config = 0; } else if (status == RRC_CONNECTED) { @@ -1583,10 +489,10 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_config[j]->has_lcid = 1; lc_config[j]->lcid = j+1; - int lcg = flexran_get_lcg(i, j+1); + int lcg = flexran_get_lcg(mod_id, i, j+1); if (lcg >= 0 && lcg <= 3) { lc_config[j]->has_lcg = 1; - lc_config[j]->lcg = flexran_get_lcg(i,j+1); + lc_config[j]->lcg = flexran_get_lcg(mod_id, i,j+1); } lc_config[j]->has_direction = 1; @@ -1600,6 +506,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_config[j]->has_qci = 1; lc_config[j]->qci = 1; if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) { + /* TODO all of the need to be taken from API */ //TODO: Set the max bitrate (UL) lc_config[j]->has_e_rab_max_bitrate_ul = 0; lc_config[j]->e_rab_max_bitrate_ul = 0; @@ -1650,6 +557,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexUeConfigRequest *ue_config_request_msg = input->ue_config_request_msg; xid = (ue_config_request_msg->header)->xid; @@ -1662,7 +570,6 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl goto error; protocol__flex_ue_config_reply__init(ue_config_reply_msg); - Protocol__FlexHeader *header; if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_UE_CONFIG_REPLY, &header) != 0) goto error; @@ -1682,6 +589,8 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i); ue_config[i]->has_rnti = 1; + ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, i); + ue_config[i]->has_imsi = 1; //TODO: Set the DRX configuration (optional) //Not supported for now, so we do not set it @@ -1723,21 +632,16 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl Protocol__FlexUeCapabilities *capabilities; capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); protocol__flex_ue_capabilities__init(capabilities); - //TODO: Set half duplex (FDD operation) - capabilities->has_half_duplex = 0; - capabilities->half_duplex = 0;//flexran_get_half_duplex(i); - //TODO: Set intra-frame hopping flag - capabilities->has_intra_sf_hopping = 0; - capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); - //TODO: Set support for type 2 hopping with n_sb > 1 - capabilities->has_type2_sb_1 = 0; - capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); - //TODO: Set ue category - capabilities->has_ue_category = 0; - capabilities->ue_category = 1;//flexran_get_ue_category(i); - //TODO: Set UE support for resource allocation type 1 - capabilities->has_res_alloc_type1 = 0; - capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); + capabilities->has_half_duplex = 1; + capabilities->half_duplex = flexran_get_half_duplex(mod_id, i); + capabilities->has_intra_sf_hopping = 1; + capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i); + capabilities->has_type2_sb_1 = 1; + capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i); + capabilities->has_ue_category = 1; + capabilities->ue_category = flexran_get_ue_category(mod_id, i); + capabilities->has_res_alloc_type1 = 1; + capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i); //Set the capabilites to the message ue_config[i]->capabilities = capabilities; @@ -1771,9 +675,10 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); } - if (flexran_get_ack_nack_simultaneous_trans(mod_id,i) != -1) { + /* assume primary carrier */ + if (flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0) != -1) { ue_config[i]->has_ack_nack_simultaneous_trans = 1; - ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i); + ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0); } if (flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { @@ -1791,9 +696,9 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl } } - if (flexran_get_tdd_ack_nack_feedback(mod_id, i) != -1) { + if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { ue_config[i]->has_tdd_ack_nack_feedback = 1; - ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback(mod_id,i); + ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); } if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { @@ -1854,7 +759,7 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl int flexran_agent_enb_config_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; xid_t xid = 1; Protocol__FlexEnbConfigRequest *enb_config_request_msg; @@ -1893,12 +798,12 @@ int flexran_agent_enb_config_request(mid_t mod_id, const void* params, Protocol_ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEnbConfigRequest *enb_config_req_msg = input->enb_config_request_msg; xid = (enb_config_req_msg->header)->xid; int i, j; - int enb_id = mod_id; Protocol__FlexEnbConfigReply *enb_config_reply_msg; enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply)); @@ -1906,15 +811,14 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F goto error; protocol__flex_enb_config_reply__init(enb_config_reply_msg); - Protocol__FlexHeader *header; if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REPLY, &header) != 0) goto error; enb_config_reply_msg->header = header; - - enb_config_reply_msg->enb_id = mod_id; - - + + enb_config_reply_msg->enb_id = RC.flexran[mod_id]->agent_id; + enb_config_reply_msg->has_enb_id = 1; + enb_config_reply_msg->n_cell_config = MAX_NUM_CCs; Protocol__FlexCellConfig **cell_conf; @@ -1927,61 +831,60 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F protocol__flex_cell_config__init(cell_conf[i]); cell_conf[i]->phy_cell_id = 1; - cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(enb_id,i); + cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(mod_id,i); cell_conf[i]->cell_id = i; cell_conf[i]->has_cell_id = 1; - cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(enb_id,i); + cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(mod_id,i); cell_conf[i]->has_pusch_hopping_offset = 1; - if (flexran_get_hopping_mode(enb_id,i) == 0) { + if (flexran_get_hopping_mode(mod_id,i) == 0) { cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER; - } else if(flexran_get_hopping_mode(enb_id,i) == 1) { + } else if(flexran_get_hopping_mode(mod_id,i) == 1) { cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA; } cell_conf[i]->has_hopping_mode = 1; - cell_conf[i]->n_sb = flexran_get_n_SB(enb_id,i); + cell_conf[i]->n_sb = flexran_get_n_SB(mod_id,i); cell_conf[i]->has_n_sb = 1; - if (flexran_get_phich_resource(enb_id,i) == 0) { + if (flexran_get_phich_resource(mod_id,i) == 0) { cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; //0 - } else if (flexran_get_phich_resource(enb_id,i) == 1) { + } else if (flexran_get_phich_resource(mod_id,i) == 1) { cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; //1 - } else if (flexran_get_phich_resource(enb_id,i) == 2) { + } else if (flexran_get_phich_resource(mod_id,i) == 2) { cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; // 2 - } else if (flexran_get_phich_resource(enb_id,i) == 3) { + } else if (flexran_get_phich_resource(mod_id,i) == 3) { cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;//3 } cell_conf[i]->has_phich_resource = 1; - if (flexran_get_phich_duration(enb_id,i) == 0) { + if (flexran_get_phich_duration(mod_id,i) == 0) { cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL; - } else if(flexran_get_phich_duration(enb_id,i) == 1) { + } else if(flexran_get_phich_duration(mod_id,i) == 1) { cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED; } cell_conf[i]->has_phich_duration = 1; - //TODO: Fill in with actual value, See TS 36.211, section 6.9 - cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(enb_id,i); - cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 0; - //TODO: Fill in with actual value - /* Protocol__FlexSiConfig *si_config; */ - /* si_config = malloc(sizeof(Protocol__FlexSiConfig)); */ - /* if(si_config == NULL) */ - /* goto error; */ - /* protocol__flex_si_config__init(si_config); */ - /* //TODO: Fill in with actual value, Frame number to apply the SI configuration */ - /* si_config->sfn = 1; */ - /* si_config->has_sfn = 1; */ - /* //TODO: Fill in with actual value, the length of SIB1 in bytes */ - /* si_config->sib1_length = get_sib1_length(enb_id,i); */ - /* si_config->has_sib1_length = 1; */ - /* //TODO: Fill in with actual value, Scheduling window for all SIs in SF */ - /* si_config->si_window_length = (uint32_t) get_si_window_length(enb_id,i); */ - /* si_config->has_si_window_length = 1; */ - /* //TODO: Fill in with actual value, the number of SI messages */ - /* si_config->n_si_message=1; */ + cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i); + cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1; + Protocol__FlexSiConfig *si_config; + si_config = malloc(sizeof(Protocol__FlexSiConfig)); + if(si_config == NULL) + goto error; + protocol__flex_si_config__init(si_config); + + si_config->sfn = flexran_get_current_system_frame_num(mod_id); + si_config->has_sfn = 1; + + si_config->sib1_length = flexran_get_sib1_length(mod_id,i); + si_config->has_sib1_length = 1; + + si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, i); + si_config->has_si_window_length = 1; + + si_config->n_si_message = 0; + /* Protocol__FlexSiMessage **si_message; */ /* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */ /* if(si_message == NULL) */ @@ -2001,44 +904,42 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F /* if(si_config->n_si_message > 0){ */ /* si_config->si_message = si_message; */ /* } */ - /* cell_conf[i]->si_config = si_config; */ - - cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(enb_id,i); + + cell_conf[i]->si_config = si_config; + + cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i); cell_conf[i]->has_dl_bandwidth = 1; - cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(enb_id,i); + cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(mod_id,i); cell_conf[i]->has_ul_bandwidth = 1; - if (flexran_get_ul_cyclic_prefix_length(enb_id, i) == 0) { + if (flexran_get_ul_cyclic_prefix_length(mod_id, i) == 0) { cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL; - } else if(flexran_get_ul_cyclic_prefix_length(enb_id, i) == 1) { - cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED; + } else if(flexran_get_ul_cyclic_prefix_length(mod_id, i) == 1) { + cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED; } cell_conf[i]->has_ul_cyclic_prefix_length = 1; - if (flexran_get_ul_cyclic_prefix_length(enb_id,i) == 0) { + if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 0) { cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL; - } else if (flexran_get_ul_cyclic_prefix_length(enb_id,i) == 1) { + } else if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 1) { cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED; } cell_conf[i]->has_dl_cyclic_prefix_length = 1; - //TODO: Fill in with actual value, number of cell specific antenna ports. Currently single port support - cell_conf[i]->antenna_ports_count = 1; + cell_conf[i]->antenna_ports_count = flexran_get_antenna_ports(mod_id, i); cell_conf[i]->has_antenna_ports_count = 1; - if (flexran_get_duplex_mode(enb_id,i) == 1) { + if (flexran_get_duplex_mode(mod_id,i) == 1) { cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; - } else if(flexran_get_duplex_mode(enb_id,i) == 0) { + } else if(flexran_get_duplex_mode(mod_id,i) == 0) { cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; } cell_conf[i]->has_duplex_mode = 1; - //TODO: Fill in with actual value, DL/UL subframe assignment. TDD only - cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(enb_id, i); - cell_conf[i]->has_subframe_assignment = 0; - //TODO: Fill in with actual value, TDD only. See TS 36.211, table 4.2.1 - cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(enb_id,i); - cell_conf[i]->has_special_subframe_patterns = 0; + cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(mod_id, i); + cell_conf[i]->has_subframe_assignment = 1; + cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id,i); + cell_conf[i]->has_special_subframe_patterns = 1; //TODO: Fill in with actual value, The MBSFN radio frame period cell_conf[i]->n_mbsfn_subframe_config_rfperiod = 0; uint32_t *elem_rfperiod; @@ -2049,7 +950,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F elem_rfperiod[j] = 1; } cell_conf[i]->mbsfn_subframe_config_rfperiod = elem_rfperiod; - + //TODO: Fill in with actual value, The MBSFN radio frame offset cell_conf[i]->n_mbsfn_subframe_config_rfoffset = 0; uint32_t *elem_rfoffset; @@ -2060,7 +961,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F elem_rfoffset[j] = 1; } cell_conf[i]->mbsfn_subframe_config_rfoffset = elem_rfoffset; - + //TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes cell_conf[i]->n_mbsfn_subframe_config_sfalloc = 0; uint32_t *elem_sfalloc; @@ -2071,47 +972,62 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F elem_sfalloc[j] = 1; } cell_conf[i]->mbsfn_subframe_config_sfalloc = elem_sfalloc; - - cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(enb_id,i); + + cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(mod_id,i); cell_conf[i]->has_prach_config_index = 1; - cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(enb_id,i); + cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id,i); cell_conf[i]->has_prach_freq_offset = 1; - cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(enb_id,i); + cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id,i); cell_conf[i]->has_ra_response_window_size = 1; - cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(enb_id,i); + cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id,i); cell_conf[i]->has_mac_contention_resolution_timer = 1; - cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(enb_id,i); + cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id,i); cell_conf[i]->has_max_harq_msg3tx = 1; - cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(enb_id,i); + cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(mod_id,i); cell_conf[i]->has_n1pucch_an = 1; - cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(enb_id,i); + cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id,i); cell_conf[i]->has_deltapucch_shift = 1; - cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(enb_id,i); + cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(mod_id,i); cell_conf[i]->has_nrb_cqi = 1; - cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(enb_id,i); + cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id,i); cell_conf[i]->has_srs_subframe_config = 1; - cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(enb_id,i); + cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id,i); cell_conf[i]->has_srs_bw_config = 1; - cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(enb_id,i); + cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id,i); cell_conf[i]->has_srs_mac_up_pts = 1; - if (flexran_get_enable64QAM(enb_id,i) == 0) { + cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (mod_id,i); + cell_conf[i]->has_dl_freq = 1; + + cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (mod_id, i); + cell_conf[i]->has_ul_freq = 1; + + cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (mod_id,i); + cell_conf[i]->has_eutra_band = 1; + + cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id, i); + cell_conf[i]->has_dl_pdsch_power = 1; + + cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id,i); + cell_conf[i]->has_ul_pusch_power = 1; + + if (flexran_get_enable64QAM(mod_id,i) == 0) { cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; - } else if(flexran_get_enable64QAM(enb_id,i) == 1) { + } else if(flexran_get_enable64QAM(mod_id,i) == 1) { cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM; } cell_conf[i]->has_enable_64qam = 1; - + cell_conf[i]->carrier_index = i; cell_conf[i]->has_carrier_index = 1; } @@ -2140,191 +1056,39 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F } +int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { -/* - * timer primitives - */ + protocol_ctxt_t ctxt; + + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + Protocol__FlexRrcTriggering *triggering = input->rrc_triggering; -//struct flexran_agent_map agent_map; -flexran_agent_timer_instance_t timer_instance; -int agent_timer_init = 0; -err_code_t flexran_agent_init_timer(void){ + agent_reconf_rrc *reconf_param = malloc(sizeof(agent_reconf_rrc)); - LOG_I(FLEXRAN_AGENT, "init RB tree\n"); - if (!agent_timer_init) { - RB_INIT(&timer_instance.flexran_agent_head); - agent_timer_init = 1; - } - - return PROTOCOL__FLEXRAN_ERR__NO_ERR; -} -RB_GENERATE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); + reconf_param->trigger_policy = triggering->rrc_trigger; -/* The timer_id might not be the best choice for the comparison */ -int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b){ + struct rrc_eNB_ue_context_s *ue_context_p = NULL; - if (a->timer_id < b->timer_id) return -1; - if (a->timer_id > b->timer_id) return 1; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[mod_id]->rrc_ue_head)){ - // equal timers - return 0; -} -err_code_t flexran_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, - uint32_t timer_type, - xid_t xid, - flexran_agent_timer_callback_t cb, - void* timer_args, - long *timer_id){ - - struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); - DevAssert(e != NULL); - -//uint32_t timer_id; - int ret=-1; - - if ((interval_sec == 0) && (interval_usec == 0 )) - return TIMER_NULL; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id); - if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) - return TIMER_TYPE_INVALIDE; - - if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT){ - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - instance, - TIMER_ONE_SHOT, - timer_args, - timer_id); - - e->type = TIMER_ONE_SHOT; - } - else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ){ - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - instance, - TIMER_PERIODIC, - timer_args, - timer_id); - - e->type = TIMER_PERIODIC; - } - - if (ret < 0 ) { - return TIMER_SETUP_FAILED; - } - - e->agent_id = agent_id; - e->instance = instance; - e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE; - e->timer_id = *timer_id; - e->xid = xid; - e->timer_args = timer_args; - e->cb = cb; - /*element should be a real pointer*/ - RB_INSERT(flexran_agent_map, &timer_instance.flexran_agent_head, e); - - LOG_I(FLEXRAN_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n", - e->timer_id, e->agent_id, e->instance); - - return 0; -} - -err_code_t flexran_agent_destroy_timer(long timer_id){ - - struct flexran_agent_timer_element_s *e = get_timer_entry(timer_id); + flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0, reconf_param); - if (e != NULL ) { - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); } - if (timer_remove(timer_id) < 0 ) - goto error; + *msg = NULL; return 0; - - error: - LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); - return TIMER_REMOVED_FAILED ; -} - -err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid) { - struct flexran_agent_timer_element_s *e = NULL; - long timer_id; - RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { - if (e->xid == xid) { - timer_id = e->timer_id; - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); - if (timer_remove(timer_id) < 0 ) { - goto error; - } - } - } - return 0; - - error: - LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); - return TIMER_REMOVED_FAILED ; } -err_code_t flexran_agent_destroy_timers(void){ - - struct flexran_agent_timer_element_s *e = NULL; - - RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - timer_remove(e->timer_id); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); - } +int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg){ + // TODO return 0; - } -void flexran_agent_sleep_until(struct timespec *ts, int delay) { - ts->tv_nsec += delay; - if(ts->tv_nsec >= 1000*1000*1000){ - ts->tv_nsec -= 1000*1000*1000; - ts->tv_sec++; - } - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL); -} - - -err_code_t flexran_agent_stop_timer(long timer_id){ - - struct flexran_agent_timer_element_s *e=NULL; - struct flexran_agent_timer_element_s search; - memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); - search.timer_id = timer_id; - - e = RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); - - if (e != NULL ) { - e->state = FLEXRAN_AGENT_TIMER_STATE_STOPPED; - } - - timer_remove(timer_id); - - return 0; -} -struct flexran_agent_timer_element_s * get_timer_entry(long timer_id) { - - struct flexran_agent_timer_element_s search; - memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); - search.timer_id = timer_id; - return RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); -} diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index 7ab89acb4b1e4690b6ea6b1d3249427a9ecd853e..057c5b9489a7332a9cdb8923f3abeb58a44f7d46 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -21,8 +21,8 @@ /*! \file flexran_agent_common.h * \brief common message primitves and utilities - * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ @@ -37,11 +37,11 @@ #include "flexran.pb-c.h" #include "stats_messages.pb-c.h" #include "stats_common.pb-c.h" - +#include "flexran_agent_ran_api.h" +#include "flexran_agent_net_comm.h" #include "flexran_agent_defs.h" #include "enb_config.h" -#include "LAYER2/MAC/extern.h" #include "LAYER2/RLC/rlc.h" # include "tree.h" @@ -60,6 +60,19 @@ typedef int (*flexran_agent_message_destruction_callback)( Protocol__FlexranMessage *msg ); +typedef struct { + + uint8_t is_initialized; + volatile uint8_t cont_update; + xid_t xid; + Protocol__FlexranMessage *stats_req; + Protocol__FlexranMessage *prev_stats_reply; + + pthread_mutex_t *mutex; +} stats_updates_context_t; + +stats_updates_context_t stats_context[NUM_MAX_ENB]; + /********************************** * FlexRAN protocol messages helper * functions and generic handlers @@ -116,10 +129,6 @@ int flexran_agent_destroy_ue_config_request(Protocol__FlexranMessage *msg); /* TODO: Need to define and implement destructor */ int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg); -/* UE state change message constructor and destructor */ -int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change); -int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); - /* Control delegation message constructor and destructor */ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg); @@ -128,6 +137,11 @@ int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg); int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg); +/* rrc triggering measurement message constructor and destructor */ +int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); +int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg); + + /* FlexRAN protocol message dispatcher function */ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, uint8_t *data, @@ -136,367 +150,21 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, /* Function to be used to send a message to a dispatcher once the appropriate event is triggered. */ Protocol__FlexranMessage *flexran_agent_handle_timed_task(void *args); +/*Top level Statistics hanlder*/ +int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); +/* Function to be used to handle reply message . */ +int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg); +/* Top level Statistics request protocol message constructor and destructor */ +int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); +int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg); -/**************************** - * get generic info from RAN - ****************************/ - -void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran); - -int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag); - -/*Return the current frame number - *Could be using implementation specific numbering of frames - */ -unsigned int flexran_get_current_frame(mid_t mod_id); - -/*Return the current SFN (0-1023)*/ -unsigned int flexran_get_current_system_frame_num(mid_t mod_id); - -unsigned int flexran_get_current_subframe(mid_t mod_id); - -/*Return the frame and subframe number in compact 16-bit format. - Bits 0-3 subframe, rest for frame. Required by FlexRAN protocol*/ -uint16_t flexran_get_sfn_sf (mid_t mod_id); - -/* Return a future frame and subframe number that is ahead_of_time - subframes later in compact 16-bit format. Bits 0-3 subframe, - rest for frame */ -uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); - -/* Return the number of attached UEs */ -int flexran_get_num_ues(mid_t mod_id); - -/* Get the rnti of a UE with id ue_id */ -int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id); - -/* Get the RLC buffer status report of a ue for a designated - logical channel id */ -int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid); - -/* Get power headroom of UE with id ue_id */ -int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id); - -/* Get the UE wideband CQI */ -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) */ -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); - -/* Get the number of active component carriers for a specific UE */ -int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); - -/* Get the rank indicator for a designated cell and UE */ -int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id); - -/* See TS 36.213, section 10.1 */ -int flexran_get_n1pucch_an(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.4 */ -int flexran_get_nRB_CQI(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.4 */ -int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.7.1 */ -int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.7.1 */ -int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id); - -/* See TS 36.321 */ -int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id); - -/* Get the length of the UL cyclic prefix */ -int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id); - -/* Get the length of the DL cyclic prefix */ -int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id); - -/* Get the physical cell id of a cell */ -int flexran_get_cell_id(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.5.3.2 */ -int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id); - -/* See TS 36.211, table 5.5.3.3-1 and 2 */ -int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id); - -/* Boolean value. See TS 36.211, - section 5.5.3.2. TDD only */ -int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id); - -/* Get number of DL resource blocks */ -int flexran_get_N_RB_DL(mid_t mod_id, int CC_id); - -/* Get number of UL resource blocks */ -int flexran_get_N_RB_UL(mid_t mod_id, int CC_id); - -/* Get number of resource block groups */ -int flexran_get_N_RBG(mid_t mod_id, int CC_id); - -/* Get DL/UL subframe assignment. TDD only */ -int flexran_get_subframe_assignment(mid_t mod_id, int CC_id); - -/* TDD only. See TS 36.211, table 4.2.1 */ -int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id); - -/* Get the duration of the random access response window in subframes */ -int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id); - -/* Get timer used for random access */ -int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id); - -/* Get type of duplex mode (FDD/TDD) */ -int flexran_get_duplex_mode(mid_t mod_id, int CC_id); - -/* Get the SI window length */ -long flexran_get_si_window_length(mid_t mod_id, int CC_id); - -/* Get the number of PDCCH symbols configured for the cell */ -int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id); - -/* See TS 36.213, sec 5.1.1.1 */ -int flexran_get_tpc(mid_t mod_id, mid_t ue_id); - -/* Get the first available HARQ process for a specific cell and UE during - a designated frame and subframe. Returns 0 for success. The id and the - status of the HARQ process are stored in id and status respectively */ -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); - -/* Uplink power control management*/ -int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id); - -int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id); - -int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id); - -int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id); - - -/* - * ************************************ - * Get Messages for UE Configuration Reply - * ************************************ - */ - -/* Get timer in subframes. Controls the synchronization - status of the UE, not the actual timing - advance procedure. See TS 36.321 */ -int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); - -/* Get measurement gap configuration. See TS 36.133 */ -int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); - -/* Get measurement gap configuration offset if applicable */ -int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); - -/* DL aggregated bit-rate of non-gbr bearer - per UE. See TS 36.413 */ -int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id); - -/* UL aggregated bit-rate of non-gbr bearer - per UE. See TS 36.413 */ -int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id); - -/* Only half-duplex support. FDD - operation. Boolean value */ -int flexran_get_half_duplex(mid_t ue_id); - -/* Support of intra-subframe hopping. - Boolean value */ -int flexran_get_intra_sf_hopping(mid_t ue_id); - -/* UE support for type 2 hopping with - n_sb>1 */ -int flexran_get_type2_sb_1(mid_t ue_id); - -/* Get the UE category */ -int flexran_get_ue_category(mid_t ue_id); - -/* UE support for resource allocation - type 1 */ -int flexran_get_res_alloc_type1(mid_t ue_id); - -/* Get UE transmission mode */ -int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); - -/* Boolean value. See TS 36.321 */ -int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id); - -/* The max HARQ retransmission for UL. - See TS 36.321 */ -int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); - -/* See TS 36.213 */ -int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); - -/* See TS 36.213 */ -int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); - -/* See TS 36.213 */ -int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); - -/* Boolean. See TS36.213, Section 10.1 */ -int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); - -/* Boolean. See TS 36.213, Section 8.2 */ -int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id); - -/* Get aperiodic CQI report mode */ -int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); - -/* Get ACK/NACK feedback mode. TDD only */ -int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id); - -/* See TS36.213, section 10.1 */ -int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); - -/* Boolean. Extended buffer status report size */ -int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); - -/* Get number of UE transmission antennas */ -int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); - -/* Get logical channel group of a channel with id lc_id */ -int flexran_get_lcg(mid_t ue_id, mid_t lc_id); - -/* Get direction of logical channel with id lc_id */ -int flexran_get_direction(mid_t ue_id, mid_t lc_id); - -/******************* - * timer primitves - *******************/ - -#define TIMER_NULL -1 -#define TIMER_TYPE_INVALIDE -2 -#define TIMER_SETUP_FAILED -3 -#define TIMER_REMOVED_FAILED -4 -#define TIMER_ELEMENT_NOT_FOUND -5 - - -/* Type of the callback executed when the timer expired */ -typedef Protocol__FlexranMessage *(*flexran_agent_timer_callback_t)(void*); - -typedef enum { - /* oneshot timer: */ - FLEXRAN_AGENT_TIMER_TYPE_ONESHOT = 0x0, - - /* periodic timer */ - FLEXRAN_AGENT_TIMER_TYPE_PERIODIC = 0x1, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_TYPE_EVENT_DRIVEN = 0x2, - - /* Max number of states available */ - FLEXRAN_AGENT_TIMER_TYPE_MAX, -} flexran_agent_timer_type_t; - -typedef enum { - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_INACTIVE = 0x0, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_ACTIVE = 0x1, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_STOPPED = 0x2, - - /* Max number of states available */ - FLEXRAN_AGENT_TIMER_STATE_MAX, -} flexran_agent_timer_state_t; - -typedef struct flexran_agent_timer_args_s{ - mid_t mod_id; - Protocol__FlexranMessage *msg; -} flexran_agent_timer_args_t; - - - -typedef struct flexran_agent_timer_element_s{ - RB_ENTRY(flexran_agent_timer_element_s) entry; - - agent_id_t agent_id; - instance_t instance; - - flexran_agent_timer_type_t type; - flexran_agent_timer_state_t state; - - uint32_t interval_sec; - uint32_t interval_usec; - - long timer_id; /* Timer id returned by the timer API*/ - xid_t xid; /*The id of the task as received by the controller - message*/ - - flexran_agent_timer_callback_t cb; - flexran_agent_timer_args_t *timer_args; - -} flexran_agent_timer_element_t; - -typedef struct flexran_agent_timer_instance_s{ - RB_HEAD(flexran_agent_map, flexran_agent_timer_element_s) flexran_agent_head; -}flexran_agent_timer_instance_t; - - -err_code_t flexran_agent_init_timer(void); - -/* Create a timer for some agent related event with id xid. Will store the id - of the generated timer in timer_id */ -err_code_t flexran_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, - uint32_t timer_type, - xid_t xid, - flexran_agent_timer_callback_t cb, - void* timer_args, - long *timer_id); - -/* Destroy all existing timers */ -err_code_t flexran_agent_destroy_timers(void); - -/* Destroy the timer with the given timer_id */ -err_code_t flexran_agent_destroy_timer(long timer_id); - -/* Destroy the timer for task with id xid */ -err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid); - -/* Stop a timer */ -err_code_t flexran_agent_stop_timer(long timer_id); - -/* Restart the given timer */ -err_code_t flexran_agent_restart_timer(long *timer_id); - -/* Find the timer with the given timer_id */ -struct flexran_agent_timer_element_s * get_timer_entry(long timer_id); - -/* Obtain the protocol message stored in the given expired timer */ -Protocol__FlexranMessage * flexran_agent_process_timeout(long timer_id, void* timer_args); - -/* Comparator function comparing two timers. Decides the ordering of the timers */ -int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b); - -/*Specify a delay in nanoseconds to timespec and sleep until then*/ -void flexran_agent_sleep_until(struct timespec *ts, int delay); +err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id); -/* RB_PROTOTYPE is for .h files */ -RB_PROTOTYPE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); +void flexran_agent_send_update_stats(mid_t mod_id); +err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ; +err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id); #endif diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 240856b948254f45d558848a0050b1720595b2f2..8874a0f64852f06ac619ba4eed39e7d02fe292ec 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -21,8 +21,8 @@ /*! \file flexran_agent_common_internal.c * \brief internal functions for common message primitves and utilities - * \author Xenofon Foukas - * \date 2016 + * \author Xenofon Foukas and N. Nikaein + * \date 2017 * \version 0.1 */ @@ -32,6 +32,57 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" +/* needed to soft-restart the lte-softmodem */ +#include "targets/RT/USER/lte-softmodem.h" + +void handle_reconfiguration(mid_t mod_id) +{ + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC, &start); + flexran_agent_info_t *flexran = RC.flexran[mod_id]; + + if (ENB_WAIT == flexran->node_ctrl_state) { + /* this is already waiting, just release */ + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_NORMAL_OPERATION; + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + pthread_cond_signal(&flexran->cond_node_ctrl); + return; + } + + if (stop_L1L2(mod_id) < 0) { + LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); + return; + } + + /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not + * executed by the FlexRAN thread */ + if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_WAIT; + while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) + pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + } + + if (restart_L1L2(mod_id) < 0) { + LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); + itti_terminate_tasks(TASK_PHY_ENB); + return; + } + + clock_gettime(CLOCK_MONOTONIC, &end); + end.tv_sec -= start.tv_sec; + if (end.tv_nsec >= start.tv_nsec) { + end.tv_nsec -= start.tv_nsec; + } else { + end.tv_sec -= 1; + end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; + } + LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); +} + int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { yaml_parser_t parser; @@ -64,7 +115,17 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy break; case YAML_SCALAR_EVENT: // Check the system name and call the proper handler - if (strcmp((char *) event.data.scalar.value, "mac") == 0) { + // Check the system name and call the proper handler + if (strcmp((char *) event.data.scalar.value, "enb") == 0) { + LOG_I(ENB_APP, "This is intended for the enb system\n"); + // Call the enb handler + if (parse_enb_id(mod_id, &parser) == -1) { + LOG_E(ENB_APP, "cannot parse data for eNB\n"); + goto error; + } else { // succeful parse and setting + handle_reconfiguration(mod_id); + } + } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) { LOG_D(ENB_APP, "This is intended for the mac system\n"); // Call the mac handler if (parse_mac_config(mod_id, &parser) == -1) { @@ -90,8 +151,8 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy // TODO : Just skip it for now if (skip_system_section(&parser) == -1) { goto error; - } - } else { + } + } else { goto error; } break; @@ -115,6 +176,145 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy } +int parse_enb_id(mid_t mod_id, yaml_parser_t *parser) { + yaml_event_t event; + + char *endptr; + // int is_array; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping of parameters + case YAML_SEQUENCE_START_EVENT: + // is_array = 1; + break; + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + // use eNB egistered + if (mac_agent_registered[mod_id]) { + LOG_I(ENB_APP, "Setting parameter for eNB %s\n", event.data.scalar.value); + if (strcmp((char *) event.data.scalar.tag, YAML_INT_TAG) == 0) { // if int + if ((strtol((char *) event.data.scalar.value, &endptr, 10))== mod_id ) { // enb_id == mod_id: right enb instance to be configured + if (parse_enb_config_parameters(mod_id, parser) == -1) { + goto error; + } + } + else{ + goto error; // not the expected type + } + } + } + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + +int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { + yaml_event_t event; + + char *endptr; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping of parameters + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + if (strcmp((char *) event.data.scalar.value, "dl_freq") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_dl_freq(mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting dl_freq to %s\n", event.data.scalar.value); + } else if (strcmp((char *) event.data.scalar.value, "ul_freq_offset") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_ul_freq(mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting ul_freq_offset to %s\n", event.data.scalar.value); + } else if (strcmp((char *) event.data.scalar.value, "bandwidth") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_bandwidth(mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting bandwidth to %s\n", event.data.scalar.value); + } else if (strcmp((char *) event.data.scalar.value, "frame_type") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_frame_type (mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting frame_type to %s\n", event.data.scalar.value); + }else { // not supported tag + LOG_E(FLEXRAN_AGENT, "Unsupported tag %s\n", event.data.scalar.value); + goto error; + } + + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + int skip_system_section(yaml_parser_t *parser) { yaml_event_t event; diff --git a/openair2/ENB_APP/flexran_agent_common_internal.h b/openair2/ENB_APP/flexran_agent_common_internal.h index d91c2dc7f6578db33ece11dfeb642ea701c35ae9..bf908ac13232b8743c72411481a8be649d884519 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.h +++ b/openair2/ENB_APP/flexran_agent_common_internal.h @@ -21,8 +21,8 @@ /*! \file flexran_agent_common_internal.h * \brief internal agent functions for common message primitves and utilities - * \author Xenofon Foukas - * \date 2016 + * \author Xenofon Foukas and N. Nikaein + * \date 2017 * \version 0.1 */ @@ -37,6 +37,10 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy int apply_parameter_modification(void *parameter, yaml_parser_t *parser); +int parse_enb_id(mid_t mod_id, yaml_parser_t *parser); +int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) ; + + // This can be used when parsing for a specific system that is not yet implmeneted // in order to skip its configuration, without affecting the rest int skip_system_section(yaml_parser_t *parser); diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 12e3c56dffa16ffeb71a8141bf0499e8db585bba..aa71dd33fab750e933a0d86ab1b1ab43f28c5a43 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -21,8 +21,8 @@ /*! \file flexran_agent_defs.h * \brief FlexRAN agent common definitions - * \author Navid Nikaein and Xenofon Foukas - * \date 2016 + * \author Navid Nikaein and Xenofon Foukas and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ #ifndef FLEXRAN_AGENT_DEFS_H_ @@ -32,11 +32,16 @@ #include <stdlib.h> #include <pthread.h> #include <string.h> +#include <stdbool.h> +#include <time.h> #include "link_manager.h" #define NUM_MAX_ENB 2 +#define NUM_MAX_DRB 8 +#define NUM_MAX_SRB 3 #define NUM_MAX_UE 2048 +#define DEFAULT_DRB 3 #define DEFAULT_FLEXRAN_AGENT_IPv4_ADDRESS "127.0.0.1" #define DEFAULT_FLEXRAN_AGENT_PORT 2210 #define DEFAULT_FLEXRAN_AGENT_CACHE "/mnt/oai_agent_cache" @@ -102,10 +107,69 @@ typedef uint8_t lcid_t; typedef int32_t err_code_t; +/*---------Timer Enums --------- */ + +typedef enum { + /* oneshot timer: */ + FLEXRAN_AGENT_TIMER_TYPE_ONESHOT = 0, + + /* periodic timer */ + FLEXRAN_AGENT_TIMER_TYPE_PERIODIC = 1, + + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_TYPE_EVENT_DRIVEN = 2, + + /* Max number of states available */ + FLEXRAN_AGENT_TIMER_TYPE_MAX, +} flexran_agent_timer_type_t; + + +typedef enum { + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_STATE_INACTIVE = 0x0, + + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_STATE_ACTIVE = 0x1, + + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_STATE_STOPPED = 0x2, + + /* Max number of states available */ + FLEXRAN_AGENT_TIMER_STATE_MAX, +} flexran_agent_timer_state_t; + +#define FLEXRAN_CAP_LOPHY 1 +#define FLEXRAN_CAP_HIPHY 2 +#define FLEXRAN_CAP_LOMAC 4 +#define FLEXRAN_CAP_HIMAC 8 +#define FLEXRAN_CAP_RLC 16 +#define FLEXRAN_CAP_PDCP 32 +#define FLEXRAN_CAP_SDAP 64 +#define FLEXRAN_CAP_RRC 128 + +typedef enum { + ENB_NORMAL_OPERATION = 0x0, + ENB_WAIT = 0x1, + ENB_MAKE_WAIT = 0x2, +} flexran_enb_state_t; typedef struct { /* general info */ - + int enabled; + char *interface_name; + char *remote_ipv4_addr; + uint16_t remote_port; + char *cache_name; + + mid_t mod_id; + uint64_t agent_id; + uint8_t capability_mask; + + /* lock for waiting before starting or soft-restart */ + pthread_cond_t cond_node_ctrl; + pthread_mutex_t mutex_node_ctrl; + flexran_enb_state_t node_ctrl_state; + /* stats */ uint32_t total_rx_msg; @@ -116,10 +180,51 @@ typedef struct { } flexran_agent_info_t; + +/* +rrc triggering + */ + + typedef struct { - mid_t enb_id; - flexran_agent_info_t agent_info; - -} flexran_agent_instance_t; + char * trigger_policy; + uint32_t report_interval; + uint32_t report_amount; + +} agent_reconf_rrc; + + +/* These structs will be used to give + instructions for the type of stats reports + we need to create */ + + +typedef struct { + uint16_t ue_rnti; + uint32_t ue_report_flags; /* Indicates the report elements + required for this UE id. See + FlexRAN specification 1.2.4.2 */ +} ue_report_type_t; + +typedef struct { + uint16_t cc_id; + uint32_t cc_report_flags; /* Indicates the report elements + required for this CC index. See + FlexRAN specification 1.2.4.3 */ +} cc_report_type_t; + +typedef struct { + int nr_ue; + ue_report_type_t *ue_report_type; + int nr_cc; + cc_report_type_t *cc_report_type; +} report_config_t; + +typedef struct stats_request_config_s{ + uint8_t report_type; + uint8_t report_frequency; + uint16_t period; /*In number of subframes*/ + report_config_t *config; +} stats_request_config_t; #endif diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index 6237f78367cad368d6115e42f7b6e02cdae88f75..ae77e9227aa960afa13823ff9fe67996253d356a 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -20,9 +20,9 @@ */ /*! \file ENB_APP/extern.h - * \brief FlexRAN agent - mac interface primitives - * \author Xenofon Foukas - * \date 2016 + * \brief FlexRAN agent - Extern VSF xfaces + * \author Xenofon Foukas and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 * \mail x.foukas@sms.ed.ac.uk */ @@ -32,12 +32,8 @@ #include "flexran_agent_defs.h" #include "flexran_agent_mac_defs.h" - - -//extern msg_context_t shared_ctxt[NUM_MAX_ENB][FLEXRAN_AGENT_MAX]; - -/* full path of the local cache for storing VSFs */ -extern char local_cache[40]; +#include "flexran_agent_rrc_defs.h" +#include "flexran_agent_pdcp_defs.h" /* Control module interface for the communication of the MAC Control Module with the agent */ extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; @@ -45,8 +41,20 @@ 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]; +/* Control module interface for the communication of the RRC Control Module with the agent */ +extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; + +/* Flag indicating whether the VSFs for the RRC control module have been registered */ +extern unsigned int rrc_agent_registered[NUM_MAX_ENB]; + +/* Control module interface for the communication of the RRC Control Module with the agent */ +extern AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB]; + +/* Flag indicating whether the VSFs for the RRC control module have been registered */ +extern unsigned int pdcp_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]; +extern int harq_pid_updated[NUM_MAX_UE][8]; +extern int harq_pid_round[NUM_MAX_UE][8]; #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 51188bea86216a8ce6640e396d31bdae1046ea45..6c20c635a19365df6e6541306c88b2ab0fbe57c2 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -21,14 +21,18 @@ /*! \file flexran_agent_handler.c * \brief FlexRAN agent tx and rx message handler - * \author Xenofon Foukas and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas and Navid Nikaein and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ - +#include "flexran_agent_defs.h" #include "flexran_agent_common.h" #include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" +#include "flexran_agent_pdcp.h" +#include "flexran_agent_timer.h" +#include "flexran_agent_ran_api.h" #include "log.h" #include "assertions.h" @@ -37,7 +41,7 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = { {flexran_agent_hello, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG*/ {flexran_agent_echo_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG*/ //Must add handler when receiving echo reply - {flexran_agent_mac_handle_stats, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/ + {flexran_agent_handle_stats, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG*/ {0, 0, 0}, /*PROTOCOK__FLEXRAN_MESSAGE__MSG_SF_TRIGGER_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG*/ @@ -51,13 +55,14 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = { {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG*/ {flexran_agent_control_delegation, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_CONTROL_DELEGATION_MSG*/ {flexran_agent_reconfiguration, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_AGENT_RECONFIGURATION_MSG*/ + {flexran_agent_rrc_measurement, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_RRC_TRIGGERING_MSG*/ }; flexran_agent_message_destruction_callback message_destruction_callback[] = { flexran_agent_destroy_hello, flexran_agent_destroy_echo_request, flexran_agent_destroy_echo_reply, - flexran_agent_mac_destroy_stats_request, + flexran_agent_destroy_stats_request, flexran_agent_mac_destroy_stats_reply, flexran_agent_mac_destroy_sf_trigger, flexran_agent_mac_destroy_sr_info, @@ -93,7 +98,6 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, err_code= PROTOCOL__FLEXRAN_ERR__MSG_DECODING; goto error; } - if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3 * sizeof(flexran_agent_message_decoded_callback))) || (decoded_message->msg_dir > PROTOCOL__FLEXRAN_DIRECTION__UNSUCCESSFUL_OUTCOME)){ err_code= PROTOCOL__FLEXRAN_ERR__MSG_NOT_HANDLED; @@ -139,7 +143,7 @@ void * flexran_agent_pack_message(Protocol__FlexranMessage *msg, DevAssert(buffer !=NULL); - LOG_D(FLEXRAN_AGENT,"Serilized the enb mac stats reply (size %d)\n", *size); + LOG_D(FLEXRAN_AGENT,"Serilized the eNB-UE stats reply (size %d)\n", *size); return buffer; @@ -187,3 +191,587 @@ Protocol__FlexranMessage* flexran_agent_process_timeout(long timer_id, void* tim err_code_t flexran_agent_destroy_flexran_message(Protocol__FlexranMessage *msg) { return ((*message_destruction_callback[msg->msg_case-1])(msg)); } + + +/* + Top Level Statistics Report + + */ + + + +int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg){ + + // TODO: Must deal with sanitization of input + // TODO: Must check if RNTIs and cell ids of the request actually exist + // TODO: Must resolve conflicts among stats requests + + int i; + err_code_t err_code; + xid_t xid; + uint32_t usec_interval, sec_interval; + + //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 + int enb_id = mod_id; + + //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; + //UE_list_t *eNB_UE_list= &eNB->UE_list; + + report_config_t report_config; + + uint32_t ue_flags = 0; + uint32_t c_flags = 0; + + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + + Protocol__FlexStatsRequest *stats_req = input->stats_request_msg; + xid = (stats_req->header)->xid; + + // Check the type of request that is made + switch(stats_req->body_case) { + case PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ; + Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request; + if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF) { + /*Disable both periodic and continuous updates*/ + // flexran_agent_disable_cont_stats_update(mod_id); + flexran_agent_destroy_timer_by_task_id(xid); + *msg = NULL; + return 0; + } else { //One-off, periodical or continuous reporting + //Set the proper flags + ue_flags = comp_req->ue_report_flags; + c_flags = comp_req->cell_report_flags; + //Create a list of all eNB RNTIs and cells + + //Set the number of UEs and create list with their RNTIs stats configs + report_config.nr_ue = flexran_get_num_ues(mod_id); //eNB_UE_list->num_UEs + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_ue; i++) { + report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; + report_config.ue_report_type[i].ue_report_flags = ue_flags; + } + //Set the number of CCs and create a list with the cell stats configs + report_config.nr_cc = MAX_NUM_CCs; + report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); + if (report_config.cc_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_cc; i++) { + //TODO: Must fill in the proper cell ids + report_config.cc_report_type[i].cc_id = i; + report_config.cc_report_type[i].cc_report_flags = c_flags; + } + /* Check if request was periodical */ + if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) { + /* Create a one off flexran message as an argument for the periodical task */ + Protocol__FlexranMessage *timer_msg; + stats_request_config_t request_config; + request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; + request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; + request_config.period = 0; + /* Need to make sure that the ue flags are saved (Bug) */ + if (report_config.nr_ue == 0) { + report_config.nr_ue = 1; + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + report_config.ue_report_type[0].ue_rnti = 0; // Dummy value + report_config.ue_report_type[0].ue_report_flags = ue_flags; + } + request_config.config = &report_config; + flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg); + /* Create a timer */ + long timer_id = 0; + flexran_agent_timer_args_t *timer_args; + timer_args = malloc(sizeof(flexran_agent_timer_args_t)); + memset (timer_args, 0, sizeof(flexran_agent_timer_args_t)); + timer_args->mod_id = enb_id; + timer_args->msg = timer_msg; + /*Convert subframes to usec time*/ + usec_interval = 1000*comp_req->sf; + sec_interval = 0; + /*add seconds if required*/ + if (usec_interval >= 1000*1000) { + sec_interval = usec_interval/(1000*1000); + usec_interval = usec_interval%(1000*1000); + } + flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, flexran_agent_handle_timed_task,(void*) timer_args, &timer_id); + } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) { + /*If request was for continuous updates, disable the previous configuration and + set up a new one*/ + flexran_agent_disable_cont_stats_update(mod_id); + stats_request_config_t request_config; + request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; + request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; + request_config.period = 0; + /* Need to make sure that the ue flags are saved (Bug) */ + if (report_config.nr_ue == 0) { + report_config.nr_ue = 1; + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + report_config.ue_report_type[0].ue_rnti = 0; // Dummy value + report_config.ue_report_type[0].ue_report_flags = ue_flags; + } + request_config.config = &report_config; + flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config); + } + } + break; + case PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST:; + Protocol__FlexCellStatsRequest *cell_req = stats_req->cell_stats_request; + // UE report config will be blank + report_config.nr_ue = 0; + report_config.ue_report_type = NULL; + report_config.nr_cc = cell_req->n_cell; + report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); + if (report_config.cc_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_cc; i++) { + //TODO: Must fill in the proper cell ids + report_config.cc_report_type[i].cc_id = cell_req->cell[i]; + report_config.cc_report_type[i].cc_report_flags = cell_req->flags; + } + break; + case PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST:; + Protocol__FlexUeStatsRequest *ue_req = stats_req->ue_stats_request; + // Cell report config will be blank + report_config.nr_cc = 0; + report_config.cc_report_type = NULL; + report_config.nr_ue = ue_req->n_rnti; + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_ue; i++) { + report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i]; + report_config.ue_report_type[i].ue_report_flags = ue_req->flags; + } + break; + default: + //TODO: Add appropriate error code + err_code = -100; + goto error; + } + + if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )){ + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + free(report_config.ue_report_type); + free(report_config.cc_report_type); + + return 0; + + error : + LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code); + return err_code; +} + +/* + Top level reply + */ + +int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg){ + + Protocol__FlexHeader *header = NULL; + err_code_t err_code; + int i; + + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) + goto error; + + + Protocol__FlexStatsReply *stats_reply_msg; + + stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); + + if (stats_reply_msg == NULL) + goto error; + + protocol__flex_stats_reply__init(stats_reply_msg); + stats_reply_msg->header = header; + + stats_reply_msg->n_ue_report = report_config->nr_ue; + stats_reply_msg->n_cell_report = report_config->nr_cc; + + // UE report + + Protocol__FlexUeStatsReport **ue_report; + + + ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * report_config->nr_ue); + if (ue_report == NULL) + goto error; + + for (i = 0; i < report_config->nr_ue; i++) { + + ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); + protocol__flex_ue_stats_report__init(ue_report[i]); + ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; + ue_report[i]->has_rnti = 1; + ue_report[i]->flags = report_config->ue_report_type[i].ue_report_flags; + ue_report[i]->has_flags = 1; + + } + + // cell rpoert + + Protocol__FlexCellStatsReport **cell_report; + + + cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * report_config->nr_cc); + if (cell_report == NULL) + goto error; + + for (i = 0; i < report_config->nr_cc; i++) { + + cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); + if(cell_report[i] == NULL) + goto error; + + protocol__flex_cell_stats_report__init(cell_report[i]); + cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id; + cell_report[i]->has_carrier_index = 1; + cell_report[i]->flags = report_config->cc_report_type[i].cc_report_flags; + cell_report[i]->has_flags = 1; + + } + + /* + MAC reply split + */ + + + if (flexran_agent_mac_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + /* + RRC reply split + */ + + if (flexran_agent_rrc_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + + /* + PDCP reply split + */ + + if (flexran_agent_pdcp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + + stats_reply_msg->cell_report = cell_report; + stats_reply_msg->ue_report = ue_report; + + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) + goto error; + protocol__flexran_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; + (*msg)->stats_reply_msg = stats_reply_msg; + + return 0; + +error : + LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code); + return err_code; + +} + +/* + Top Level Request + */ + +int flexran_agent_stats_request(mid_t mod_id, + xid_t xid, + const stats_request_config_t *report_config, + Protocol__FlexranMessage **msg) { + Protocol__FlexHeader *header = NULL; + int i; + + Protocol__FlexStatsRequest *stats_request_msg; + stats_request_msg = malloc(sizeof(Protocol__FlexStatsRequest)); + if(stats_request_msg == NULL) + goto error; + protocol__flex_stats_request__init(stats_request_msg); + + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REQUEST, &header) != 0) + goto error; + + stats_request_msg->header = header; + + stats_request_msg->type = report_config->report_type; + stats_request_msg->has_type = 1; + + switch (report_config->report_type) { + case PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS: + stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST; + Protocol__FlexCompleteStatsRequest *complete_stats; + complete_stats = malloc(sizeof(Protocol__FlexCompleteStatsRequest)); + if(complete_stats == NULL) + goto error; + protocol__flex_complete_stats_request__init(complete_stats); + complete_stats->report_frequency = report_config->report_frequency; + complete_stats->has_report_frequency = 1; + complete_stats->sf = report_config->period; + complete_stats->has_sf = 1; + complete_stats->has_cell_report_flags = 1; + complete_stats->has_ue_report_flags = 1; + if (report_config->config->nr_cc > 0) { + complete_stats->cell_report_flags = report_config->config->cc_report_type[0].cc_report_flags; + } + if (report_config->config->nr_ue > 0) { + complete_stats->ue_report_flags = report_config->config->ue_report_type[0].ue_report_flags; + } + stats_request_msg->complete_stats_request = complete_stats; + break; + case PROTOCOL__FLEX_STATS_TYPE__FLST_CELL_STATS: + stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST; + Protocol__FlexCellStatsRequest *cell_stats; + cell_stats = malloc(sizeof(Protocol__FlexCellStatsRequest)); + if(cell_stats == NULL) + goto error; + protocol__flex_cell_stats_request__init(cell_stats); + cell_stats->n_cell = report_config->config->nr_cc; + cell_stats->has_flags = 1; + if (cell_stats->n_cell > 0) { + uint32_t *cells; + cells = (uint32_t *) malloc(sizeof(uint32_t)*cell_stats->n_cell); + for (i = 0; i < cell_stats->n_cell; i++) { + cells[i] = report_config->config->cc_report_type[i].cc_id; + } + cell_stats->cell = cells; + cell_stats->flags = report_config->config->cc_report_type[i].cc_report_flags; + } + stats_request_msg->cell_stats_request = cell_stats; + break; + case PROTOCOL__FLEX_STATS_TYPE__FLST_UE_STATS: + stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST; + Protocol__FlexUeStatsRequest *ue_stats; + ue_stats = malloc(sizeof(Protocol__FlexUeStatsRequest)); + if(ue_stats == NULL) + goto error; + protocol__flex_ue_stats_request__init(ue_stats); + ue_stats->n_rnti = report_config->config->nr_ue; + ue_stats->has_flags = 1; + if (ue_stats->n_rnti > 0) { + uint32_t *ues; + ues = (uint32_t *) malloc(sizeof(uint32_t)*ue_stats->n_rnti); + for (i = 0; i < ue_stats->n_rnti; i++) { + ues[i] = report_config->config->ue_report_type[i].ue_rnti; + } + ue_stats->rnti = ues; + ue_stats->flags = report_config->config->ue_report_type[i].ue_report_flags; + } + stats_request_msg->ue_stats_request = ue_stats; + break; + default: + goto error; + } + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) + goto error; + protocol__flexran_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + (*msg)->stats_request_msg = stats_request_msg; + return 0; + + error: + // TODO: Need to make proper error handling + if (header != NULL) + free(header); + if (stats_request_msg != NULL) + free(stats_request_msg); + if(*msg != NULL) + free(*msg); + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG) + goto error; + free(msg->stats_request_msg->header); + if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST) { + free(msg->stats_request_msg->cell_stats_request->cell); + } + if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST) { + free(msg->stats_request_msg->ue_stats_request->rnti); + } + free(msg->stats_request_msg); + free(msg); + return 0; + + error: + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +/* + Top Level Update + */ + +void flexran_agent_send_update_stats(mid_t mod_id) { + + Protocol__FlexranMessage *current_report = NULL; + void *data; + int size; + err_code_t err_code; + int priority = 0; + + if (pthread_mutex_lock(stats_context[mod_id].mutex)) { + goto error; + } + + if (stats_context[mod_id].cont_update == 1) { + + /*Create a fresh report with the required flags*/ + err_code = flexran_agent_handle_stats(mod_id, (void *) stats_context[mod_id].stats_req, ¤t_report); + if (err_code < 0) { + goto error; + } + } + /* /\*TODO:Check if a previous reports exists and if yes, generate a report */ + /* *that is the diff between the old and the new report, */ + /* *respecting the thresholds. Otherwise send the new report*\/ */ + /* if (stats_context[mod_id].prev_stats_reply != NULL) { */ + + /* msg = flexran_agent_generate_diff_mac_stats_report(current_report, stats_context[mod_id].prev_stats_reply); */ + + /* /\*Destroy the old stats*\/ */ + /* flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); */ + /* } */ + /* /\*Use the current report for future comparissons*\/ */ + /* stats_context[mod_id].prev_stats_reply = current_report; */ + + + if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { + goto error; + } + + if (current_report != NULL){ + data=flexran_agent_pack_message(current_report, &size); + /*Send any stats updates using the MAC channel of the eNB*/ + if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; + goto error; + } + + LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); + return; + } + error: + LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n"); +} + +err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id) { + /*Disable the continuous updates for the MAC*/ + if (pthread_mutex_lock(stats_context[mod_id].mutex)) { + goto error; + } + stats_context[mod_id].cont_update = 0; + stats_context[mod_id].xid = 0; + if (stats_context[mod_id].stats_req != NULL) { + flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req); + } + if (stats_context[mod_id].prev_stats_reply != NULL) { + flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); + } + if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { + goto error; + } + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id); + return -1; + +} + +err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, + xid_t xid, stats_request_config_t *stats_req) { + + if (pthread_mutex_lock(stats_context[mod_id].mutex)) { + goto error; + } + + Protocol__FlexranMessage *req_msg; + + flexran_agent_stats_request(mod_id, xid, stats_req, &req_msg); + stats_context[mod_id].stats_req = req_msg; + stats_context[mod_id].prev_stats_reply = NULL; + + stats_context[mod_id].cont_update = 1; + stats_context[mod_id].xid = xid; + + if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { + goto error; + } + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id); + return -1; +} + + +err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) { + + + /*Initially the continuous update is set to false*/ + stats_context[mod_id].cont_update = 0; + stats_context[mod_id].is_initialized = 1; + stats_context[mod_id].stats_req = NULL; + stats_context[mod_id].prev_stats_reply = NULL; + stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t)); + if (stats_context[mod_id].mutex == NULL) + goto error; + if (pthread_mutex_init(stats_context[mod_id].mutex, NULL)) + goto error; + + return 0; + + error: + return -1; +} + +err_code_t flexran_agent_destroy_cont_stats_update(mid_t mod_id) { + + stats_context[mod_id].cont_update = 0; + stats_context[mod_id].is_initialized = 0; + flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req); + flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); + free(stats_context[mod_id].mutex); + + // mac_agent_registered[mod_id] = 0; + return 1; +} diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c index e6442512095963885e6361f7a3c7595d7dd0b9b9..6971c2975048fae72be383fa2a9ab38d00fe7579 100644 --- a/openair2/ENB_APP/flexran_agent_net_comm.c +++ b/openair2/ENB_APP/flexran_agent_net_comm.c @@ -118,7 +118,7 @@ int flexran_agent_create_channel(void *channel_info, /*element should be a real pointer*/ RB_INSERT(flexran_agent_channel_map, &channel_instance.flexran_agent_head, channel); - LOG_I(FLEXRAN_AGENT,"Created a new channel with id 0x%lx\n", channel->channel_id); + LOG_I(FLEXRAN_AGENT,"Created a new channel with id %d \n", channel->channel_id); return channel_id; } @@ -141,9 +141,9 @@ int flexran_agent_destroy_channel(int channel_id) { for (i = 0; i < NUM_MAX_ENB; i++) { for (j = 0; j < FLEXRAN_AGENT_MAX; j++) { if (agent_channel[i][j] != NULL) { - if (agent_channel[i][j]->channel_id == e->channel_id) { - agent_channel[i][j] == NULL; - } + if (agent_channel[i][j]->channel_id == e->channel_id) { + free(agent_channel[i][j]); + } } } } @@ -164,7 +164,9 @@ err_code_t flexran_agent_init_channel_container(void) { for (i = 0; i < NUM_MAX_ENB; i++) { for (j = 0; j < FLEXRAN_AGENT_MAX; j++) { - agent_channel[i][j] == NULL; + agent_channel[i][j] = malloc(sizeof(flexran_agent_channel_t)); + if (!agent_channel[i][j]) + return -1; } } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c new file mode 100644 index 0000000000000000000000000000000000000000..2e5bccd93514671481c537884190448238a19a13 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -0,0 +1,1395 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_ran_api.c + * \brief FlexRAN RAN API abstraction + * \author N. Nikaein, X. Foukas, S. SHARIAT BAGHERI and R. Schmidt + * \date 2017 + * \version 0.1 + */ + +#include "flexran_agent_ran_api.h" + +static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) +{ + return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id]; +} + +static inline int mac_is_present(mid_t mod_id) +{ + return RC.mac && RC.mac[mod_id]; +} + +static inline int rrc_is_present(mid_t mod_id) +{ + return RC.rrc && RC.rrc[mod_id]; +} + +uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag) +{ + if (!mac_is_present(mod_id)) return 0; + if (subframe_flag == 1) + return RC.mac[mod_id]->frame*10 + RC.mac[mod_id]->subframe; + else + return RC.mac[mod_id]->frame*10; +} + +frame_t flexran_get_current_frame(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return 0; + // #warning "SFN will not be in [0-1023] when oaisim is used" + return RC.mac[mod_id]->frame; +} + +frame_t flexran_get_current_system_frame_num(mid_t mod_id) +{ + return flexran_get_current_frame(mod_id) % 1024; +} + +sub_frame_t flexran_get_current_subframe(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->subframe; +} + +/* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */ +uint16_t flexran_get_sfn_sf(mid_t mod_id) +{ + frame_t frame = flexran_get_current_system_frame_num(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); + uint16_t sfn_sf, frame_mask, sf_mask; + + frame_mask = (1 << 12) - 1; + sf_mask = (1 << 4) - 1; + sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); + + return sfn_sf; +} + +uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) +{ + frame_t frame = flexran_get_current_system_frame_num(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); + uint16_t sfn_sf, frame_mask, sf_mask; + int additional_frames; + + subframe = (subframe + ahead_of_time) % 10; + + if (subframe < flexran_get_current_subframe(mod_id)) + frame = (frame + 1) % 1024; + + 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); + + return sfn_sf; +} + +int flexran_get_num_ues(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.num_UEs; +} + +rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) +{ + return UE_RNTI(mod_id, ue_id); +} + +int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].ul_buffer_info[lcid]; +} + +int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info; +} + +uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0]; +} + +rlc_buffer_occupancy_t 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); + frame_t frame = flexran_get_current_frame(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0 +#ifdef Rel14 + ,0, 0 +#endif + ); + return rlc_status.bytes_in_buffer; +} + +rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(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); + frame_t frame = flexran_get_current_frame(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0 +#ifdef Rel14 + ,0, 0 +#endif + ); + return rlc_status.pdus_in_buffer; +} + +frame_t 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); + frame_t frame = flexran_get_current_frame(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0 +#ifdef Rel14 + ,0, 0 +#endif + ); + return rlc_status.head_sdu_creation_time; +} + +int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + + int32_t tau = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update; + switch (flexran_get_N_RB_DL(mod_id, cc_id)) { + case 6: + return tau; + case 15: + return tau / 2; + case 25: + return tau / 4; + case 50: + return tau / 8; + case 75: + return tau / 12; + case 100: + if (flexran_get_threequarter_fs(mod_id, cc_id) == 0) + return tau / 16; + else + return tau / 12; + default: + return 0; + } +} + +uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes; +} + +uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx; +} + +uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS; +} + +uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_TBS; +} + +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx; +} + +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx; +} + +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used; +} + +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_rx; +} + +uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id]; +} + +uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1; +} + +uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2; +} + +uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1; +} + +uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2; +} + +uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used; +} + +uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx; +} + +uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus; +} + +uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx; +} + +uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes; +} + +uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS; +} + +int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].harq_round; +} + +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx; +} + +unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index]; +} + +uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid]; +} + + +/* TODO needs to be revised */ +void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t 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 { + ue_sched_ctl->ta_timer--; + ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command + } +*/ +#warning "Implement flexran_update_TA() in RAN API" +} + +/* TODO needs to be revised, looks suspicious: why do we need UE stats? */ +int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ +#warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API" + if (!phy_is_present(mod_id, cc_id)) return 0; + + /* UE_stats can not be null, they are an array in RC + LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); + + if (eNB_UE_stats == NULL) { + return 0; + } + */ + + if (flexran_get_TA(mod_id, ue_id, cc_id) != 0) { + return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; + } else { + return 0; + } +} + +int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.numactiveCCs[ue_id]; +} + +uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].rank; +} + +int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + + /* before: tested that UL_rssi != NULL and set parameter ([0]), but it is a + * static array -> target_rx_power is useless in old ifs?! */ + int pCCid = UE_PCCID(mod_id,ue_id); + int32_t target_rx_power = RC.eNB[mod_id][pCCid]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; + int32_t normalized_rx_power = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].UL_rssi[0]; + + int tpc; + if (normalized_rx_power > target_rx_power + 1) + tpc = 0; //-1 + else if (normalized_rx_power < target_rx_power - 1) + tpc = 2; //+1 + else + tpc = 1; //0 + return tpc; +} + +int flexran_get_harq(mid_t mod_id, + uint8_t cc_id, + mid_t ue_id, + frame_t frame, + sub_frame_t subframe, + uint8_t *pid, + uint8_t *round, + uint8_t harq_flag) +{ + /* 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];*/ + + /* TODO IMPLEMENT */ + /* + uint8_t harq_pid; + uint8_t harq_round; + + if (mac_xface_not_ready()) return 0 ; + + uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + if (harq_flag == openair_harq_DL){ + + mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); + + } else if (harq_flag == openair_harq_UL){ + + mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,round,openair_harq_UL); + } + else { + + LOG_W(FLEXRAN_AGENT,"harq_flag is not recongnized"); + } + + + *pid = harq_pid; + *round = harq_round;*/ + /* if (round > 0) { */ + /* *status = 1; */ + /* } else { */ + /* *status = 0; */ + /* } */ + /*return *round;*/ +#warning "Implement flexran_get_harq() in RAN API" + return 0; +} + +int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm; +} + +int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH; +} + +int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update; +} + +int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0; + return 0; +} + + +/* + * ************************************ + * Get Messages for eNB Configuration Reply + * ************************************ + */ +uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.threequarter_fs; +} + + +uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset; +} + +PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode; +} + +uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB; +} + +uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM; +} + +PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration; +} + +int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) { + case oneSixth: + return 0; + case half: + return 1; + case one: + return 2; + case two: + return 3; + default: + return -1; + } +} + +uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN; +} + +uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI; +} + +uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift; +} + +uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; +} + +uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; +} + +uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx; +} + +lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL; +} + +lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.Ncp; +} + +uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.Nid_cell; +} + +uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig; +} + +uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig; +} + +uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_MaxUpPts; +} + +uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL; +} + +uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL; +} + +uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.N_RBG; +} + +uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config; +} + +uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config_S; +} + +long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.rach_raResponseWindowSize[cc_id]; +} + +long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.rach_macContentionResolutionTimer[cc_id]; +} + +Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + switch (RC.eNB[mod_id][cc_id]->frame_parms.frame_type) { + case TDD: + return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; + case FDD: + return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; + default: + return -1; + } +} + +long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc_is_present(mod_id) || !RC.rrc[mod_id]->carrier[cc_id].sib1) return 0; + return RC.rrc[mod_id]->carrier[cc_id].sib1->si_WindowLength; +} + +uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1; +} + +uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols; +} + + + +/* + * ************************************ + * Get Messages for UE Configuration Reply + * ************************************ + */ + + +TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; +} + +Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measGapConfig) return -1; + if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1; + switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { + case MeasGapConfig__setup__gapOffset_PR_gp0: + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; + case MeasGapConfig__setup__gapOffset_PR_gp1: + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; + default: + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; + } +} + + +long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measGapConfig) return -1; + if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1; + switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { + case MeasGapConfig__setup__gapOffset_PR_gp0: + return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; + case MeasGapConfig__setup__gapOffset_PR_gp1: + return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp1; + default: + return -1; + } +} + +uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return 0; + + rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return RRC_INACTIVE; + return ue_context_p->ue_context.Status; +} + +uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; +} + +uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; +} + +int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA; + for (int i = 0; i < bands->list.count; i++) { + if (bands->list.array[i]->halfDuplex > 0) return 1; + } + return 0; +} + +int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; + /* According to TS 36.331 Annex B.1, Intra SF Hopping is bit 1 (leftmost bit) + * in this bitmap, i.e. the eighth bit (from right) in the first bye (from + * left) */ + BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; + uint8_t buf = fgi->buf[0]; + return (buf >> 7) & 1; +} + +int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; + /* According to TS 36.331 Annex B.1, Predefined intra- and inter-sf or + * predfined inter-sf frequency hopping for PUSCH with N_sb>1 is bit 21 (bit + * 1 is leftmost bit) in this bitmap, i.e. the fourth bit (from right) in the + * third byte (from left) */ + BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; + uint8_t buf = fgi->buf[2]; + return (buf >> 3) & 1; +} + +long flexran_get_ue_category(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + return ue_context_p->ue_context.UE_Capability->ue_Category; +} + +int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; + /* According to TS 36.331 Annex B.1, Resource allocation type 1 for PDSCH is + * bit 2 (bit 1 is leftmost bit) in this bitmap, i.e. the seventh bit (from + * right) in the first byte (from left) */ + BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; + uint8_t buf = fgi->buf[0]; + return (buf >> 6) & 1; +} + +long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; +} + +BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; + return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; +} + +long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; + return *(ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx); +} + +long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; +} + +long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; +} + +long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; +} + +BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; +} + +BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!rrc_is_present(mod_id)) return -1; + if (!RC.rrc[mod_id]->carrier[cc_id].sib2) return -1; + return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; +} + +CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; + return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; +} + +long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) return -1; + return *(ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode); +} + +long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; +} + +long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ext2) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020) return -1; + return *(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10); +} + +int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; + switch (ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup) { + case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop: + return 2; + case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop: + return 1; + default: + return 0; + } +} + +uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id) +{ + uint64_t imsi; + if (!rrc_is_present(mod_id)) return 0; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return 0; + + imsi = ue_context_p->ue_context.imsi.digit15; + imsi += ue_context_p->ue_context.imsi.digit14 * 10; // pow(10, 1) + imsi += ue_context_p->ue_context.imsi.digit13 * 100; // pow(10, 2) + imsi += ue_context_p->ue_context.imsi.digit12 * 1000; // pow(10, 3) + imsi += ue_context_p->ue_context.imsi.digit11 * 10000; // pow(10, 4) + imsi += ue_context_p->ue_context.imsi.digit10 * 100000; // pow(10, 5) + imsi += ue_context_p->ue_context.imsi.digit9 * 1000000; // pow(10, 6) + imsi += ue_context_p->ue_context.imsi.digit8 * 10000000; // pow(10, 7) + imsi += ue_context_p->ue_context.imsi.digit7 * 100000000; // pow(10, 8) + imsi += ue_context_p->ue_context.imsi.digit6 * 1000000000; // pow(10, 9) + imsi += ue_context_p->ue_context.imsi.digit5 * 10000000000; // pow(10, 10) + imsi += ue_context_p->ue_context.imsi.digit4 * 100000000000; // pow(10, 11) + imsi += ue_context_p->ue_context.imsi.digit3 * 1000000000000; // pow(10, 12) + imsi += ue_context_p->ue_context.imsi.digit2 * 10000000000000; // pow(10, 13) + imsi += ue_context_p->ue_context.imsi.digit1 * 100000000000000; // pow(10, 14) + return imsi; +} + +long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].lcgidmap[lc_id]; +} + +/* TODO Navid: needs to be revised */ +int flexran_get_direction(mid_t ue_id, mid_t lc_id) +{ + switch (lc_id) { + case DCCH: + case DCCH1: + return 2; + case DTCH: + return 1; + default: + return -1; + } +} + +uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB; +} + +uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000; +} + +uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000; +} + +uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.eutra_band; +} + +int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id) +{ + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower; +} + +long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.pusch_p0_Nominal[cc_id]; +} + +void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz) +{ + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq = dl_freq_mhz * 1000000; + } else { + LOG_E(FLEXRAN_AGENT, "can not set dl_CarrierFreq to %d MHz in PHY: PHY is not present\n", dl_freq_mhz); + } + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.downlink_frequency[cc_id] = dl_freq_mhz * 1000000; + } else { + LOG_E(FLEXRAN_AGENT, "can not set downlink_frequency to %d MHz in RRC: RRC is not present\n", dl_freq_mhz); + } +} + +void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset) +{ + if (phy_is_present(mod_id, cc_id)) { + uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset; + RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq = new_ul_freq_mhz * 1000000; + } else { + LOG_E(FLEXRAN_AGENT, "can not set ul_CarrierFreq using offset %d MHz in PHY: PHY is not present\n", ul_freq_mhz_offset); + } + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.uplink_frequency_offset[cc_id] = ul_freq_mhz_offset; + } else { + LOG_E(FLEXRAN_AGENT, "can not set uplink_frequency_offset to %d MHz in RRC: RRC is not present\n", ul_freq_mhz_offset); + } +} + +void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band) +{ + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.eutra_band = eutra_band; + } else { + LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in PHY: PHY is not present\n", eutra_band); + } + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.eutra_band[cc_id] = eutra_band; + } else { + LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in RRC: RRC is not present\n", eutra_band); + } +} + +/* Sets both DL/UL */ +void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB) +{ + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL = N_RB; + RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL = N_RB; + } else { + LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL and N_RB_UL to %d in PHY: PHY is not present\n", N_RB); + } + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.N_RB_DL[cc_id] = N_RB; + } else { + LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL to %d in RRC: RRC is not present\n", N_RB); + } +} + +void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type) +{ + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.frame_type = frame_type; + } else { + LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in PHY: PHY is not present\n", frame_type); + } + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.frame_type[cc_id] = frame_type; + } else { + LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in RRC: RRC is not present\n", frame_type); + } +} + +/*********** PDCP *************/ +/*PDCP super frame counter flexRAN*/ +uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){ + return pdcp_enb[mod_id].sfn; +} + +/*PDCP super frame counter flexRAN*/ +void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ + if (obs_window > 0 ){ + Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window; + } + else{ + Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000; + } +} + +/*PDCP super frame counter flexRAN*/ +void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ + if (obs_window > 0 ){ + Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window; + } + else{ + Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000; + } +} + +/*PDCP num tx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + if (mod_id <0 || mod_id> MAX_NUM_CCs || ue_id<0 || ue_id> MAX_MOBILES_PER_ENB || lcid<0 || lcid>NB_RB_MAX) + return -1; + return Pdcp_stats_tx[mod_id][ue_id][lcid]; +} + +/*PDCP num tx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_bytes[mod_id][ue_id][lcid]; +} + +/*PDCP number of transmit packet / second status flexRAN*/ +uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_w[mod_id][ue_id][lcid]; +} + +/*PDCP throughput (bit/s) status flexRAN*/ +uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_bytes_w[mod_id][ue_id][lcid]; +} + +/*PDCP tx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_sn[mod_id][ue_id][lcid]; +} + +/*PDCP tx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_aiat[mod_id][ue_id][lcid]; +} + +/*PDCP tx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_aiat_w[mod_id][ue_id][lcid]; +} + + +/*PDCP num rx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx[mod_id][ue_id][lcid]; +} + +/*PDCP num rx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_bytes[mod_id][ue_id][lcid]; +} + +/*PDCP number of received packet / second flexRAN*/ +uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_w[mod_id][ue_id][lcid]; +} + +/*PDCP gootput (bit/s) status flexRAN*/ +uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_bytes_w[mod_id][ue_id][lcid]; +} + +/*PDCP rx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_sn[mod_id][ue_id][lcid]; +} + +/*PDCP rx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_aiat[mod_id][ue_id][lcid]; +} + +/*PDCP rx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_aiat_w[mod_id][ue_id][lcid]; +} + +/*PDCP num of received outoforder pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_outoforder[mod_id][ue_id][lcid]; +} + +/******************** RRC *****************************/ + +MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + return ue_context_p->ue_context.measResults->measId; +} + +float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult]; +} + +float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult]; +} + +/*Number of neighbouring cells for specific UE*/ +int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return 0; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return 0; + if (!ue_context_p->ue_context.measResults) return 0; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0; + return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count; +} + +PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; + return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; +} + +float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return 0; + return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; +} + +float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0; + return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; +} diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h new file mode 100644 index 0000000000000000000000000000000000000000..3354d8ace875da91ed0dc6fc9b53f5fca5225877 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -0,0 +1,506 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_ran_api.h + * \brief FlexRAN RAN API abstraction header + * \author N. Nikaein, X. Foukas and S. SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include <stdio.h> +#include <time.h> + +#include "flexran_agent_common.h" +#include "flexran_agent_common_internal.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_defs.h" + + +#include "enb_config.h" +#include "LAYER2/RLC/rlc.h" +#include "SCHED/sched_eNB.h" +#include "pdcp.h" +#include "RRC/LTE/rrc_extern.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "RRC/LTE/rrc_eNB_UE_context.h" +#include "PHY/phy_extern.h" +#include "log.h" + +/**************************** + * get generic info from RAN + ****************************/ + +uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag); + +/*Return the current frame number + *Could be using implementation specific numbering of frames + */ +frame_t flexran_get_current_frame(mid_t mod_id); + +/*Return the current SFN (0-1023)*/ +frame_t flexran_get_current_system_frame_num(mid_t mod_id); + +sub_frame_t flexran_get_current_subframe(mid_t mod_id); + +/*Return the frame and subframe number in compact 16-bit format. + Bits 0-3 subframe, rest for frame. Required by FlexRAN protocol*/ +uint16_t flexran_get_sfn_sf(mid_t mod_id); + +/* Return a future frame and subframe number that is ahead_of_time + subframes later in compact 16-bit format. Bits 0-3 subframe, + rest for frame */ +uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); + +/* Return the number of attached UEs */ +int flexran_get_num_ues(mid_t mod_id); + +/* Get the rnti of a UE with id ue_id */ +rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id); + +/* Get the RLC buffer status report in bytes of a ue for a designated + * logical channel id */ +int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid); + +/* Get power headroom of UE with id ue_id */ +int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id); + +/* Get the UE wideband CQI */ +uint8_t 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 */ +rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); + +/*Get number of pdus in RLC buffer*/ +rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(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 */ +frame_t 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 */ +int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +/* Update the timing advance status(find out whether a timing advance command is required) */ +/* currently broken +void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); */ + +/* Return timing advance MAC control element for a designated cell and UE */ +/* this function is broken */ +int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +/*Get number of mac SDU DL*/ +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Return the MAC sdu size got from logical channel lcid */ +uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid); + +/*Return number of MAC SDUs obtained in MAC layer*/ +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get mac sdu lcid index*/ +unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index); + +/*Get MAC size sdus length dl*/ +uint32_t flexran_get_size_dl_mac_sdus(mid_t mod_id, int cc_id); + +/*Get MAC size sdus length ul */ +uint32_t flexran_get_size_ul_mac_sdus(mid_t mod_id, int cc_id); + +/*Get total size DL MAC SDUS*/ +uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total size of UL mac SDUS*/ +uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total number of PDU DL*/ +uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total number of PDU UL*/ +uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total PRB dl TODO Should be changed*/ +uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total PRB ul TODO Should be changed*/ +uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for tx per UE DL*/ +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for rx per UE UL*/ +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for retx per UE UL*/ +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for retx per UE*/ +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS before rate adaptation DL*/ +uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS after rate adaptation DL*/ +uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS before rate adaptation UL*/ +uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS after rate adaptation UL*/ +uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get downlink TBS*/ +uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get uplink TBS */ +uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total TBS DL*/ +uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total TBS DL*/ +uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/* Get the current HARQ round for UE ue_id */ +int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id); + +/* Get the number of active component carriers for a specific UE */ +int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); + +/* Get the rank indicator for a designated cell and UE */ +uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +/* See TS 36.213, section 10.1 */ +uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.211, section 5.4 */ +uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.211, section 5.4 */ +uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.211, section 5.7.1 */ +uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.211, section 5.7.1 */ +uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.321 */ +uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id); + +/* Get the length of the UL cyclic prefix */ +lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); + +/* Get the length of the DL cyclic prefix */ +lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); + +/* Get the physical cell id of a cell */ +uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.211, section 5.5.3.2 */ +uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.211, table 5.5.3.3-1 and 2 */ +uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id); + +/* Boolean value. See TS 36.211, + section 5.5.3.2. TDD only */ +uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id); + +/* Get number of DL resource blocks */ +uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id); + +/* Get number of UL resource blocks */ +uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id); + +/* Get number of resource block groups */ +uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id); + +/* Get DL/UL subframe assignment. TDD only */ +uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id); + +/* TDD only. See TS 36.211, table 4.2.1 */ +uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id); + +/* Get the duration of the random access response window in subframes */ +long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id); + +/* Get timer used for random access */ +long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id); + +/* Get type of duplex mode(FDD/TDD) */ +Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id); + +/* Get the SI window length */ +long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id); + +/* Get length of SystemInformationBlock1 */ +uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id); + +/* Get the number of PDCCH symbols configured for the cell */ +uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id); + +uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id); + +/* See TS 36.213, sec 5.1.1.1 */ +int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +/* Get the first available HARQ process for a specific cell and UE during + a designated frame and subframe. Returns 0 for success. The id and the + status of the HARQ process are stored in id and status respectively */ +/* currently broken +int flexran_get_harq(mid_t mod_id, uint8_t cc_id, mid_t ue_id, frame_t frame, + sub_frame_t subframe, unsigned char *id, unsigned char *round, + uint8_t harq_flag); */ + +/* Uplink power control management*/ +int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id); + +int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id); + +PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id); + +uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id); + +uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id); + +int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id); + +uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id); + +PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id); + +/* + * ************************************ + * Get Messages for UE Configuration Reply + * ************************************ + */ + +/* Get timer in subframes. Controls the synchronization + status of the UE, not the actual timing + advance procedure. See TS 36.321 */ +TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); + +/* Get measurement gap configuration. See TS 36.133 */ +Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); + +/* Get measurement gap configuration offset if applicable */ +long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); + +/* DL aggregated bit-rate of non-gbr bearer + per UE. See TS 36.413 */ +uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id); + +/* UL aggregated bit-rate of non-gbr bearer + per UE. See TS 36.413 */ +uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id); + +/* Only half-duplex support. FDD operation. Boolean value */ +int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id); + +/* Support of intra-subframe hopping. Boolean value */ +int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id); + +/* UE support for type 2 hopping with n_sb>1 */ +int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id); + +/* Get the UE category */ +long flexran_get_ue_category(mid_t mod_id, mid_t ue_id); + +/* UE support for resource allocation type 1 */ +int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id); + +/* Get UE transmission mode */ +long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); + +/* Boolean value. See TS 36.321 */ +BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id); + +/* The max HARQ retransmission for UL. + See TS 36.321 */ +long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); + +/* See TS 36.213 */ +long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); + +/* See TS 36.213 */ +long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); + +/* See TS 36.213 */ +long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); + +/* Boolean. See TS36.213, Section 10.1 */ +BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); + +/* Boolean. See TS 36.213, Section 8.2 */ +BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id); + +/* Get aperiodic CQI report mode */ +CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); + +/* Get ACK/NACK feedback mode. TDD only */ +long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id); + +/* See TS36.213, section 10.1 */ +long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); + +/* Boolean. Extended buffer status report size */ +long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); + +/* Get number of UE transmission antennas */ +int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); + +/* Get the IMSI of UE */ +uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id); + +/* Get logical channel group of a channel with id lc_id */ +long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id); + +/* Get direction of logical channel with id lc_id */ +int flexran_get_direction(mid_t ue_id, mid_t lc_id); + +/*Get downlink frequency*/ +uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id); + +/*Get uplink frequency*/ +uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id); + +/*Get eutra band*/ +uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id); + +/*Get downlink ref signal power*/ +int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id); + +/*Get uplink power*/ +long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id); + +/*set the dl freq */ +void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz); + +/* set the ul freq */ +void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset); + +/*set the the band */ +void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band); + +/* set the bandwidth (in RB) */ +void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB); + +/*set frame type*/ +void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type); + +/*RRC status flexRAN*/ +uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id); + + +/***************************** PDCP ***********************/ + +/*PDCP superframe numberflexRAN*/ +uint32_t flexran_get_pdcp_sfn(const mid_t mod_id); + +/*PDCP pdcp tx stats window*/ +void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); + +/*PDCP pdcp rx stats window*/ +void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); + +/*PDCP num tx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP num tx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP number of transmit packet / second status flexRAN*/ +uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP pdcp tx bytes in a given window flexRAN*/ +uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP tx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP tx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP tx aggregated packet arrival per second flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + + +/*PDCP num rx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP num rx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP number of received packet / second flexRAN*/ +uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP gootput (bit/s) status flexRAN*/ +uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP rx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP rx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP rx aggregated packet arrival per second flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP num of received outoforder pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*********************RRC**********************/ +/*Get primary cell measuremeant id flexRAN*/ +MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id); + +/*Get primary cell RSRP measurement flexRAN*/ +float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id); + +/*Get primary cell RSRQ measurement flexRAN*/ +float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id); + +/* Get RRC neighbouring measurement */ +int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id); + +/*Get physical cell id*/ +PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id); + +/*Get RSRP of neighbouring Cell*/ +float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id); + +/*Get RSRQ of neighbouring Cell*/ +float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id); + +/*Get MCC PLMN identity neighbouring Cell*/ +/* currently not implemented +int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); */ + +/*Get MNC PLMN identity neighbouring Cell*/ +/* currently not implemented +int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */ diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..dda302735388ce56f5ce57d9e39de10a5cd712b8 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -0,0 +1,217 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_timer.c + * \brief FlexRAN Timer + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +/* + * timer primitives + */ + +#include "flexran_agent_timer.h" + +//struct flexran_agent_map agent_map; +flexran_agent_timer_instance_t timer_instance; +int agent_timer_init = 0; +err_code_t flexran_agent_init_timer(void){ + + LOG_I(FLEXRAN_AGENT, "init RB tree\n"); + if (!agent_timer_init) { + RB_INIT(&timer_instance.flexran_agent_head); + agent_timer_init = 1; + } + + return PROTOCOL__FLEXRAN_ERR__NO_ERR; +} + +RB_GENERATE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); + +/* The timer_id might not be the best choice for the comparison */ +int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b){ + + if (a->timer_id < b->timer_id) return -1; + if (a->timer_id > b->timer_id) return 1; + + // equal timers + return 0; +} + +err_code_t flexran_agent_create_timer(uint32_t interval_sec, + uint32_t interval_usec, + agent_id_t agent_id, + instance_t instance, + uint32_t timer_type, + xid_t xid, + flexran_agent_timer_callback_t cb, + void* timer_args, + long *timer_id){ + + struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); + DevAssert(e != NULL); + +//uint32_t timer_id; + int ret=-1; + + if ((interval_sec == 0) && (interval_usec == 0 )) + return TIMER_NULL; + + if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) + return TIMER_TYPE_INVALIDE; + + if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT){ + ret = timer_setup(interval_sec, + interval_usec, + TASK_FLEXRAN_AGENT, + instance, + TIMER_ONE_SHOT, + timer_args, + timer_id); + + e->type = TIMER_ONE_SHOT; + } + else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ){ + ret = timer_setup(interval_sec, + interval_usec, + TASK_FLEXRAN_AGENT, + instance, + TIMER_PERIODIC, + timer_args, + timer_id); + + e->type = TIMER_PERIODIC; + } + + if (ret < 0 ) { + return TIMER_SETUP_FAILED; + } + + e->agent_id = agent_id; + e->instance = instance; + e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE; + e->timer_id = *timer_id; + e->xid = xid; + e->timer_args = timer_args; + e->cb = cb; + /*element should be a real pointer*/ + RB_INSERT(flexran_agent_map, &timer_instance.flexran_agent_head, e); + + LOG_I(FLEXRAN_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n", + e->timer_id, e->agent_id, e->instance); + + return 0; +} + +err_code_t flexran_agent_destroy_timer(long timer_id){ + + struct flexran_agent_timer_element_s *e = get_timer_entry(timer_id); + + if (e != NULL ) { + RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); + flexran_agent_destroy_flexran_message(e->timer_args->msg); + free(e); + } + + if (timer_remove(timer_id) < 0 ) + goto error; + + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); + return TIMER_REMOVED_FAILED ; +} + +err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid) { + struct flexran_agent_timer_element_s *e = NULL; + long timer_id; + RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { + if (e->xid == xid) { + timer_id = e->timer_id; + RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); + flexran_agent_destroy_flexran_message(e->timer_args->msg); + free(e); + if (timer_remove(timer_id) < 0 ) { + goto error; + } + } + } + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); + return TIMER_REMOVED_FAILED ; +} + +err_code_t flexran_agent_destroy_timers(void){ + + struct flexran_agent_timer_element_s *e = NULL; + + RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { + RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); + timer_remove(e->timer_id); + flexran_agent_destroy_flexran_message(e->timer_args->msg); + free(e); + } + + return 0; + +} + +void flexran_agent_sleep_until(struct timespec *ts, int delay) { + ts->tv_nsec += delay; + if(ts->tv_nsec >= 1000*1000*1000){ + ts->tv_nsec -= 1000*1000*1000; + ts->tv_sec++; + } + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL); +} + + +err_code_t flexran_agent_stop_timer(long timer_id){ + + struct flexran_agent_timer_element_s *e=NULL; + struct flexran_agent_timer_element_s search; + memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); + search.timer_id = timer_id; + + e = RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); + + if (e != NULL ) { + e->state = FLEXRAN_AGENT_TIMER_STATE_STOPPED; + } + + timer_remove(timer_id); + + return 0; +} + +struct flexran_agent_timer_element_s * get_timer_entry(long timer_id) { + + struct flexran_agent_timer_element_s search; + memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); + search.timer_id = timer_id; + + return RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); +} diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..98d83c78a950d7db533316f297e3f3e4ac4c9704 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -0,0 +1,133 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 flexran_agent_timer.h + * \brief FlexRAN Timer header + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include <stdio.h> +#include <time.h> + +#include "flexran_agent_common.h" +#include "flexran_agent_common_internal.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_defs.h" + + +# include "tree.h" +# include "intertask_interface.h" +# include "timer.h" + + + +/******************* + * timer primitves + *******************/ + +#define TIMER_NULL -1 +#define TIMER_TYPE_INVALIDE -2 +#define TIMER_SETUP_FAILED -3 +#define TIMER_REMOVED_FAILED -4 +#define TIMER_ELEMENT_NOT_FOUND -5 + + +/* Type of the callback executed when the timer expired */ +typedef Protocol__FlexranMessage *(*flexran_agent_timer_callback_t)(void*); + + +typedef struct flexran_agent_timer_args_s{ + mid_t mod_id; + Protocol__FlexranMessage *msg; +} flexran_agent_timer_args_t; + + +typedef struct flexran_agent_timer_element_s{ + RB_ENTRY(flexran_agent_timer_element_s) entry; + + agent_id_t agent_id; + instance_t instance; + + flexran_agent_timer_type_t type; + flexran_agent_timer_state_t state; + + uint32_t interval_sec; + uint32_t interval_usec; + + long timer_id; /* Timer id returned by the timer API*/ + xid_t xid; /*The id of the task as received by the controller + message*/ + + flexran_agent_timer_callback_t cb; + flexran_agent_timer_args_t *timer_args; + +} flexran_agent_timer_element_t; + +typedef struct flexran_agent_timer_instance_s{ + RB_HEAD(flexran_agent_map, flexran_agent_timer_element_s) flexran_agent_head; +}flexran_agent_timer_instance_t; + + +err_code_t flexran_agent_init_timer(void); + +/* Create a timer for some agent related event with id xid. Will store the id + of the generated timer in timer_id */ +err_code_t flexran_agent_create_timer(uint32_t interval_sec, + uint32_t interval_usec, + agent_id_t agent_id, + instance_t instance, + uint32_t timer_type, + xid_t xid, + flexran_agent_timer_callback_t cb, + void* timer_args, + long *timer_id); + +/* Destroy all existing timers */ +err_code_t flexran_agent_destroy_timers(void); + +/* Destroy the timer with the given timer_id */ +err_code_t flexran_agent_destroy_timer(long timer_id); + +/* Destroy the timer for task with id xid */ +err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid); + +/* Stop a timer */ +err_code_t flexran_agent_stop_timer(long timer_id); + +/* Restart the given timer */ +err_code_t flexran_agent_restart_timer(long *timer_id); + +/* Find the timer with the given timer_id */ +struct flexran_agent_timer_element_s * get_timer_entry(long timer_id); + +/* Obtain the protocol message stored in the given expired timer */ +Protocol__FlexranMessage * flexran_agent_process_timeout(long timer_id, void* timer_args); + +/* Comparator function comparing two timers. Decides the ordering of the timers */ +int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b); + +/*Specify a delay in nanoseconds to timespec and sleep until then*/ +void flexran_agent_sleep_until(struct timespec *ts, int delay); + +/* RB_PROTOTYPE is for .h files */ +RB_PROTOTYPE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 95809957b3d5e5b9ff9e4574cf7c76ea3d82f1af..929c0fad245fac3222ba55991aeaf7e4c3f0513d 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -32,25 +32,24 @@ #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" -#include "SCHED/defs.h" #include "SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" #include "RadioResourceConfigDedicated.h" -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) #include "PRACH-ConfigSIB-v1310.h" #endif #include "MeasGapConfig.h" #include "MeasObjectToAddModList.h" #include "TDD-Config.h" #include "MAC-MainConfig.h" -#include "defs.h" -#include "proto.h" -#include "extern.h" +#include "mac.h" +#include "mac_proto.h" +#include "mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "common/ran_context.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-AreaInfo-r9.h" #include "MBSFN-SubframeConfigList.h" @@ -61,161 +60,125 @@ extern RAN_CONTEXT_t RC; extern int l2_init_eNB(void); extern void mac_top_init_eNB(void); extern void mac_init_cell_params(int Mod_idP,int CC_idP); -extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); extern uint8_t nfapi_mode; -/* sec 5.9, 36.321: MAC Reset Procedure */ -void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) -{ - - //Resetting Bj - UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0; - UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0; - UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0; - - //Stopping all timers - - //timeAlignmentTimer expires - - // PHY changes for UE MAC reset - phy_reset_ue(module_idP, 0, eNB_index); - - // notify RRC to relase PUCCH/SRS - // cancel all pending SRs - UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; - UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; - -//Set BSR Trigger Bmp and remove timer flags - UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; - - // stop ongoing RACH procedure - - // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any - UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check! - UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; - - - ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure - -} - int32_t **rxdata; int32_t **txdata; typedef struct eutra_bandentry_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - uint32_t N_OFFs_DL; + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + uint32_t N_OFFs_DL; } eutra_bandentry_t; typedef struct band_info_s { - int nbands; - eutra_bandentry_t band_info[100]; + int nbands; + eutra_bandentry_t band_info[100]; } band_info_t; static const eutra_bandentry_t eutra_bandtable[] = { - {1, 19200, 19800, 21100, 21700, 0}, - {2, 18500, 19100, 19300, 19900, 6000}, - {3, 17100, 17850, 18050, 18800, 12000}, - {4, 17100, 17550, 21100, 21550, 19500}, - {5, 8240, 8490, 8690, 8940, 24000}, - {6, 8300, 8400, 8750, 8850, 26500}, - {7, 25000, 25700, 26200, 26900, 27500}, - {8, 8800, 9150, 9250, 9600, 34500}, - {9, 17499, 17849, 18449, 18799, 38000}, - {10, 17100, 17700, 21100, 21700, 41500}, - {11, 14279, 14529, 14759, 15009, 47500}, - {12, 6980, 7160, 7280, 7460, 50100}, - {13, 7770, 7870, 7460, 7560, 51800}, - {14, 7880, 7980, 7580, 7680, 52800}, - {17, 7040, 7160, 7340, 7460, 57300}, - {18, 8150, 9650, 8600, 10100, 58500}, - {19, 8300, 8450, 8750, 8900, 60000}, - {20, 8320, 8620, 7910, 8210, 61500}, - {21, 14479, 14629, 14959, 15109, 64500}, - {22, 34100, 34900, 35100, 35900, 66000}, - {23, 20000, 20200, 21800, 22000, 75000}, - {24, 16126, 16605, 15250, 15590, 77000}, - {25, 18500, 19150, 19300, 19950, 80400}, - {26, 8140, 8490, 8590, 8940, 86900}, - {27, 8070, 8240, 8520, 8690, 90400}, - {28, 7030, 7580, 7580, 8130, 92100}, - {29, 0, 0, 7170, 7280, 96600}, - {30, 23050, 23250, 23500, 23600, 97700}, - {31, 45250, 34900, 46250, 35900, 98700}, - {32, 0, 0, 14520, 14960, 99200}, - {33, 19000, 19200, 19000, 19200, 36000}, - {34, 20100, 20250, 20100, 20250, 36200}, - {35, 18500, 19100, 18500, 19100, 36350}, - {36, 19300, 19900, 19300, 19900, 36950}, - {37, 19100, 19300, 19100, 19300, 37550}, - {38, 25700, 26200, 25700, 26300, 37750}, - {39, 18800, 19200, 18800, 19200, 38250}, - {40, 23000, 24000, 23000, 24000, 38650}, - {41, 24960, 26900, 24960, 26900, 39650}, - {42, 34000, 36000, 34000, 36000, 41590}, - {43, 36000, 38000, 36000, 38000, 43590}, - {44, 7030, 8030, 7030, 8030, 45590}, - {45, 14470, 14670, 14470, 14670, 46590}, - {46, 51500, 59250, 51500, 59250, 46790}, - {65, 19200, 20100, 21100, 22000, 65536}, - {66, 17100, 18000, 21100, 22000, 66436}, - {67, 0, 0, 7380, 7580, 67336}, - {68, 6980, 7280, 7530, 7830, 67536} + {1, 19200, 19800, 21100, 21700, 0}, + {2, 18500, 19100, 19300, 19900, 6000}, + {3, 17100, 17850, 18050, 18800, 12000}, + {4, 17100, 17550, 21100, 21550, 19500}, + {5, 8240, 8490, 8690, 8940, 24000}, + {6, 8300, 8400, 8750, 8850, 26500}, + {7, 25000, 25700, 26200, 26900, 27500}, + {8, 8800, 9150, 9250, 9600, 34500}, + {9, 17499, 17849, 18449, 18799, 38000}, + {10, 17100, 17700, 21100, 21700, 41500}, + {11, 14279, 14529, 14759, 15009, 47500}, + {12, 6980, 7160, 7280, 7460, 50100}, + {13, 7770, 7870, 7460, 7560, 51800}, + {14, 7880, 7980, 7580, 7680, 52800}, + {17, 7040, 7160, 7340, 7460, 57300}, + {18, 8150, 9650, 8600, 10100, 58500}, + {19, 8300, 8450, 8750, 8900, 60000}, + {20, 8320, 8620, 7910, 8210, 61500}, + {21, 14479, 14629, 14959, 15109, 64500}, + {22, 34100, 34900, 35100, 35900, 66000}, + {23, 20000, 20200, 21800, 22000, 75000}, + {24, 16126, 16605, 15250, 15590, 77000}, + {25, 18500, 19150, 19300, 19950, 80400}, + {26, 8140, 8490, 8590, 8940, 86900}, + {27, 8070, 8240, 8520, 8690, 90400}, + {28, 7030, 7580, 7580, 8130, 92100}, + {29, 0, 0, 7170, 7280, 96600}, + {30, 23050, 23250, 23500, 23600, 97700}, + {31, 45250, 34900, 46250, 35900, 98700}, + {32, 0, 0, 14520, 14960, 99200}, + {33, 19000, 19200, 19000, 19200, 36000}, + {34, 20100, 20250, 20100, 20250, 36200}, + {35, 18500, 19100, 18500, 19100, 36350}, + {36, 19300, 19900, 19300, 19900, 36950}, + {37, 19100, 19300, 19100, 19300, 37550}, + {38, 25700, 26200, 25700, 26300, 37750}, + {39, 18800, 19200, 18800, 19200, 38250}, + {40, 23000, 24000, 23000, 24000, 38650}, + {41, 24960, 26900, 24960, 26900, 39650}, + {42, 34000, 36000, 34000, 36000, 41590}, + {43, 36000, 38000, 36000, 38000, 43590}, + {44, 7030, 8030, 7030, 8030, 45590}, + {45, 14470, 14670, 14470, 14670, 46590}, + {46, 51500, 59250, 51500, 59250, 46790}, + {65, 19200, 20100, 21100, 22000, 65536}, + {66, 17100, 18000, 21100, 22000, 66436}, + {67, 0, 0, 7380, 7580, 67336}, + {68, 6980, 7280, 7530, 7830, 67536} }; uint32_t to_earfcn(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw) { - uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000; - int bw_by_100 = bw / 100; + uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000; + int bw_by_100 = bw / 100; - int i; + int i; - AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); + for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); - AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min, - "Band %d, bw %u : DL carrier frequency %u Hz < %u\n", - eutra_bandP, bw, dl_CarrierFreq, - eutra_bandtable[i].dl_min); - AssertFatal(dl_CarrierFreq_by_100k <= - (eutra_bandtable[i].dl_max - bw_by_100), - "Band %d, bw %u: DL carrier frequency %u Hz > %d\n", - eutra_bandP, bw, dl_CarrierFreq, - eutra_bandtable[i].dl_max - bw_by_100); + AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min, + "Band %d, bw %u : DL carrier frequency %u Hz < %u\n", + eutra_bandP, bw, dl_CarrierFreq, + eutra_bandtable[i].dl_min); + AssertFatal(dl_CarrierFreq_by_100k <= + (eutra_bandtable[i].dl_max - bw_by_100), + "Band %d, bw %u: DL carrier frequency %u Hz > %d\n", + eutra_bandP, bw, dl_CarrierFreq, + eutra_bandtable[i].dl_max - bw_by_100); - return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + - (eutra_bandtable[i].N_OFFs_DL / 10)); + return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + + (eutra_bandtable[i].N_OFFs_DL / 10)); } uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { - int i; + int i; - AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); + for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); - return (eutra_bandtable[i].dl_min + - (dl_earfcn - (eutra_bandtable[i].N_OFFs_DL / 10))) * 100000; + return (eutra_bandtable[i].dl_min + + (dl_earfcn - (eutra_bandtable[i].N_OFFs_DL / 10))) * 100000; } int32_t get_uldl_offset(int eutra_bandP) { - int i; + int i; - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); - return (eutra_bandtable[i].dl_min - eutra_bandtable[i].ul_min); + for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + return (eutra_bandtable[i].dl_min - eutra_bandtable[i].ul_min); } uint32_t bw_table[6] = {6*180,15*180,25*180,50*180,75*180,100*180}; @@ -229,8 +192,12 @@ void config_mib(int Mod_idP, int NcpP, int p_eNBP, uint32_t dl_CarrierFreqP, - uint32_t ul_CarrierFreqP, - uint32_t pbch_repetitionP) { + uint32_t ul_CarrierFreqP +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + uint32_t pbch_repetitionP +#endif + ) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; @@ -251,7 +218,7 @@ void config_mib(int Mod_idP, cfg->rf_config.dl_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; cfg->num_tlv++; -LOG_D(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); + LOG_D(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); cfg->rf_config.ul_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; @@ -298,33 +265,33 @@ LOG_D(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); cfg->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; cfg->num_tlv++; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; cfg->num_tlv++; #endif - LOG_I(MAC, - "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" -#ifdef Rel14 - " PBCH repetition %d" + "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + + " PBCH repetition %d" #endif - "\n" - ,__FUNCTION__ - ,cfg->num_tlv - ,cfg->rf_config.dl_channel_bandwidth.value - ,cfg->rf_config.ul_channel_bandwidth.value - ,NcpP,p_eNBP - ,cfg->nfapi_config.earfcn.value - ,cfg->nfapi_config.rf_bands.rf_band[0] - ,cfg->phich_config.phich_resource.value - ,cfg->phich_config.phich_duration.value - ,cfg->phich_config.phich_power_offset.value - ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value - ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value - ,cfg->sch_config.physical_cell_id.value -#ifdef Rel14 - ,cfg->emtc_config.pbch_repetitions_enable_r13.value + "\n" + ,__FUNCTION__ + ,cfg->num_tlv + ,cfg->rf_config.dl_channel_bandwidth.value + ,cfg->rf_config.ul_channel_bandwidth.value + ,NcpP,p_eNBP + ,cfg->nfapi_config.earfcn.value + ,cfg->nfapi_config.rf_bands.rf_band[0] + ,cfg->phich_config.phich_resource.value + ,cfg->phich_config.phich_duration.value + ,cfg->phich_config.phich_power_offset.value + ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.physical_cell_id.value +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,cfg->emtc_config.pbch_repetitions_enable_r13.value #endif ); } @@ -332,7 +299,8 @@ LOG_D(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); void config_sib1(int Mod_idP, int CC_idP, TDD_Config_t * tdd_ConfigP) { - nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; + + nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; if (tdd_ConfigP) { //TDD cfg->subframe_config.duplex_mode.value = 0; @@ -361,7 +329,7 @@ void config_sib2(int Mod_idP, int CC_idP, RadioResourceConfigCommonSIB_t * radioResourceConfigCommonP, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BRP, #endif ARFCN_ValueEUTRA_t *ul_CArrierFreqP, @@ -432,16 +400,13 @@ config_sib2(int Mod_idP, cfg->pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; cfg->num_tlv++; - if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) - { + if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; } - else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) - { + else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; } - else // No hopping - { + else { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; } cfg->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; @@ -469,8 +434,7 @@ config_sib2(int Mod_idP, cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; cfg->srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; cfg->num_tlv++; - - + if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { cfg->srs_config.max_up_pts.value = 1; } @@ -481,11 +445,11 @@ config_sib2(int Mod_idP, cfg->num_tlv++; } -#ifdef Rel14 - if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13>0) { - AssertFatal(radioResourceConfigCommon_BRP!=NULL,"radioResource rou is missing\n"); - AssertFatal(radioResourceConfigCommon_BRP->ext4!=NULL,"ext4 is missing\n"); - cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0) { + AssertFatal(radioResourceConfigCommon_BRP != NULL, "radioResource rou is missing\n"); + AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL, "ext4 is missing\n"); + cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; cfg->num_tlv++; @@ -493,35 +457,35 @@ config_sib2(int Mod_idP, cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; + cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; cfg->num_tlv++; - - struct PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + struct PRACH_ConfigSIB_v1310 *ext4_prach = radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; + + PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; PRACH_ParametersCE_r13_t *p; - cfg->emtc_config.prach_ce_level_0_enable.value=0; + cfg->emtc_config.prach_ce_level_0_enable.value = 0; cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_1_enable.value=0; + + cfg->emtc_config.prach_ce_level_1_enable.value = 0; cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_2_enable.value=0; + + cfg->emtc_config.prach_ce_level_2_enable.value = 0; cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_3_enable.value=0; + + cfg->emtc_config.prach_ce_level_3_enable.value = 0; cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; cfg->num_tlv++; - + switch (prach_ParametersListCE_r13->list.count) { case 4: - p=prach_ParametersListCE_r13->list.array[3]; - cfg->emtc_config.prach_ce_level_3_enable.value = 1; + p = prach_ParametersListCE_r13->list.array[3]; + cfg->emtc_config.prach_ce_level_3_enable.value = 1; cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; cfg->num_tlv++; @@ -539,7 +503,7 @@ config_sib2(int Mod_idP, if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } @@ -547,13 +511,13 @@ config_sib2(int Mod_idP, cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; cfg->num_tlv++; case 3: - p=prach_ParametersListCE_r13->list.array[2]; - cfg->emtc_config.prach_ce_level_2_enable.value = 1; + p = prach_ParametersListCE_r13->list.array[2]; + cfg->emtc_config.prach_ce_level_2_enable.value = 1; cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; cfg->num_tlv++; @@ -571,7 +535,7 @@ config_sib2(int Mod_idP, if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } @@ -579,13 +543,13 @@ config_sib2(int Mod_idP, cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; cfg->num_tlv++; case 2: - p=prach_ParametersListCE_r13->list.array[1]; - cfg->emtc_config.prach_ce_level_1_enable.value = 1; + p = prach_ParametersListCE_r13->list.array[1]; + cfg->emtc_config.prach_ce_level_1_enable.value = 1; cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; cfg->num_tlv++; @@ -603,84 +567,84 @@ config_sib2(int Mod_idP, if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } - + cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + + cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; cfg->num_tlv++; - + case 1: - p=prach_ParametersListCE_r13->list.array[0]; + p = prach_ParametersListCE_r13->list.array[0]; cfg->emtc_config.prach_ce_level_0_enable.value = 1; cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; cfg->num_tlv++; - + cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; cfg->num_tlv++; - + cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; cfg->num_tlv++; - + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; - + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } - + cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + + cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; cfg->num_tlv++; } struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; - if ((ext4_freqHoppingParameters) && - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ + if ((ext4_freqHoppingParameters) && + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ - break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ + break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; cfg->num_tlv++; - break; + break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; cfg->num_tlv++; - break; + break; } } - if ((ext4_freqHoppingParameters) && - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ + if ((ext4_freqHoppingParameters) && + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ - break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ + break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; cfg->num_tlv++; - break; + break; case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; cfg->num_tlv++; - break; + break; } } } @@ -705,26 +669,27 @@ config_dedicated_scell(int Mod_idP, } + int rrc_mac_config_req_eNB(module_id_t Mod_idP, int CC_idP, int physCellId, int p_eNB, int Ncp, int eutra_band, uint32_t dl_CarrierFreq, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int pbch_repetition, #endif rnti_t rntiP, BCCH_BCH_Message_t * mib, RadioResourceConfigCommonSIB_t * radioResourceConfigCommon, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BR, #endif struct PhysicalConfigDedicated *physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) SCellToAddMod_r10_t * sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -742,12 +707,12 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , uint8_t MBMS_Flag, MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, PMCH_InfoList_r9_t * pmch_InfoList #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , SystemInformationBlockType1_v1310_IEs_t * sib1_v13ext @@ -798,8 +763,8 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, p_eNB, dl_CarrierFreq, ul_CarrierFreq -#ifdef Rel14 - , pbch_repetition +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , pbch_repetition #endif ); @@ -810,70 +775,71 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList = schedulingInfoList; config_sib1(Mod_idP,CC_idP,tdd_Config); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if (sib1_v13ext != NULL) { RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext; } #endif if (radioResourceConfigCommon != NULL) { - LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n"); - LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.n_SB); - LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); - LOG_I(MAC, - "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); - LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); - LOG_I(MAC, - "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - groupHoppingEnabled); - LOG_I(MAC, - "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - groupAssignmentPUSCH); - LOG_I(MAC, - "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - sequenceHoppingEnabled); - LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); - - AssertFatal(radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx > 0, - "radioResourceconfigCommon %d == 0\n", - (int) radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx); - - RC.mac[Mod_idP]->common_channels[CC_idP]. - radioResourceConfigCommon = radioResourceConfigCommon; - if (ul_CarrierFreq > 0) - RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = - ul_CarrierFreq; - if (ul_Bandwidth) - RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = - *ul_Bandwidth; - else - RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = - RC.mac[Mod_idP]->common_channels[CC_idP].mib->message. - dl_Bandwidth; - - config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, -#ifdef Rel14 - radioResourceConfigCommon_BR, + LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n"); + LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.n_SB); + LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); + LOG_I(MAC, + "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); + LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); + LOG_I(MAC, + "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. + groupHoppingEnabled); + LOG_I(MAC, + "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. + groupAssignmentPUSCH); + LOG_I(MAC, + "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. + sequenceHoppingEnabled); + LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); + + AssertFatal(radioResourceConfigCommon-> + rach_ConfigCommon.maxHARQ_Msg3Tx > 0, + "radioResourceconfigCommon %d == 0\n", + (int) radioResourceConfigCommon-> + rach_ConfigCommon.maxHARQ_Msg3Tx); + + RC.mac[Mod_idP]->common_channels[CC_idP]. + radioResourceConfigCommon = radioResourceConfigCommon; + if (ul_CarrierFreq > 0) + RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = + ul_CarrierFreq; + if (ul_Bandwidth) + RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = + *ul_Bandwidth; + else + RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = + RC.mac[Mod_idP]->common_channels[CC_idP].mib->message. + dl_Bandwidth; + + config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + radioResourceConfigCommon_BR, #endif - NULL, ul_Bandwidth, additionalSpectrumEmission, - mbsfn_SubframeConfigList); + NULL, ul_Bandwidth, additionalSpectrumEmission, + mbsfn_SubframeConfigList); + } } // mib != NULL @@ -884,14 +850,14 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, if (UE_id == -1) { LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, - __LINE__, __FUNCTION__); + __LINE__, __FUNCTION__); } else { if (logicalChannelConfig) UE_list-> UE_template[CC_idP][UE_id].lcgidmap [logicalChannelIdentity] = *logicalChannelConfig-> - ul_SpecificParameters->logicalChannelGroup; + ul_SpecificParameters->logicalChannelGroup; else UE_list-> UE_template[CC_idP][UE_id].lcgidmap @@ -910,48 +876,47 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sCellToAddMod_r10 != NULL) { UE_id = find_UE_id(Mod_idP, rntiP); if (UE_id == -1) LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, - __LINE__, __FUNCTION__); + __LINE__, __FUNCTION__); else - config_dedicated_scell(Mod_idP, rntiP, sCellToAddMod_r10); - + config_dedicated_scell(Mod_idP, rntiP, sCellToAddMod_r10); } #endif - if (mbsfn_SubframeConfigList != NULL) { - LOG_I(MAC, - "[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", - Mod_idP, mbsfn_SubframeConfigList->list.count); - RC.mac[Mod_idP]->common_channels[0].num_sf_allocation_pattern = - mbsfn_SubframeConfigList->list.count; - - for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) { - RC.mac[Mod_idP]->common_channels[0].mbsfn_SubframeConfig[i] = - mbsfn_SubframeConfigList->list.array[i]; - LOG_I(MAC, - "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", - Mod_idP, i, - RC.mac[Mod_idP]-> - common_channels[0].mbsfn_SubframeConfig[i]-> - subframeAllocation.choice.oneFrame.buf[0]); - } + if (mbsfn_SubframeConfigList != NULL) { + LOG_I(MAC, + "[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", + Mod_idP, mbsfn_SubframeConfigList->list.count); + RC.mac[Mod_idP]->common_channels[0].num_sf_allocation_pattern = + mbsfn_SubframeConfigList->list.count; + + for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) { + RC.mac[Mod_idP]->common_channels[0].mbsfn_SubframeConfig[i] = + mbsfn_SubframeConfigList->list.array[i]; + LOG_I(MAC, + "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", + Mod_idP, i, + RC.mac[Mod_idP]-> + common_channels[0].mbsfn_SubframeConfig[i]-> + subframeAllocation.choice.oneFrame.buf[0]); + } -#ifdef Rel10 - RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag; +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag; #endif - } -#if defined(Rel10) || defined(Rel14) + } +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbsfn_AreaInfoList != NULL) { - // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time + // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, mbsfn_AreaInfoList->list.count); RC.mac[Mod_idP]->common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; @@ -963,38 +928,39 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, } } - if (pmch_InfoList != NULL) { - - // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); - - LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", - pmch_InfoList->list.count); - - for (i = 0; i < pmch_InfoList->list.count; i++) { - RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] = - &pmch_InfoList->list.array[i]->pmch_Config_r9; - - LOG_I(MAC, - "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", - i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->sf_AllocEnd_r9); - LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", - i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->mch_SchedulingPeriod_r9); - LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->dataMCS_r9); - - // MBMS session info list in each MCH - RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] = - &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; - LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i, - RC.mac[Mod_idP]->common_channels[0]. - mbms_SessionList[i]->list.count); - } + if (pmch_InfoList != NULL) { + + // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); + + LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", + pmch_InfoList->list.count); + + for (i = 0; i < pmch_InfoList->list.count; i++) { + RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] = + &pmch_InfoList->list.array[i]->pmch_Config_r9; + + LOG_I(MAC, + "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", + i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->sf_AllocEnd_r9); + LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", + i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->mch_SchedulingPeriod_r9); + LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->dataMCS_r9); + + // MBMS session info list in each MCH + RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] = + &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; + LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i, + RC.mac[Mod_idP]->common_channels[0]. + mbms_SessionList[i]->list.count); } + } + #endif LOG_D(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req); @@ -1016,495 +982,12 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, phycfg.Mod_id = Mod_idP; phycfg.CC_id = CC_idP; phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; - + if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); } RC.mac[Mod_idP]->scheduler_mode = global_scheduler_mode; return(0); } - -int -rrc_mac_config_req_ue(module_id_t Mod_idP, - int CC_idP, - uint8_t eNB_index, - RadioResourceConfigCommonSIB_t * - radioResourceConfigCommon, - struct PhysicalConfigDedicated - *physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) - SCellToAddMod_r10_t * sCellToAddMod_r10, - //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, -#endif - MeasObjectToAddMod_t ** measObj, - MAC_MainConfig_t * mac_MainConfig, - long logicalChannelIdentity, - LogicalChannelConfig_t * logicalChannelConfig, - MeasGapConfig_t * measGapConfig, - TDD_Config_t * tdd_Config, - MobilityControlInfo_t * mobilityControlInfo, - uint8_t * SIwindowsize, - uint16_t * SIperiod, - ARFCN_ValueEUTRA_t * ul_CarrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t * - additionalSpectrumEmission, - struct MBSFN_SubframeConfigList - *mbsfn_SubframeConfigList -#if defined(Rel10) || defined(Rel14) - , uint8_t MBMS_Flag, - MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, - PMCH_InfoList_r9_t * pmch_InfoList -#endif -#ifdef CBA - , uint8_t num_active_cba_groups, uint16_t cba_rnti -#endif - ) -{ - - int i; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); - - LOG_I(MAC, "[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n", - Mod_idP, eNB_index); - - if (tdd_Config != NULL) { - UE_mac_inst[Mod_idP].tdd_Config = tdd_Config; - } - - - if (tdd_Config && SIwindowsize && SIperiod) { - phy_config_sib1_ue(Mod_idP, 0, eNB_index, tdd_Config, - *SIwindowsize, *SIperiod); - } - - if (radioResourceConfigCommon != NULL) { - UE_mac_inst[Mod_idP].radioResourceConfigCommon = - radioResourceConfigCommon; - phy_config_sib2_ue(Mod_idP, 0, eNB_index, - radioResourceConfigCommon, ul_CarrierFreq, - ul_Bandwidth, additionalSpectrumEmission, - mbsfn_SubframeConfigList); - } - // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup - if (logicalChannelConfig != NULL) { - LOG_I(MAC, - "[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n", - Mod_idP, eNB_index); - UE_mac_inst[Mod_idP].logicalChannelConfig[logicalChannelIdentity] = - logicalChannelConfig; - UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity] = 0; // initilize the bucket for this lcid - - AssertFatal(logicalChannelConfig->ul_SpecificParameters != NULL, - "[UE %d] LCID %ld NULL ul_SpecificParameters\n", - Mod_idP, logicalChannelIdentity); - UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size - if (logicalChannelConfig->ul_SpecificParameters-> - logicalChannelGroup != NULL) { - UE_mac_inst[Mod_idP].scheduling_info. - LCGID[logicalChannelIdentity] = - *logicalChannelConfig->ul_SpecificParameters-> - logicalChannelGroup; - LOG_D(MAC, - "[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n", - Mod_idP, logicalChannelIdentity, - *logicalChannelConfig-> - ul_SpecificParameters->logicalChannelGroup); - } else { - UE_mac_inst[Mod_idP].scheduling_info. - LCGID[logicalChannelIdentity] = MAX_NUM_LCGID; - } - UE_mac_inst[Mod_idP]. - scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0; - } - - if (mac_MainConfig != NULL) { - LOG_I(MAC, - "[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n", - Mod_idP, eNB_index); - UE_mac_inst[Mod_idP].macConfig = mac_MainConfig; - UE_mac_inst[Mod_idP].measGapConfig = measGapConfig; - - if (mac_MainConfig->ul_SCH_Config) { - - if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) { - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = - (uint16_t) * - mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; - } else { - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = -#ifndef Rel14 - (uint16_t) - MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity -#else - (uint16_t) PeriodicBSR_Timer_r12_infinity; -#endif - ; - } - - if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) { - UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = - (uint16_t) * mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; - } else { - UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = - (uint16_t) - MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; - } - phy_config_harq_ue(Mod_idP, 0, eNB_index, - UE_mac_inst[Mod_idP]. - scheduling_info.maxHARQ_Tx); - - if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) { - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = - (uint16_t) mac_MainConfig->ul_SCH_Config-> - retxBSR_Timer; - } else { -#ifndef Rel14 - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = - (uint16_t) - MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; -#else - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = - (uint16_t) RetxBSR_Timer_r12_sf2560; -#endif - } - } -#if defined(Rel10) || defined(Rel14) - - if (mac_MainConfig->ext1 - && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { - UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = - (uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9; - } else { - UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0; - } - - if (mac_MainConfig->ext2 - && mac_MainConfig->ext2->mac_MainConfig_v1020) { - if (mac_MainConfig->ext2-> - mac_MainConfig_v1020->extendedBSR_Sizes_r10) { - UE_mac_inst[Mod_idP].scheduling_info. - extendedBSR_Sizes_r10 = - (uint16_t) * - mac_MainConfig->ext2-> - mac_MainConfig_v1020->extendedBSR_Sizes_r10; - } else { - UE_mac_inst[Mod_idP].scheduling_info. - extendedBSR_Sizes_r10 = (uint16_t) 0; - } - if (mac_MainConfig->ext2->mac_MainConfig_v1020-> - extendedPHR_r10) { - UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = - (uint16_t) * - mac_MainConfig->ext2->mac_MainConfig_v1020-> - extendedPHR_r10; - } else { - UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = - (uint16_t) 0; - } - } else { - UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = - (uint16_t) 0; - UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = - (uint16_t) 0; - } -#endif - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF = - MAC_UE_BSR_TIMER_NOT_RUNNING; - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF = - MAC_UE_BSR_TIMER_NOT_RUNNING; - - UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE; - - LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", - Mod_idP, - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF, - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF); - - UE_mac_inst[Mod_idP].scheduling_info.drx_config = - mac_MainConfig->drx_Config; - UE_mac_inst[Mod_idP].scheduling_info.phr_config = - mac_MainConfig->phr_Config; - - if (mac_MainConfig->phr_Config) { - UE_mac_inst[Mod_idP].PHR_state = - mac_MainConfig->phr_Config->present; - UE_mac_inst[Mod_idP].PHR_reconfigured = 1; - UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = - mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer; - UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer; - UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = - mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange; - } else { - UE_mac_inst[Mod_idP].PHR_reconfigured = 0; - UE_mac_inst[Mod_idP].PHR_state = - MAC_MainConfig__phr_Config_PR_setup; - UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = - MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; - UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = - MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; - UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = - MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; - } - - UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF = - get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP]. - scheduling_info.periodicPHR_Timer); - UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF = - get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP]. - scheduling_info.prohibitPHR_Timer); - UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db = - get_db_dl_PathlossChange(UE_mac_inst[Mod_idP]. - scheduling_info.PathlossChange); - UE_mac_inst[Mod_idP].PHR_reporting_active = 0; - LOG_D(MAC, - "[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", - Mod_idP, - (mac_MainConfig->phr_Config) ? mac_MainConfig-> - phr_Config->present : -1, - UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF, - UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF, - UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db); - } - - - if (physicalConfigDedicated != NULL) { - phy_config_dedicated_ue(Mod_idP, 0, eNB_index, - physicalConfigDedicated); - UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc - } -#if defined(Rel10) || defined(Rel14) - - if (sCellToAddMod_r10 != NULL) { - - - phy_config_dedicated_scell_ue(Mod_idP, eNB_index, - sCellToAddMod_r10, 1); - UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0 - } -#endif - - if (measObj != NULL) { - if (measObj[0] != NULL) { - UE_mac_inst[Mod_idP].n_adj_cells = - measObj[0]->measObject.choice. - measObjectEUTRA.cellsToAddModList->list.count; - LOG_I(MAC, "Number of adjacent cells %d\n", - UE_mac_inst[Mod_idP].n_adj_cells); - - for (i = 0; i < UE_mac_inst[Mod_idP].n_adj_cells; i++) { - UE_mac_inst[Mod_idP].adj_cell_id[i] = - measObj[0]->measObject.choice. - measObjectEUTRA.cellsToAddModList->list.array[i]-> - physCellId; - LOG_I(MAC, "Cell %d : Nid_cell %d\n", i, - UE_mac_inst[Mod_idP].adj_cell_id[i]); - } - - phy_config_meas_ue(Mod_idP, 0, eNB_index, - UE_mac_inst[Mod_idP].n_adj_cells, - UE_mac_inst[Mod_idP].adj_cell_id); - } - } - - - if (mobilityControlInfo != NULL) { - - LOG_D(MAC, "[UE%d] MAC Reset procedure triggered by RRC eNB %d \n", - Mod_idP, eNB_index); - ue_mac_reset(Mod_idP, eNB_index); - - if (mobilityControlInfo->radioResourceConfigCommon. - rach_ConfigCommon) { - memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - rach_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.rach_ConfigCommon, - sizeof(RACH_ConfigCommon_t)); - } - - memcpy((void *) &UE_mac_inst[Mod_idP]. - radioResourceConfigCommon->prach_Config.prach_ConfigInfo, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.prach_Config.prach_ConfigInfo, - sizeof(PRACH_ConfigInfo_t)); - UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - prach_Config.rootSequenceIndex = - mobilityControlInfo->radioResourceConfigCommon. - prach_Config.rootSequenceIndex; - - if (mobilityControlInfo->radioResourceConfigCommon. - pdsch_ConfigCommon) { - memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - pdsch_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.pdsch_ConfigCommon, - sizeof(PDSCH_ConfigCommon_t)); - } - // not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon - memcpy((void *) &UE_mac_inst[Mod_idP]. - radioResourceConfigCommon->pusch_ConfigCommon, - (void *) &mobilityControlInfo-> - radioResourceConfigCommon.pusch_ConfigCommon, - sizeof(PUSCH_ConfigCommon_t)); - - if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) { - /* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config, - (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, - sizeof(PHICH_Config_t)); */ - } - - if (mobilityControlInfo->radioResourceConfigCommon. - pucch_ConfigCommon) { - memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - pucch_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.pucch_ConfigCommon, - sizeof(PUCCH_ConfigCommon_t)); - } - - if (mobilityControlInfo-> - radioResourceConfigCommon.soundingRS_UL_ConfigCommon) { - memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - soundingRS_UL_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.soundingRS_UL_ConfigCommon, - sizeof(SoundingRS_UL_ConfigCommon_t)); - } - - if (mobilityControlInfo-> - radioResourceConfigCommon.uplinkPowerControlCommon) { - memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - uplinkPowerControlCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.uplinkPowerControlCommon, - sizeof(UplinkPowerControlCommon_t)); - } - //configure antennaInfoCommon somewhere here.. - if (mobilityControlInfo->radioResourceConfigCommon.p_Max) { - //to be configured - } - - if (mobilityControlInfo->radioResourceConfigCommon.tdd_Config) { - UE_mac_inst[Mod_idP].tdd_Config = - mobilityControlInfo->radioResourceConfigCommon.tdd_Config; - } - - if (mobilityControlInfo-> - radioResourceConfigCommon.ul_CyclicPrefixLength) { - memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - ul_CyclicPrefixLength, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.ul_CyclicPrefixLength, - sizeof(UL_CyclicPrefixLength_t)); - } - // store the previous rnti in case of failure, and set thenew rnti - UE_mac_inst[Mod_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti; - UE_mac_inst[Mod_idP].crnti = - ((mobilityControlInfo-> - newUE_Identity.buf[0]) | (mobilityControlInfo-> - newUE_Identity.buf[1] << 8)); - LOG_I(MAC, "[UE %d] Received new identity %x from %d\n", Mod_idP, - UE_mac_inst[Mod_idP].crnti, eNB_index); - UE_mac_inst[Mod_idP].rach_ConfigDedicated = - malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated)); - - if (mobilityControlInfo->rach_ConfigDedicated) { - memcpy((void *) UE_mac_inst[Mod_idP].rach_ConfigDedicated, - (void *) mobilityControlInfo->rach_ConfigDedicated, - sizeof(*mobilityControlInfo->rach_ConfigDedicated)); - } - - phy_config_afterHO_ue(Mod_idP, 0, eNB_index, mobilityControlInfo, - 0); - } - - - if (mbsfn_SubframeConfigList != NULL) { - LOG_I(MAC, - "[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", - Mod_idP, mbsfn_SubframeConfigList->list.count); - UE_mac_inst[Mod_idP].num_sf_allocation_pattern = - mbsfn_SubframeConfigList->list.count; - - for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) { - LOG_I(MAC, - "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", - Mod_idP, i); - UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] = - mbsfn_SubframeConfigList->list.array[i]; - // LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP, - // UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); - } - } -#if defined(Rel10) || defined(Rel14) - - if (mbsfn_AreaInfoList != NULL) { - LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n", - Mod_idP, mbsfn_AreaInfoList->list.count); - UE_mac_inst[Mod_idP].num_active_mbsfn_area = - mbsfn_AreaInfoList->list.count; - - for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) { - UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] = - mbsfn_AreaInfoList->list.array[i]; - LOG_I(MAC, - "[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", - Mod_idP, i, - UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_RepetitionPeriod_r9); - phy_config_sib13_ue(Mod_idP, 0, eNB_index, i, - UE_mac_inst[Mod_idP]. - mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); - } - } - - if (pmch_InfoList != NULL) { - - // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); - - LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n", - Mod_idP); - - for (i = 0; i < pmch_InfoList->list.count; i++) { - UE_mac_inst[Mod_idP].pmch_Config[i] = - &pmch_InfoList->list.array[i]->pmch_Config_r9; - LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", - Mod_idP, i, - UE_mac_inst[Mod_idP]. - pmch_Config[i]->mch_SchedulingPeriod_r9); - } - - UE_mac_inst[Mod_idP].mcch_status = 1; - } -#endif -#ifdef CBA - - if (cba_rnti) { - UE_mac_inst[Mod_idP].cba_rnti[num_active_cba_groups - 1] = - cba_rnti; - LOG_D(MAC, - "[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n", - Mod_idP, Mod_idP % num_active_cba_groups, cba_rnti, - eNB_index, num_active_cba_groups); - phy_config_cba_rnti(Mod_idP, CC_idP, eNB_flagP, eNB_index, - cba_rnti, num_active_cba_groups - 1, - num_active_cba_groups); - } -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); - - return (0); -} diff --git a/openair2/LAYER2/MAC/config_NB_IoT.h b/openair2/LAYER2/MAC/config_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..0e497e3b0f407b9c3da8fd7d357375a5596f8422 --- /dev/null +++ b/openair2/LAYER2/MAC/config_NB_IoT.h @@ -0,0 +1,301 @@ + +/*! \file config_NB_IoT.h + * \brief configured structures used by scheduler + * \author NTUST BMW Lab./ + * \date 2017 + * \email: + * \version 1.0 + * + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +//#include "NB_IoT_Message_definitions.h" + +#define NUMBER_OF_SIBS_MAX_NB_IoT 6 + +///MIB +typedef enum operationModeInf{ + iNB_IoTand_SamePCI_r13 = 1, + iNB_IoTand_DifferentPCI_r13 = 2, + guardband_r13 = 3, + standalone_r13 = 4 +}operationModeInf_t; + +///SIB1_SchedulingInfo_NB_IoT_r13 +typedef enum si_Periodicity{ + si_Periodicity_rf64=640, + si_Periodicity_rf128=1280, + si_Periodicity_rf256=2560, + si_Periodicity_rf512=5120, + si_Periodicity_rf1024=10240, + si_Periodicity_rf2048=20480, + si_Periodicity_rf4096=40960 +}si_Periodicity_NB_IoT; + +typedef enum si_RepetitionPattern{ + si_RepetitionPattern_every2ndRF=0, + si_RepetitionPattern_every4thRF, + si_RepetitionPattern_every8thRF, + si_RepetitionPattern_every16thRF +}si_RepetitionPattern_NB_IoT; + +typedef enum sib_MappingInfo{ + sib2_v=0x1, + sib3_v=0x2, + sib4_v=0x4, + sib5_v=0x8, + sib14_v=0x10, + sib16_v=0x20 +}sib_MappingInfo_NB_IoT; + +typedef enum si_TB{ + si_TB_56=2, + si_TB_120=2, + si_TB_208=8, + si_TB_256=8, + si_TB_328=8, + si_TB_440=8, + si_TB_552=8, + si_TB_680=8 +}si_TB_NB_IoT; + +///RACH_ConfigCommon configuration + +typedef enum ra_ResponseWindowSize{ + ra_ResponseWindowSize_pp2=2, + ra_ResponseWindowSize_pp3=3, + ra_ResponseWindowSize_pp4=4, + ra_ResponseWindowSize_pp5=5, + ra_ResponseWindowSize_pp6=6, + ra_ResponseWindowSize_pp7=7, + ra_ResponseWindowSize_pp8=8, + ra_ResponseWindowSize_pp10=10 +}ra_ResponseWindowSize_NB_IoT; + +typedef enum mac_ContentionResolutionTimer{ + mac_ContentionResolutionTimer_pp1=1, + mac_ContentionResolutionTimer_pp2=2, + mac_ContentionResolutionTimer_pp3=3, + mac_ContentionResolutionTimer_pp4=4, + mac_ContentionResolutionTimer_pp8=8, + mac_ContentionResolutionTimer_pp16=16, + mac_ContentionResolutionTimer_pp32=32, + mac_ContentionResolutionTimer_pp64=64 +}mac_ContentionResolutionTimer_NB_IoT; + +///NPRACH_ConfigSIB configuration + +typedef enum nprach_Periodicity{ + nprach_Periodicity_ms40=40, + nprach_Periodicity_ms80=80, + nprach_Periodicity_ms160=160, + nprach_Periodicity_ms240=240, + nprach_Periodicity_ms320=320, + nprach_Periodicity_ms640=640, + nprach_Periodicity_ms1280=1280, + nprach_Periodicity_ms2560=2560 +}nprach_Periodicity_NB_IoT; + +typedef enum nprach_StartTime{ + nprach_StartTime_ms8=8, + nprach_StartTime_ms16=16, + nprach_StartTime_ms32=32, + nprach_StartTime_ms64=64, + nprach_StartTime_ms128=128, + nprach_StartTime_ms256=256, + nprach_StartTime_ms512=512, + nprach_StartTime_ms1024=1024 +}nprach_StartTime_NB_IoT; + +typedef enum nprach_SubcarrierOffset{ + nprach_SubcarrierOffset_n0=0, + nprach_SubcarrierOffset_n12=12, + nprach_SubcarrierOffset_n24=24, + nprach_SubcarrierOffset_n36=36, + nprach_SubcarrierOffset_n2=2, + nprach_SubcarrierOffset_n18=18, + nprach_SubcarrierOffset_n34=34 +}nprach_SubcarrierOffset_NB_IoT; + +typedef enum nprach_NumSubcarriers{ + nprach_NumSubcarriers_n12=12, + nprach_NumSubcarriers_n24=24, + nprach_NumSubcarriers_n36=36, + nprach_NumSubcarriers_n48=48 +}nprach_NumSubcarriers_NB_IoT; + +typedef enum nprach_SubcarrierMSG3_RangeStart{ + nprach_SubcarrierMSG3_RangeStart_zero=0, + nprach_SubcarrierMSG3_RangeStart_oneThird=1/3, + nprach_SubcarrierMSG3_RangeStart_twoThird=2/3, + nprach_SubcarrierMSG3_RangeStart_one=1 +}nprach_SubcarrierMSG3_RangeStart_NB_IoT; + +typedef enum maxNumPreambleAttemptCE{ + maxNumPreambleAttemptCE_n3=3, + maxNumPreambleAttemptCE_n4=4, + maxNumPreambleAttemptCE_n5=5, + maxNumPreambleAttemptCE_n6=6, + maxNumPreambleAttemptCE_n7=7, + maxNumPreambleAttemptCE_n8=8, + maxNumPreambleAttemptCE_n10=10 +}maxNumPreambleAttemptCE_NB_IoT; + +typedef enum numRepetitionsPerPreambleAttempt{ + numRepetitionsPerPreambleAttempt_n1=1, + numRepetitionsPerPreambleAttempt_n2=2, + numRepetitionsPerPreambleAttempt_n4=4, + numRepetitionsPerPreambleAttempt_n8=8, + numRepetitionsPerPreambleAttempt_n16=16, + numRepetitionsPerPreambleAttempt_n32=32, + numRepetitionsPerPreambleAttempt_n64=64, + numRepetitionsPerPreambleAttempt_n128=128 +}numRepetitionsPerPreambleAttempt_NB_IoT; + +typedef enum npdcch_NumRepetitions_RA{ + npdcch_NumRepetitions_RA_r1=1, + npdcch_NumRepetitions_RA_r2=2, + npdcch_NumRepetitions_RA_r4=4, + npdcch_NumRepetitions_RA_r8=8, + npdcch_NumRepetitions_RA_r16=16, + npdcch_NumRepetitions_RA_r32=32, + npdcch_NumRepetitions_RA_r64=64, + npdcch_NumRepetitions_RA_r128=128, + npdcch_NumRepetitions_RA_r256=256, + npdcch_NumRepetitions_RA_r512=512, + npdcch_NumRepetitions_RA_r1024=1024, + npdcch_NumRepetitions_RA_r2048=2048 +}npdcch_NumRepetitions_RA_NB_IoT; + +typedef enum npdcch_StartSF_CSS_RA{ + npdcch_StartSF_CSS_RA_v1dot5=3/2, + npdcch_StartSF_CSS_RA_v2=2, + npdcch_StartSF_CSS_RA_v4=4, + npdcch_StartSF_CSS_RA_v8=8, + npdcch_StartSF_CSS_RA_v16=16, + npdcch_StartSF_CSS_RA_v32=32, + npdcch_StartSF_CSS_RA_v48=48, + npdcch_StartSF_CSS_RA_v64=64 +}npdcch_StartSF_CSS_RA_NB_IoT; + +typedef enum npdcch_Offset_RA{ + zero=0, + oneEighth=1/8, + oneFourth=1/4, + threeEighth=3/8 +}npdcch_Offset_RA_NB_IoT; + +typedef enum si_window_length_e{ + ms160=160, + ms320=320, + ms480=480, + ms640=640, + ms960=960, + ms1280=1280, + ms1600=1600 +}si_window_length_t; + +typedef enum si_periodicity_e{ + rf64=640, + rf128=1280, + rf256=2560, + rf512=5120, + rf1024=10240, + rf2048=20480, + rf4096=40960 +}si_periodicity_t; + +typedef enum si_repetition_pattern_e{ + every2ndRF=20, + every4thRF=40, + every8thRF=80, + every16thRF=160 +}si_repetition_pattern_t; + +typedef enum si_tb_e{ + b56=2, + b120=2, + b208=8, + b256=8, + b328=8, + b440=8, + b552=8, + b680=8 +}si_tb_t; + + +typedef struct sibs_NB_IoT_sched_s{ + si_periodicity_t si_periodicity; + si_repetition_pattern_t si_repetition_pattern; + sib_MappingInfo_NB_IoT sib_mapping_info; //bit vector + si_tb_t si_tb; + +}sibs_NB_IoT_sched_t; + + +///-------------------------------------------------------MAC--------------------------------------------------------------------/// +typedef struct sib1_NB_IoT_sched_s{ + int repetitions; // 4, 8, 16 + int starting_rf; +}sib1_NB_IoT_sched_t; + +typedef struct { + + uint32_t mac_ra_ResponseWindowSize_NB_IoT; + uint32_t mac_ContentionResolutionTimer_NB_IoT; + +}mac_RACH_ConfigCommon_NB_IoT; + +typedef struct { + + uint32_t mac_nprach_Periodicity_NB_IoT; + uint32_t mac_nprach_StartTime_NB_IoT; + uint32_t mac_nprach_SubcarrierOffset_NB_IoT; + uint32_t mac_nprach_NumSubcarriers_NB_IoT; + uint32_t mac_nprach_SubcarrierMSG3_RangeStart_NB_IoT; + uint32_t mac_maxNumPreambleAttemptCE_NB_IoT; + uint32_t mac_numRepetitionsPerPreambleAttempt_NB_IoT; + // css + uint32_t mac_npdcch_NumRepetitions_RA_NB_IoT; // rmax + uint32_t mac_npdcch_StartSF_CSS_RA_NB_IoT; // G + uint32_t mac_npdcch_Offset_RA_NB_IoT; // alpha offset + +}mac_NPRACH_ConfigSIB_NB_IoT; + +typedef struct{ + //npdcch-NumRepetitions-r13 + uint32_t R_max; + //npdcch-StartSF-USS-r13 + double G; + //npdcch-Offset-USS-r13 + double a_offset; +}npdcch_ConfigDedicated_NB_IoT; + +typedef struct rrc_config_NB_IoT_s{ + + ///MIB + uint16_t schedulingInfoSIB1_NB_IoT; + + ///SIB1 + uint32_t cellIdentity_NB_IoT; + + sib1_NB_IoT_sched_t sib1_NB_IoT_sched_config; + ///SIBS + sibs_NB_IoT_sched_t sibs_NB_IoT_sched[NUMBER_OF_SIBS_MAX_NB_IoT]; + si_window_length_t si_window_length; + uint32_t si_radio_frame_offset; + + ///SIB2 mac_RACH_ConfigCommon_NB_IoT + mac_RACH_ConfigCommon_NB_IoT mac_RACH_ConfigCommon[3]; + + ///SIB2 mac_NPRACH_ConfigSIB_NB_IoT + mac_NPRACH_ConfigSIB_NB_IoT mac_NPRACH_ConfigSIB[3]; + + ///NPDCCH Dedicated config + npdcch_ConfigDedicated_NB_IoT npdcch_ConfigDedicated[3]; + +}rrc_config_NB_IoT_t; + +#endif diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..0b27955dad61a096ffebeaf9b87e0b8fd556ba93 --- /dev/null +++ b/openair2/LAYER2/MAC/config_ue.c @@ -0,0 +1,622 @@ + +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 config.c + * \brief UE and eNB configuration performed by RRC or as a consequence of RRC procedures + * \author Navid Nikaein and Raymond Knopp + * \date 2010 - 2014 + * \version 0.1 + * \email: navid.nikaein@eurecom.fr + * @ingroup _mac + + */ + +#include "COMMON/platform_types.h" +#include "COMMON/platform_constants.h" +#include "SCHED_UE/sched_UE.h" +#include "SystemInformationBlockType2.h" +//#include "RadioResourceConfigCommonSIB.h" +#include "RadioResourceConfigDedicated.h" +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#include "PRACH-ConfigSIB-v1310.h" +#endif +#include "MeasGapConfig.h" +#include "MeasObjectToAddModList.h" +#include "TDD-Config.h" +#include "MAC-MainConfig.h" +#include "mac.h" +#include "mac_proto.h" +#include "mac_extern.h" +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "PHY/INIT/phy_init.h" + +#include "common/ran_context.h" +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "MBSFN-AreaInfoList-r9.h" +#include "MBSFN-AreaInfo-r9.h" +#include "MBSFN-SubframeConfigList.h" +#include "PMCH-InfoList-r9.h" +#endif + +extern void mac_init_cell_params(int Mod_idP,int CC_idP); +extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + +extern uint8_t nfapi_mode; + + +/* sec 5.9, 36.321: MAC Reset Procedure */ +void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) +{ + + //Resetting Bj + UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0; + UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0; + UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0; + + //Stopping all timers + + //timeAlignmentTimer expires + + // PHY changes for UE MAC reset + phy_reset_ue(module_idP, 0, eNB_index); + + // notify RRC to relase PUCCH/SRS + // cancel all pending SRs + UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; + UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; + + //Set BSR Trigger Bmp and remove timer flags + UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; + + // stop ongoing RACH procedure + + // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any + UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check! + UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; + + + ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure + +} + +int32_t **rxdata; +int32_t **txdata; + + +int +rrc_mac_config_req_ue(module_id_t Mod_idP, + int CC_idP, + uint8_t eNB_index, + RadioResourceConfigCommonSIB_t * + radioResourceConfigCommon, + struct PhysicalConfigDedicated + *physicalConfigDedicated, +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + SCellToAddMod_r10_t * sCellToAddMod_r10, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + MeasObjectToAddMod_t ** measObj, + MAC_MainConfig_t * mac_MainConfig, + long logicalChannelIdentity, + LogicalChannelConfig_t * logicalChannelConfig, + MeasGapConfig_t * measGapConfig, + TDD_Config_t * tdd_Config, + MobilityControlInfo_t * mobilityControlInfo, + uint8_t * SIwindowsize, + uint16_t * SIperiod, + ARFCN_ValueEUTRA_t * ul_CarrierFreq, + long *ul_Bandwidth, + AdditionalSpectrumEmission_t * + additionalSpectrumEmission, + struct MBSFN_SubframeConfigList + *mbsfn_SubframeConfigList +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , uint8_t MBMS_Flag, + MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, + PMCH_InfoList_r9_t * pmch_InfoList +#endif +#ifdef CBA + , uint8_t num_active_cba_groups, uint16_t cba_rnti +#endif +#if defined(Rel14) + ,config_action_t config_action + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + ) +{ + + int i; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); + + LOG_I(MAC, "[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n", + Mod_idP, eNB_index); + + if (tdd_Config != NULL) { + UE_mac_inst[Mod_idP].tdd_Config = tdd_Config; + } + + + if (tdd_Config && SIwindowsize && SIperiod) { + phy_config_sib1_ue(Mod_idP, 0, eNB_index, tdd_Config, + *SIwindowsize, *SIperiod); + } + + if (radioResourceConfigCommon != NULL) { + UE_mac_inst[Mod_idP].radioResourceConfigCommon = + radioResourceConfigCommon; + phy_config_sib2_ue(Mod_idP, 0, eNB_index, + radioResourceConfigCommon, ul_CarrierFreq, + ul_Bandwidth, additionalSpectrumEmission, + mbsfn_SubframeConfigList); + } + // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup + if (logicalChannelConfig != NULL) { + LOG_I(MAC, + "[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n", + Mod_idP, eNB_index); + UE_mac_inst[Mod_idP].logicalChannelConfig[logicalChannelIdentity] = + logicalChannelConfig; + UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity] = 0; // initilize the bucket for this lcid + + AssertFatal(logicalChannelConfig->ul_SpecificParameters != NULL, + "[UE %d] LCID %ld NULL ul_SpecificParameters\n", + Mod_idP, logicalChannelIdentity); + UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size + if (logicalChannelConfig->ul_SpecificParameters-> + logicalChannelGroup != NULL) { + UE_mac_inst[Mod_idP].scheduling_info. + LCGID[logicalChannelIdentity] = + *logicalChannelConfig->ul_SpecificParameters-> + logicalChannelGroup; + LOG_D(MAC, + "[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n", + Mod_idP, logicalChannelIdentity, + *logicalChannelConfig-> + ul_SpecificParameters->logicalChannelGroup); + } else { + UE_mac_inst[Mod_idP].scheduling_info. + LCGID[logicalChannelIdentity] = MAX_NUM_LCGID; + } + UE_mac_inst[Mod_idP]. + scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0; + } + + if (mac_MainConfig != NULL) { + LOG_I(MAC, + "[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n", + Mod_idP, eNB_index); + UE_mac_inst[Mod_idP].macConfig = mac_MainConfig; + UE_mac_inst[Mod_idP].measGapConfig = measGapConfig; + + if (mac_MainConfig->ul_SCH_Config) { + + if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) { + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = + (uint16_t) * + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; + } else { + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = +#if (RRC_VERSION < MAKE_VERSION(12, 0, 0)) + (uint16_t) + MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity +#else + (uint16_t) PeriodicBSR_Timer_r12_infinity; +#endif + ; + } + + if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) { + UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = + (uint16_t) * mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; + } else { + UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = + (uint16_t) + MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + } + if(nfapi_mode!=3) + phy_config_harq_ue(Mod_idP, 0, eNB_index, + UE_mac_inst[Mod_idP]. + scheduling_info.maxHARQ_Tx); + + if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) { + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = + (uint16_t) mac_MainConfig->ul_SCH_Config-> + retxBSR_Timer; + } else { +#if (RRC_VERSION < MAKE_VERSION(12, 0, 0)) + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = + (uint16_t) + MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; +#else + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = + (uint16_t) RetxBSR_Timer_r12_sf2560; +#endif + } + } +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + if (mac_MainConfig->ext1 + && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { + UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = + (uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9; + } else { + UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0; + } + + if (mac_MainConfig->ext2 + && mac_MainConfig->ext2->mac_MainConfig_v1020) { + if (mac_MainConfig->ext2-> + mac_MainConfig_v1020->extendedBSR_Sizes_r10) { + UE_mac_inst[Mod_idP].scheduling_info. + extendedBSR_Sizes_r10 = + (uint16_t) * + mac_MainConfig->ext2-> + mac_MainConfig_v1020->extendedBSR_Sizes_r10; + } else { + UE_mac_inst[Mod_idP].scheduling_info. + extendedBSR_Sizes_r10 = (uint16_t) 0; + } + if (mac_MainConfig->ext2->mac_MainConfig_v1020-> + extendedPHR_r10) { + UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = + (uint16_t) * + mac_MainConfig->ext2->mac_MainConfig_v1020-> + extendedPHR_r10; + } else { + UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = + (uint16_t) 0; + } + } else { + UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = + (uint16_t) 0; + UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = + (uint16_t) 0; + } +#endif + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF = + MAC_UE_BSR_TIMER_NOT_RUNNING; + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF = + MAC_UE_BSR_TIMER_NOT_RUNNING; + + UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE; + + LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", + Mod_idP, + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF, + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF); + + UE_mac_inst[Mod_idP].scheduling_info.drx_config = + mac_MainConfig->drx_Config; + UE_mac_inst[Mod_idP].scheduling_info.phr_config = + mac_MainConfig->phr_Config; + + if (mac_MainConfig->phr_Config) { + UE_mac_inst[Mod_idP].PHR_state = + mac_MainConfig->phr_Config->present; + UE_mac_inst[Mod_idP].PHR_reconfigured = 1; + UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer; + UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer; + UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange; + } else { + UE_mac_inst[Mod_idP].PHR_reconfigured = 0; + UE_mac_inst[Mod_idP].PHR_state = + MAC_MainConfig__phr_Config_PR_setup; + UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = + MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; + UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = + MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; + UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = + MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; + } + + UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF = + get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP]. + scheduling_info.periodicPHR_Timer); + UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF = + get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP]. + scheduling_info.prohibitPHR_Timer); + UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db = + get_db_dl_PathlossChange(UE_mac_inst[Mod_idP]. + scheduling_info.PathlossChange); + UE_mac_inst[Mod_idP].PHR_reporting_active = 0; + LOG_D(MAC, + "[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", + Mod_idP, + (mac_MainConfig->phr_Config) ? mac_MainConfig-> + phr_Config->present : -1, + UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF, + UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF, + UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db); + } + + + if (physicalConfigDedicated != NULL) { + if(nfapi_mode!=3) + phy_config_dedicated_ue(Mod_idP, 0, eNB_index, + physicalConfigDedicated); + UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc + } +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + if (sCellToAddMod_r10 != NULL) { + + + phy_config_dedicated_scell_ue(Mod_idP, eNB_index, + sCellToAddMod_r10, 1); + UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0 + } +#endif + + if (measObj != NULL) { + if (measObj[0] != NULL) { + UE_mac_inst[Mod_idP].n_adj_cells = + measObj[0]->measObject.choice. + measObjectEUTRA.cellsToAddModList->list.count; + LOG_I(MAC, "Number of adjacent cells %d\n", + UE_mac_inst[Mod_idP].n_adj_cells); + + for (i = 0; i < UE_mac_inst[Mod_idP].n_adj_cells; i++) { + UE_mac_inst[Mod_idP].adj_cell_id[i] = + measObj[0]->measObject.choice. + measObjectEUTRA.cellsToAddModList->list.array[i]-> + physCellId; + LOG_I(MAC, "Cell %d : Nid_cell %d\n", i, + UE_mac_inst[Mod_idP].adj_cell_id[i]); + } + + phy_config_meas_ue(Mod_idP, 0, eNB_index, + UE_mac_inst[Mod_idP].n_adj_cells, + UE_mac_inst[Mod_idP].adj_cell_id); + } + } + + + if (mobilityControlInfo != NULL) { + + LOG_D(MAC, "[UE%d] MAC Reset procedure triggered by RRC eNB %d \n", + Mod_idP, eNB_index); + ue_mac_reset(Mod_idP, eNB_index); + + if (mobilityControlInfo->radioResourceConfigCommon. + rach_ConfigCommon) { + memcpy((void *) + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + rach_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.rach_ConfigCommon, + sizeof(RACH_ConfigCommon_t)); + } + + memcpy((void *) &UE_mac_inst[Mod_idP]. + radioResourceConfigCommon->prach_Config.prach_ConfigInfo, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.prach_Config.prach_ConfigInfo, + sizeof(PRACH_ConfigInfo_t)); + UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + prach_Config.rootSequenceIndex = + mobilityControlInfo->radioResourceConfigCommon. + prach_Config.rootSequenceIndex; + + if (mobilityControlInfo->radioResourceConfigCommon. + pdsch_ConfigCommon) { + memcpy((void *) + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + pdsch_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.pdsch_ConfigCommon, + sizeof(PDSCH_ConfigCommon_t)); + } + // not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon + memcpy((void *) &UE_mac_inst[Mod_idP]. + radioResourceConfigCommon->pusch_ConfigCommon, + (void *) &mobilityControlInfo-> + radioResourceConfigCommon.pusch_ConfigCommon, + sizeof(PUSCH_ConfigCommon_t)); + + if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) { + /* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config, + (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, + sizeof(PHICH_Config_t)); */ + } + + if (mobilityControlInfo->radioResourceConfigCommon. + pucch_ConfigCommon) { + memcpy((void *) + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + pucch_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.pucch_ConfigCommon, + sizeof(PUCCH_ConfigCommon_t)); + } + + if (mobilityControlInfo-> + radioResourceConfigCommon.soundingRS_UL_ConfigCommon) { + memcpy((void *) + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + soundingRS_UL_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.soundingRS_UL_ConfigCommon, + sizeof(SoundingRS_UL_ConfigCommon_t)); + } + + if (mobilityControlInfo-> + radioResourceConfigCommon.uplinkPowerControlCommon) { + memcpy((void *) + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + uplinkPowerControlCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.uplinkPowerControlCommon, + sizeof(UplinkPowerControlCommon_t)); + } + //configure antennaInfoCommon somewhere here.. + if (mobilityControlInfo->radioResourceConfigCommon.p_Max) { + //to be configured + } + + if (mobilityControlInfo->radioResourceConfigCommon.tdd_Config) { + UE_mac_inst[Mod_idP].tdd_Config = + mobilityControlInfo->radioResourceConfigCommon.tdd_Config; + } + + if (mobilityControlInfo-> + radioResourceConfigCommon.ul_CyclicPrefixLength) { + memcpy((void *) + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + ul_CyclicPrefixLength, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.ul_CyclicPrefixLength, + sizeof(UL_CyclicPrefixLength_t)); + } + // store the previous rnti in case of failure, and set thenew rnti + UE_mac_inst[Mod_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti; + UE_mac_inst[Mod_idP].crnti = + ((mobilityControlInfo-> + newUE_Identity.buf[0]) | (mobilityControlInfo-> + newUE_Identity.buf[1] << 8)); + LOG_I(MAC, "[UE %d] Received new identity %x from %d\n", Mod_idP, + UE_mac_inst[Mod_idP].crnti, eNB_index); + UE_mac_inst[Mod_idP].rach_ConfigDedicated = + malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated)); + + if (mobilityControlInfo->rach_ConfigDedicated) { + memcpy((void *) UE_mac_inst[Mod_idP].rach_ConfigDedicated, + (void *) mobilityControlInfo->rach_ConfigDedicated, + sizeof(*mobilityControlInfo->rach_ConfigDedicated)); + } + + phy_config_afterHO_ue(Mod_idP, 0, eNB_index, mobilityControlInfo, + 0); + } + + + if (mbsfn_SubframeConfigList != NULL) { + LOG_I(MAC, + "[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", + Mod_idP, mbsfn_SubframeConfigList->list.count); + UE_mac_inst[Mod_idP].num_sf_allocation_pattern = + mbsfn_SubframeConfigList->list.count; + + for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) { + LOG_I(MAC, + "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", + Mod_idP, i); + UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] = + mbsfn_SubframeConfigList->list.array[i]; + // LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP, + // UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); + } + } +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + if (mbsfn_AreaInfoList != NULL) { + LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n", + Mod_idP, mbsfn_AreaInfoList->list.count); + UE_mac_inst[Mod_idP].num_active_mbsfn_area = + mbsfn_AreaInfoList->list.count; + + for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) { + UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] = + mbsfn_AreaInfoList->list.array[i]; + LOG_I(MAC, + "[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", + Mod_idP, i, + UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_RepetitionPeriod_r9); + phy_config_sib13_ue(Mod_idP, 0, eNB_index, i, + UE_mac_inst[Mod_idP]. + mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); + } + } + + if (pmch_InfoList != NULL) { + + // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); + + LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n", + Mod_idP); + + for (i = 0; i < pmch_InfoList->list.count; i++) { + UE_mac_inst[Mod_idP].pmch_Config[i] = + &pmch_InfoList->list.array[i]->pmch_Config_r9; + LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", + Mod_idP, i, + UE_mac_inst[Mod_idP]. + pmch_Config[i]->mch_SchedulingPeriod_r9); + } + + UE_mac_inst[Mod_idP].mcch_status = 1; + } +#endif +#ifdef CBA + + if (cba_rnti) { + UE_mac_inst[Mod_idP].cba_rnti[num_active_cba_groups - 1] = + cba_rnti; + LOG_D(MAC, + "[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n", + Mod_idP, Mod_idP % num_active_cba_groups, cba_rnti, + eNB_index, num_active_cba_groups); + phy_config_cba_rnti(Mod_idP, CC_idP, eNB_flagP, eNB_index, + cba_rnti, num_active_cba_groups - 1, + num_active_cba_groups); + } +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); + //for D2D + #if defined(Rel10) || defined(Rel14) + switch (config_action) { + case CONFIG_ACTION_ADD: + if (sourceL2Id){ + UE_mac_inst[Mod_idP].sourceL2Id = *sourceL2Id; + LOG_I(MAC,"[UE %d] Configure source L2Id 0x%08x \n", Mod_idP, *sourceL2Id ); + } + if (destinationL2Id) { + LOG_I(MAC,"[UE %d] Configure destination L2Id 0x%08x\n", Mod_idP, *destinationL2Id ); + int j = 0; + int i = 0; + for (i=0; i< MAX_NUM_DEST; i++) { + if ((UE_mac_inst[Mod_idP].destinationList[i] == 0) && (j == 0)) j = i+1; + if (UE_mac_inst[Mod_idP].destinationList[i] == *destinationL2Id) break; //destination already exists! + } + if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[Mod_idP].destinationList[j-1] = *destinationL2Id; + UE_mac_inst[Mod_idP].numCommFlows++; + } + break; + case CONFIG_ACTION_REMOVE: + //TODO + break; + default: + break; + } + + #endif + + return (0); +} diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..02f9c47ea5cdc7d0443cd13c64492460014d4adb --- /dev/null +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -0,0 +1,543 @@ + +/*! \file defs_NB_IoT.c + * \brief MAC layer structures + * \author NTUST BMW Lab./ + * \date 2017 + * \email: + * \version 1.0 + * + */ +#ifndef __LAYER2_MAC_DEFS_NB_IOT_H__ +#define __LAYER2_MAC_DEFS_NB_IOT_H__ +#ifdef USER_MODE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#endif +//#include "COMMON/openair_defs.h" +#include "COMMON/platform_constants.h" +#include "COMMON/mac_rrc_primitives.h" +#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" +//#include "PHY/defs.h" +#include "PHY/defs_L1_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "config_NB_IoT.h" +// MAC definition +#define MAX_FRAME 0xfffff +#define NUM_FRAME 0x100000 +#define MAX_SUBFRAME 10485760 + +#define MAX(a, b) (((a)>(b))?(a):(b)) + +// RA-RNTI: 1+SFN_id>>2 +#define RA_RNTI_LOW 0x0001 // SFN_id = 0 +#define RA_RNTI_HIGH 0x0100 // SFN_id = 1023 +#define C_RNTI_LOW 0x0101 +#define C_RNTI_HIGH + +// ULSCH LCHAN IDs +/*!\brief LCID of extended power headroom for ULSCH */ +#define EXTENDED_POWER_HEADROOM 25 +/*!\brief LCID of power headroom for ULSCH */ +#define POWER_HEADROOM 26 +/*!\brief LCID of CRNTI for ULSCH */ +#define CRNTI 27 +/*!\brief LCID of truncated BSR for ULSCH */ +#define TRUNCATED_BSR 28 +/*!\brief LCID of short BSR for ULSCH */ +#define SHORT_BSR 29 +/*!\brief LCID of long BSR for ULSCH */ +#define LONG_BSR 30 +/*! \brief Values of CCCH LCID for DLSCH */ +#define CCCH_LCHANID 0 +/*!\brief Values of BCCH logical channel */ +#define BCCH 3 // SI +/*!\brief Values of PCCH logical channel */ +#define PCCH 4 // Paging +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH 0 // srb0 +/*!\brief DCCH / SRB1 logical channel */ +#define DCCH 1 // srb1 +/*!\brief DCCH1 / SRB2 logical channel */ +#define DCCH1 2 // srb2 +/*!\brief DTCH DRB1 logical channel */ +#define DTCH 3 // LCID +/*!\brief MCCH logical channel */ +#define MCCH 4 +/*!\brief MTCH logical channel */ +#define MTCH 1 +// DLSCH LCHAN ID +/*!\brief LCID of UE contention resolution identity for DLSCH*/ +#define UE_CONT_RES 28 +/*!\brief LCID of timing advance for DLSCH */ +#define TIMING_ADV_CMD 29 +/*!\brief LCID of discontinous reception mode for DLSCH */ +#define DRX_CMD 30 +/*!\brief LCID of padding LCID for DLSCH */ +#define SHORT_PADDING 31 + + +typedef enum tone_type_e +{ + sixtone = 0, + threetone, + singletone1, + singletone2, + singletone3 +}tone_type_t; + +typedef enum channel_NB_IoT_e +{ + NPDCCH = 0, + NPUSCH, + NPDSCH +}channel_NB_IoT_t; + +typedef enum{ + UL = 0, + DL +}message_direction_t; + +#define MAX_MAX_MOBILES_PER_ENB_NB_IoT 20 +#define SCH_PAYLOAD_SIZE_MAX_NB_IoT 320 +#define MAX_NUMBER_OF_SIBs_NB_IoT 16 + +/*!\brief Values of BCCH0 logical channel for MIB*/ +#define BCCH0_NB_IoT 11 // MIB-NB_IoT +/*!\brief Values of BCCH1 logical channel for SIBs */ +#define BCCH1_NB_IoT 12 // SI-SIB-NB_IoTs +/*!\brief Values of PCCH logical channel */ +#define PCCH_NB_IoT 13 // Paging XXX not used for the moment +#define MCCH_NB_IoT 14 +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH_NB_IoT 0 // srb0 ---> XXX exactly the same as in LTE (commented for compilation purposes) +/*!\brief DCCH0 / SRB1bis logical channel */ +#define DCCH0_NB_IoT 3 // srb1bis +/*!\brief DCCH1 / SRB1 logical channel */ +#define DCCH1_NB_IoT 1 // srb1 //XXX we redefine it for the SRB1 +/*!\brief DTCH0 DRB0 logical channel */ +#define DTCH0_NB_IoT 4 // DRB0 +/*!\brief DTCH1 DRB1 logical channel */ +#define DTCH1_NB_IoT 5 // DRB1 +/*Index of UE contention resoulution logical channel*/ +#define UE_CONTENTION_RESOLUTION 28 +/*Index of TIMING_ADVANCE logical channel*/ +#define TIMING_ADVANCE 29 +/*Index of DRX_COMMAND logical channel*/ +#define DRX_COMMAND 30 +/*Index of PADDING logical channel*/ +#define PADDING 31 + + +/// NPRACH-ParametersList-NB_IoT-r13 from 36.331 RRC spec defined in PHY +/*typedef struct NPRACH_Parameters_NB_IoT{ + + /// the period time for nprach + int nprach_Periodicity; + /// for the start time for the NPRACH resource from 40ms-2560ms + int nprach_StartTime; + /// for the subcarrier of set to the NPRACH preamble from n0 - n34 + int nprach_SubcarrierOffset; + ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) + int nprach_NumSubcarriers; + /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 + int nprach_SubcarrierMSG3_RangeStart; + /// The max preamble transmission attempt for the CE level from 1 - 128 + int maxNumPreambleAttemptCE; + /// Number of NPRACH repetitions per attempt for each NPRACH resource + int numRepetitionsPerPreambleAttempt; + /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) + int npdcch_NumRepetitions_RA; + /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) + int npdcch_StartSF_CSS_RA; + /// Fractional period offset of starting subframe for NPDCCH common search space + int npdcch_Offset_RA; + +} nprach_parameters_NB_IoT_t;*/ + +/*! \brief Downlink SCH PDU Structure */ +typedef struct { + uint8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; + uint32_t pdu_size; +} __attribute__ ((__packed__)) DLSCH_PDU_NB_IoT; + +/*! \brief eNB template for UE context information */ +typedef struct { + // C-RNTI of UE + rnti_t rnti; + // UE CE level + int CE_level; + // Direction of transmission(DL:0\UL:1\NONE:-1) + int32_t direction; + // DCI Reptition + uint32_t R_dci; + // MAX repetition + uint32_t R_max; + + // HARQ round + uint32_t HARQ_round; + /*Downlink information*/ + + /// DLSCH pdu + DLSCH_PDU_NB_IoT DLSCH_pdu; + // PDU size + uint32_t DLSCH_pdu_size; + // Data Reptition + uint32_t R_dl; + // MCS index + uint32_t I_mcs_dl; + // total downlink buffer DCCH0_NB_IoT + uint32_t dl_buffer_DCCH0_NB_IoT; + // NDI + int oldNDI_DL; + //HARQ ACK/NACK repetition + uint32_t R_harq; + + /*Uplink information*/ + int oldNDI_UL; + // Uplink data repeat, now just follow the rach repeat number + uint32_t R_ul; + // PHR value (0-3) + uint32_t PHR; + // The uplink data size from BSR or DVI + uint32_t ul_total_buffer; + // Determine if this UE support multi-tone transmission or not + int multi_tone; + // Next UE_template ID + int next; + // Previous UE_template ID + int prev; + // MSG4 complete + int RRC_connected; + // UE active flag + int active; + +} UE_TEMPLATE_NB_IoT; + +/*36331 NPDCCH-ConfigDedicated-NB_IoT*/ +typedef struct{ + //npdcch-NumRepetitions-r13 + uint32_t R_max; + //npdcch-StartSF-USS-r13 + double G; + //npdcch-Offset-USS-r13 + double a_offset; + //NPDCCH period + uint32_t T; + //Starting subfrane of Search Space which is mod T + uint32_t ss_start_uss; +}NPDCCH_config_dedicated_NB_IoT_t; + + +/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ +typedef struct { + + /// DCI template and MAC connection parameters for UEs + UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_MAX_MOBILES_PER_ENB_NB_IoT]; + + /// NPDCCH Period and searching space info + NPDCCH_config_dedicated_NB_IoT_t NPDCCH_config_dedicated; + //int next[MAX_MAX_MOBILES_PER_ENB_NB_IoT]; + // -1:No UE in list + int head; + // -1:No UE in list + int tail; + int num_UEs; + //boolean_t active[MAX_MAX_MOBILES_PER_ENB_NB_IoT]; + +} UE_list_NB_IoT_t; + + +typedef struct{ + + // flag to indicate scheduing MIB-NB_IoT + uint8_t flag_MIB; + // flag to indicate scheduling SIB1-NB_IoT + uint8_t flag_SIB1; + // flag to indicate scheduling SIBs-NB_IoT + uint8_t flag_SIBs[MAX_NUMBER_OF_SIBs_NB_IoT]; + // flag to indicate scheduling type2 NPDCCH CSS with different CE level + uint8_t flag_type2_css[3]; + // flag to indicate scheduling type1 NPDCCH CSS with different CE level + uint8_t flag_type1_css[3]; + // flag to indicate scheduling NPDCCH USS with UE list + uint8_t flag_uss[MAX_MAX_MOBILES_PER_ENB_NB_IoT]; + // flag to indicate scheduling sib1/MIB + uint8_t flag_fix_scheduling; + // number of the type2 css to schedule in this period + uint8_t num_type2_css_run; + // number of the type1 css to schedule in this period + uint8_t num_type1_css_run; + // number of the uss to schedule in this period + uint8_t num_uss_run; + +}scheduling_flag_t; + +typedef struct available_resource_UL_s{ + + ///Resource start subframe + uint32_t start_subframe; + ///Resource end subframe + uint32_t end_subframe; + // pointer to next node + struct available_resource_UL_s *next, *prev; + +}available_resource_UL_t; + +typedef struct available_resource_DL_s{ + uint32_t start_subframe; + uint32_t end_subframe; + + struct available_resource_DL_s *next, *prev; +}available_resource_DL_t; + +/*Structure used for scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end,sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + uint32_t start_h, end_h; + uint32_t start_f, end_f; + uint32_t start_sf, end_sf; + //whcih available resource node is used + available_resource_DL_t *node; +}sched_temp_DL_NB_IoT_t; + +/*!\brief MAC subheader short with 7bit Length field */ +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L:7; // octet 2 LSB + uint8_t F:1; // octet 2 MSB +} __attribute__((__packed__))SCH_SUBHEADER_SHORT_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:7; + uint8_t F:1; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:8; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_EXTEND_NB_IoT; +/*!\brief MAC subheader short without length field */ +typedef struct { + uint8_t LCID:5; + uint8_t F2:1; + uint8_t E:1; + uint8_t R:1; +} __attribute__((__packed__))SCH_SUBHEADER_FIXED_NB_IoT; + + +/*! \brief Uplink SCH PDU Structure */ +typedef struct { + int8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; /*!< \brief SACH payload */ + uint16_t Pdu_size; +} __attribute__ ((__packed__)) ULSCH_PDU_NB_IoT; + +typedef struct { + uint8_t PH:6; + uint8_t R:2; +} __attribute__((__packed__))POWER_HEADROOM_CMD_NB_IoT; + +typedef struct { + uint8_t RAPID:6; + uint8_t T:1; + uint8_t E:1; +} __attribute__((__packed__))RA_HEADER_RAPID_NB_IoT; + +/*Structure used for UL scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end, sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + //uint32_t start_h, end_h; + //uint32_t start_f, end_f; + //uint32_t start_sf, end_sf; + // information for allocating the resource + int tone; + int scheduling_delay; + int subcarrier_indication; + int ACK_NACK_resource_field; + available_resource_UL_t *node; +}sched_temp_UL_NB_IoT_t; + +typedef struct Available_available_resource_DL{ + + ///Available Resoruce for sixtone + available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame; + uint32_t sixtone_end_subframe; + ///Available Resoruce for threetone + available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame; + uint32_t threetone_end_subframe; + ///Available Resoruce for singletone1 + available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame; + uint32_t singletone1_end_subframe; + ///Available Resoruce for singletone2 + available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame; + uint32_t singletone2_end_subframe; + ///Available Resoruce for singletone3 + available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame; + uint32_t singletone3_end_subframe; + +}available_resource_tones_UL_t; + +typedef struct schedule_result{ + // The subframe read by output handler + uint32_t output_subframe; + // SDU length + uint32_t sdu_length; + // MAC PDU + uint8_t *DLSCH_pdu; + // The data direction indicated by this DCI + uint8_t direction; + // pointer to DCI + void *DCI_pdu; + // when all the procedure related to this DCI, enable this flag + boolean_t DCI_release; + // Indicate the channel which to transmit + channel_NB_IoT_t channel; + // rnti + rnti_t rnti; + // 0 = TC-RNTI , 1 = RA-RNTI, 2 = P-RNTI, 3 = others + uint8_t rnti_type; + // 0 = data, 1 = ACK/NACK + uint8_t npusch_format; + //HARQ ACK/NACK repetition + uint32_t R_harq; + // pointer to next node + struct schedule_result *next; + + uint32_t end_subframe; + + uint8_t *rar_buffer; + +}schedule_result_t; + +/*Flag structure used for trigger each scheduler*/ +typedef struct{ + scheduling_flag_t scheduling_flag; + //sched_temp_DL_NB_IoT_t sched_result_DL; + //resource grid for Uplink + available_resource_tones_UL_t *UL_resource; + //scheduling result read by output handler + schedule_result_t *schedule_result_list_UL; + schedule_result_t *schedule_result_list_DL; +}SCHEDULE_NB_IoT_t; + +typedef struct{ + uint32_t num_dlsf_per_period; + uint16_t *sf_to_dlsf_table; + uint16_t *dlsf_to_sf_table; +}DLSF_INFO_t; + +typedef enum ce_level_e{ + ce0=0, + ce1, + ce2, + ce_level_total +}ce_level_t; + + + +/*! \brief eNB template for the Random access information */ +typedef struct RA_TEMPLATE_NB_IoT_s{ + + boolean_t active; + uint32_t msg3_retransmit_count; + uint32_t msg4_retransmit_count; + uint16_t ta; + uint8_t preamble_index; + ce_level_t ce_level; + rnti_t ue_rnti; + rnti_t ra_rnti; + struct RA_TEMPLATE_NB_IoT_s *next, *prev; + boolean_t wait_msg4_ack; + boolean_t wait_msg3_ack; + uint8_t rar_buffer[7]; + +} RA_TEMPLATE_NB_IoT; + +typedef struct RA_template_list_s{ + RA_TEMPLATE_NB_IoT *head; + RA_TEMPLATE_NB_IoT *tail; +}RA_template_list_t; + + +/*! \brief top level eNB MAC structure */ +typedef struct eNB_MAC_INST_NB_IoT_s { + /// Ethernet parameters for northbound midhaul interface + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface + eth_params_t eth_params_s; + + uint8_t Mod_id; + // System + uint32_t hyper_system_frame; + uint32_t system_frame; + uint32_t sub_frame; + + uint32_t current_subframe; + /// Pointer to IF module instance for PHY + IF_Module_t *if_inst; + // RA + RA_template_list_t RA_msg2_list; + RA_template_list_t RA_msg3_list; + RA_template_list_t RA_msg4_list; + + RA_TEMPLATE_NB_IoT RA_template[MAX_MAX_MOBILES_PER_ENB_NB_IoT]; + + //int32_t last_tx_subframe; + + // for tool + int32_t sib1_flag[64]; + int32_t sib1_count[64]; + int32_t sib1_period; + uint16_t dlsf_table[64]; + int32_t sibs_table[256]; + + // channel config + + //USS list + //Number of USS period is used + int num_uss_list; + UE_list_NB_IoT_t *UE_list_spec; + + scheduling_flag_t scheduling_flag; + + uint32_t schedule_subframe_DL; + uint32_t schedule_subframe_UL; + + rrc_config_NB_IoT_t rrc_config; + + nfapi_config_request_t config; + + IF_Module_NB_IoT_t *if_inst_NB_IoT; +} eNB_MAC_INST_NB_IoT; + +// actually not here, but for now put it here +typedef struct { + uint32_t bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */ + uint32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ + uint32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ + uint32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ + boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ +} mac_rlc_status_resp_NB_IoT_t; + +// global variables + +nprach_parameters_NB_IoT_t nprach_list[3]; + +//DLSF Table +DLSF_INFO_t DLSF_information; + +#endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index e1e2e48583084c583f9664dc5b11e4bc0eacbc73..86a7dbe98f3c2e9646a02d38fc259798aa35c9a3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -30,34 +30,26 @@ */ #include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" - -#include "LAYER2/MAC/proto.h" +#include "LAYER2/MAC/mac_proto.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#if defined(FLEXRAN_AGENT_SB_IF) //Agent-related headers #include "flexran_agent_extern.h" #include "flexran_agent_mac.h" -#include "flexran_agent_mac_proto.h" -#endif /* for fair round robin SCHED */ #include "eNB_scheduler_fairRR.h" @@ -66,10 +58,13 @@ #include "intertask_interface.h" #endif +#include "assertions.h" + #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 extern RAN_CONTEXT_t RC; +extern int phy_test; uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; @@ -77,409 +72,280 @@ uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; void schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; - struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; - uint8_t TSFC; - uint16_t deltaTSFC; // bitmap - uint8_t srs_SubframeConfig; - - // table for TSFC (Period) and deltaSFC (offset) - const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD - const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD - - uint16_t srsPeriodicity, srsOffset; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - soundingRS_UL_ConfigCommon = - &cc[CC_id].radioResourceConfigCommon-> - soundingRS_UL_ConfigCommon; - // check if SRS is enabled in this frame/subframe - if (soundingRS_UL_ConfigCommon) { - srs_SubframeConfig = - soundingRS_UL_ConfigCommon->choice.setup. - srs_SubframeConfig; - if (cc[CC_id].tdd_Config == NULL) { // FDD - deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; - } else { // TDD - deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; - } - // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC - uint16_t tmp = (subframeP % TSFC); - - if ((1 << tmp) & deltaTSFC) { - // This is an SRS subframe, loop over UEs - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) - continue; - ul_req = - &RC.mac[module_idP]->UL_req[CC_id]. - ul_config_request_body; - - - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status - (module_idP, - UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) - continue; - - AssertFatal(UE_list->UE_template[CC_id] - [UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); - - if ((soundingRS_UL_ConfigDedicated = - UE_list->UE_template[CC_id] - [UE_id]. - physicalConfigDedicated->soundingRS_UL_ConfigDedicated) - != NULL) { - if (soundingRS_UL_ConfigDedicated->present == - SoundingRS_UL_ConfigDedicated_PR_setup) { - get_srs_pos(&cc[CC_id], - soundingRS_UL_ConfigDedicated->choice. - setup.srs_ConfigIndex, - &srsPeriodicity, &srsOffset); - if (((10 * frameP + - subframeP) % srsPeriodicity) == - srsOffset) { - // Program SRS - ul_req->srs_present = 1; - nfapi_ul_config_request_pdu_t - * ul_config_pdu = - &ul_req-> - ul_config_pdu_list - [ul_req->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof - (nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_SRS_PDU_TYPE; - ul_config_pdu->pdu_size = - 2 + (uint8_t) (2 + - sizeof - (nfapi_ul_config_srs_pdu)); - ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; - ul_config_pdu->srs_pdu.srs_pdu_rel8.size = - (uint8_t) - sizeof(nfapi_ul_config_srs_pdu); - ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = - UE_list->UE_template[CC_id][UE_id]. - rnti; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.srs_bandwidth = - soundingRS_UL_ConfigDedicated-> - choice.setup.srs_Bandwidth; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.frequency_domain_position - = - soundingRS_UL_ConfigDedicated-> - choice.setup.freqDomainPosition; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.srs_hopping_bandwidth = - soundingRS_UL_ConfigDedicated-> - choice.setup.srs_HoppingBandwidth;; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.transmission_comb = - soundingRS_UL_ConfigDedicated-> - choice.setup.transmissionComb; - ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = - soundingRS_UL_ConfigDedicated-> - choice.setup.srs_ConfigIndex; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.sounding_reference_cyclic_shift - = - soundingRS_UL_ConfigDedicated-> - choice.setup.cyclicShift; - // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// - // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = - (frameP << 4) + subframeP; - RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req->number_of_pdus++; - } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) - } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) - } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) - } // for (UE_id ... - } // if((1<<tmp) & deltaTSFC) - - } // SRS config - } + + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_body_t *ul_req; + int CC_id, UE_id; + COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; + struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; + uint8_t TSFC; + uint16_t deltaTSFC; // bitmap + uint8_t srs_SubframeConfig; + + // table for TSFC (Period) and deltaSFC (offset) + const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD + const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD + + uint16_t srsPeriodicity, srsOffset; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon; + // check if SRS is enabled in this frame/subframe + if (soundingRS_UL_ConfigCommon) { + srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; + if (cc[CC_id].tdd_Config == NULL) { // FDD + deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; + } else { // TDD + deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; + } + // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC + uint16_t tmp = (subframeP % TSFC); + + if ((1 << tmp) & deltaTSFC) { + // This is an SRS subframe, loop over UEs + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (!RC.mac[module_idP]->UE_list.active[UE_id]) continue; + ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet + if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; + + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); + + if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { + if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { + get_srs_pos(&cc[CC_id], + soundingRS_UL_ConfigDedicated->choice. + setup.srs_ConfigIndex, + &srsPeriodicity, &srsOffset); + if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) { + // Program SRS + ul_req->srs_present = 1; + nfapi_ul_config_request_pdu_t * ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu)); + ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; + ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu); + ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; + ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; + ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; + ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; + ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// + // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->number_of_pdus++; + } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) + } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) + } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) + } // for (UE_id ... + } // if((1<<tmp) & deltaTSFC) + + } // SRS config + } } void schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - COMMON_channels_t *cc; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - struct CQI_ReportPeriodic *cqi_ReportPeriodic; - uint16_t Npd, N_OFFSET_CQI; - int H; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - - cc = &eNB->common_channels[CC_id]; - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - - ul_req = - &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; - - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status - (module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) - continue; - - AssertFatal(UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated - != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); - - if (UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - cqi_ReportConfig) { - if ((cqi_ReportPeriodic = - UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportPeriodic) != NULL - && (cqi_ReportPeriodic->present != - CQI_ReportPeriodic_PR_release)) { - //Rel8 Periodic CQI/PMI/RI reporting - - get_csi_params(cc, cqi_ReportPeriodic, &Npd, - &N_OFFSET_CQI, &H); - - if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI opportunity - UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id] = - (((frameP * 10) + subframeP) / Npd) % H; - // Program CQI - nfapi_ul_config_request_pdu_t *ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req-> - number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = - 2 + (uint8_t) (2 + - sizeof - (nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - ue_information.ue_information_rel8.rnti = - UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - pucch_index = - cqi_ReportPeriodic->choice. - setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - dl_cqi_pmi_size = - get_rel8_dl_cqi_pmi_size - (&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, - get_tmode(module_idP, CC_id, UE_id), - cqi_ReportPeriodic); - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - -#if defined(Rel10) || defined(Rel14) - // PUT rel10-13 UCI options here + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + COMMON_channels_t *cc; + nfapi_ul_config_request_body_t *ul_req; + int CC_id, UE_id; + struct CQI_ReportPeriodic *cqi_ReportPeriodic; + uint16_t Npd, N_OFFSET_CQI; + int H; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + + cc = &eNB->common_channels[CC_id]; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (!UE_list->active[UE_id]) continue; + + ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + + // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; + + AssertFatal(UE_list-> + UE_template[CC_id][UE_id].physicalConfigDedicated + != NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); + + if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { + if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL + && (cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_release)) { + //Rel8 Periodic CQI/PMI/RI reporting + + get_csi_params(cc, cqi_ReportPeriodic, &Npd, + &N_OFFSET_CQI, &H); + + if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI opportunity + UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id] = (((frameP * 10) + subframeP) / Npd) % H; + // Program CQI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, + sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, + get_tmode(module_idP, CC_id, UE_id), + cqi_ReportPeriodic); + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // PUT rel10-13 UCI options here #endif - } else - if ((cqi_ReportPeriodic->choice.setup. - ri_ConfigIndex) - && ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161))) { // RI opportunity - // Program RI - nfapi_ul_config_request_pdu_t *ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req-> - number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = - 2 + (uint8_t) (2 + - sizeof - (nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - ue_information.ue_information_rel8.rnti = - UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - pucch_index = - cqi_ReportPeriodic->choice. - setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = - (frameP << 4) + subframeP; - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } - - } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { - } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + } else + if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) + && ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161))) { // RI opportunity + // Program RI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, + sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } + } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { + } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { } void schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - nfapi_ul_config_request_t *ul_req; - nfapi_ul_config_request_body_t *ul_req_body; - int CC_id; - int UE_id; - SchedulingRequestConfig_t *SRconfig; - int skip_ue; - int is_harq; - nfapi_ul_config_sr_information sr; - int i; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = - (frameP << 4) + subframeP; - - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) - continue; - - ul_req = &RC.mac[module_idP]->UL_req[CC_id]; - ul_req_body = &ul_req->ul_config_request_body; - - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status - (module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) - continue; - - AssertFatal(UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated - != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); - - if ((SRconfig = - UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - schedulingRequestConfig) != NULL) { - if (SRconfig->present == SchedulingRequestConfig_PR_setup) { - if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period - if ((subframeP % 5) != - SRconfig->choice.setup.sr_ConfigIndex) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period - if (subframeP != - (SRconfig->choice.setup.sr_ConfigIndex - 5)) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period - if ((10 * (frameP & 1) + subframeP) != - (SRconfig->choice.setup.sr_ConfigIndex - 15)) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period - if ((10 * (frameP & 3) + subframeP) != - (SRconfig->choice.setup.sr_ConfigIndex - 35)) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period - if ((10 * (frameP & 7) + subframeP) != - (SRconfig->choice.setup.sr_ConfigIndex - 75)) - continue; - } - } // SRconfig->present == SchedulingRequestConfig_PR_setup) - } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) - - // if we get here there is some PUCCH1 reception to schedule for SR - - skip_ue = 0; - is_harq = 0; - // check that there is no existing UL grant for ULSCH which overrides the SR - for (i = 0; i < ul_req_body->number_of_pdus; i++) { - if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && - (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { - skip_ue = 1; - break; - } - /* if there is already an HARQ pdu, convert to SR_HARQ */ - else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && - (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { - is_harq = 1; - break; - } - } + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_t *ul_req; + nfapi_ul_config_request_body_t *ul_req_body; + int CC_id; + int UE_id; + SchedulingRequestConfig_t *SRconfig; + int skip_ue; + int is_harq; + nfapi_ul_config_sr_information sr; + int i; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (!RC.mac[module_idP]->UE_list.active[UE_id]) continue; + + ul_req = &RC.mac[module_idP]->UL_req[CC_id]; + ul_req_body = &ul_req->ul_config_request_body; + + // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; + + AssertFatal(UE_list-> + UE_template[CC_id][UE_id].physicalConfigDedicated!= NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); + + if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig) != NULL) { + if (SRconfig->present == SchedulingRequestConfig_PR_setup) { + if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period + if ((subframeP % 5) != SRconfig->choice.setup.sr_ConfigIndex) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period + if (subframeP != (SRconfig->choice.setup.sr_ConfigIndex - 5)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period + if ((10 * (frameP & 1) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 15)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period + if ((10 * (frameP & 3) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 35)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period + if ((10 * (frameP & 7) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 75)) continue; + } + } // SRconfig->present == SchedulingRequestConfig_PR_setup) + } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) + + // if we get here there is some PUCCH1 reception to schedule for SR + + skip_ue = 0; + is_harq = 0; + // check that there is no existing UL grant for ULSCH which overrides the SR + for (i = 0; i < ul_req_body->number_of_pdus; i++) { + if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && + (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { + skip_ue = 1; + break; + } + /* if there is already an HARQ pdu, convert to SR_HARQ */ + else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && + (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { + is_harq = 1; + break; + } + } - // drop the allocation because ULSCH with handle it with BSR - if (skip_ue == 1) - continue; - - LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); - - // check Rel10 or Rel8 SR -#if defined(Rel10) || defined(Rel14) - if ((UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) - && (UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - ext2->schedulingRequestConfig_v1020) - && (UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - ext2->schedulingRequestConfig_v1020)) { - sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; - sr.sr_information_rel10.number_of_pucch_resources = 1; - sr.sr_information_rel10.pucch_index_p1 = - *UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - ext2-> - schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; - LOG_D(MAC,"REL10 PUCCH INDEX P1:%d\n", sr.sr_information_rel10.pucch_index_p1); - } else + // drop the allocation because ULSCH with handle it with BSR + if (skip_ue == 1) continue; + + LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); + + // check Rel10 or Rel8 SR +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) + && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) + && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { + sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; + sr.sr_information_rel10.number_of_pucch_resources = 1; + sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; + LOG_D(MAC,"REL10 PUCCH INDEX P1:%d\n", sr.sr_information_rel10.pucch_index_p1); + } else #endif - { - sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; - sr.sr_information_rel8.pucch_index = - UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - schedulingRequestConfig->choice.setup. - sr_PUCCH_ResourceIndex; - LOG_D(MAC,"REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); - } + { + sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; + sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; + LOG_D(MAC,"REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); + } - /* if there is already an HARQ pdu, convert to SR_HARQ */ - if (is_harq) { - nfapi_ul_config_harq_information h = ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.harq_information; - ul_req_body->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; - } else { - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; - ul_req_body->number_of_pdus++; - } /* if (is_harq) */ - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) - } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) + /* if there is already an HARQ pdu, convert to SR_HARQ */ + if (is_harq) { + nfapi_ul_config_harq_information h = ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.harq_information; + ul_req_body->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; + ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; + } else { + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; + ul_req_body->number_of_pdus++; + } /* if (is_harq) */ + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) + } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) } extern uint8_t nfapi_mode; @@ -488,150 +354,146 @@ void check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, frame_t frameP, sub_frame_t subframeP) { - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; - uint16_t rnti = UE_RNTI(module_idP, UE_id); - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - - // check uplink failure - if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) && - (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) { - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 1) - LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) { - UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1; - - // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe) - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &DL_req[CC_id]. - dl_config_request_body.dl_config_pdu_list[DL_req[CC_id]. - dl_config_request_body.number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), - UE_list->UE_sched_ctrl[UE_id]. - dl_cqi[CC_id], format1A); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0) - && (cc[CC_id].mib->message.dl_Bandwidth < 6), - "illegal dl_Bandwidth %d\n", - (int) cc[CC_id].mib->message.dl_Bandwidth); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding = - pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; - DL_req[CC_id].dl_config_request_body.number_dci++; - DL_req[CC_id].dl_config_request_body.number_pdu++; - DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - LOG_D(MAC, - "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", - UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding); - } else { // ra_pdcch_sent==1 - LOG_D(MAC, - "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n", - UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 80) == 0) - UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 8 frames - } + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + uint16_t rnti = UE_RNTI(module_idP, UE_id); + COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + + // check uplink failure + if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) && + (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) { + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 1) + LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) { + UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1; + + // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe) + nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu]; + memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + UE_list->UE_sched_ctrl[UE_id]. + dl_cqi[CC_id], format1A); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0) && (cc[CC_id].mib->message.dl_Bandwidth < 6), + "illegal dl_Bandwidth %d\n", + (int) cc[CC_id].mib->message.dl_Bandwidth); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; + DL_req[CC_id].dl_config_request_body.number_dci++; + DL_req[CC_id].dl_config_request_body.number_pdu++; + DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + LOG_D(MAC, + "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", + UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.resource_block_coding); + } else { // ra_pdcch_sent==1 + LOG_D(MAC, + "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n", + UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 80) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 8 frames + } - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; - // check threshold - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) { - // note: probably ul_failure_timer is should be less than UE radio link failure time(see T310/N310/N311) - // inform RRC of failure and clear timer - LOG_I(MAC, - "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", - UE_id, rnti); - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP, - rnti); - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; - } - } // ul_failure_timer>0 - - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++; - if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){ - LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); - mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti); - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - }// time > 60s + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; + // check threshold + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) { + // note: probably ul_failure_timer should be less than UE radio link failure time(see T310/N310/N311) + // inform RRC of failure and clear timer + LOG_I(MAC, + "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", + UE_id, rnti); + mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti); + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + + //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future + if (rrc_agent_registered[module_idP]) { + LOG_W(MAC, "notify flexran Agent of UE state change\n"); + agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, + rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } + } + } // ul_failure_timer>0 + +#if 0 + /* U-plane inactivity timer is disabled. Uncomment to re-enable. */ + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++; + if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){ + LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); + mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti); + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + }// time > 60s +#endif } void clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, frame_t frameP, sub_frame_t subframeP) { - nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0]; - nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0]; - nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[CC_idP][subframeP]; - nfapi_tx_request_t *TX_req = &eNB->TX_req[0]; + nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0]; + nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0]; + nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[CC_idP][subframeP]; + nfapi_tx_request_t *TX_req = &eNB->TX_req[0]; - eNB->pdu_index[CC_idP] = 0; + eNB->pdu_index[CC_idP] = 0; - if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF + if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF - DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; - DL_req[CC_idP].dl_config_request_body.number_dci = 0; - DL_req[CC_idP].dl_config_request_body.number_pdu = 0; - DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; - DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; + DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; + DL_req[CC_idP].dl_config_request_body.number_dci = 0; + DL_req[CC_idP].dl_config_request_body.number_pdu = 0; + DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; + DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; - HI_DCI0_req->hi_dci0_request_body.sfnsf = subframeP + (frameP<<4); - HI_DCI0_req->hi_dci0_request_body.number_of_dci = 0; + HI_DCI0_req->hi_dci0_request_body.sfnsf = subframeP + (frameP<<4); + HI_DCI0_req->hi_dci0_request_body.number_of_dci = 0; - UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; - UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now - UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now + UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; + UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now + UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now - TX_req[CC_idP].tx_request_body.number_of_pdus = 0; + TX_req[CC_idP].tx_request_body.number_of_pdus = 0; - } + } } void copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - int CC_id; - eNB_MAC_INST *mac = RC.mac[module_idP]; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][subframeP]; - nfapi_ul_config_request_t *ul_req = &mac->UL_req[CC_id]; - nfapi_ul_config_request_pdu_t *ul_req_pdu = ul_req->ul_config_request_body.ul_config_pdu_list; + int CC_id; + eNB_MAC_INST *mac = RC.mac[module_idP]; - *ul_req = *ul_req_tmp; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - // Restore the pointer - ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu; + nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][subframeP]; + nfapi_ul_config_request_t *ul_req = &mac->UL_req[CC_id]; + nfapi_ul_config_request_pdu_t *ul_req_pdu = ul_req->ul_config_request_body.ul_config_pdu_list; - ul_req->sfn_sf = (frameP<<4) + subframeP; + *ul_req = *ul_req_tmp; - ul_req_tmp->ul_config_request_body.number_of_pdus = 0; + // Restore the pointer + ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu; + ul_req->sfn_sf = (frameP<<4) + subframeP; + ul_req_tmp->ul_config_request_body.number_of_pdus = 0; - if (ul_req->ul_config_request_body.number_of_pdus>0) + if (ul_req->ul_config_request_body.number_of_pdus>0) { LOG_D(PHY, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus); } - memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list, - (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, - ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); + memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list, + (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, + ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); } } @@ -640,177 +502,176 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - int mbsfn_status[MAX_NUM_CCs]; - protocol_ctxt_t ctxt; + int mbsfn_status[MAX_NUM_CCs]; + protocol_ctxt_t ctxt; - int CC_id, i; //,next_i; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - rnti_t rnti; + int CC_id, i = -1; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + rnti_t rnti; - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - -#if defined(FLEXRAN_AGENT_SB_IF) - Protocol__FlexranMessage *msg; -#endif + COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + start_meas(&RC.mac[module_idP]->eNB_scheduler); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, + VCD_FUNCTION_IN); - start_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_IN); + RC.mac[module_idP]->frame = frameP; + RC.mac[module_idP]->subframe = subframeP; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - mbsfn_status[CC_id] = 0; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + mbsfn_status[CC_id] = 0; - // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, 100); - memset(cc[CC_id].vrb_map_UL, 0, 100); + // clear vrb_maps + memset(cc[CC_id].vrb_map, 0, 100); + memset(cc[CC_id].vrb_map_UL, 0, 100); -#if defined(Rel10) || defined(Rel14) - cc[CC_id].mcch_active = 0; +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + cc[CC_id].mcch_active = 0; #endif - RC.mac[module_idP]->frame = frameP; - RC.mac[module_idP]->subframe = subframeP; - - clear_nfapi_information(RC.mac[module_idP], CC_id, frameP, - subframeP); - } - // refresh UE list based on UEs dropped by PHY in previous subframe - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; - - rnti = UE_RNTI(module_idP, i); - CC_id = UE_PCCID(module_idP, i); - - if ((frameP == 0) && (subframeP == 0)) { - LOG_I(MAC, - "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", - rnti, - UE_list->UE_sched_ctrl[i].ul_out_of_sync == - 0 ? "in synch" : "out of sync", - UE_list->UE_template[CC_id][i].phr_info, - UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], - (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, - (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); - } + clear_nfapi_information(RC.mac[module_idP], CC_id, frameP, subframeP); + } - RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + - subframeP] = -63; - if (i == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[module_idP][CC_id]-> - pusch_stats_bsr[i][(frameP * 10) + subframeP]); - // increment this, it is cleared when we receive an sdu - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; - - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; - LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i]. - ul_inactivity_timer, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); - check_ul_failure(module_idP, CC_id, i, frameP, subframeP); - - if (RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) { - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++; - if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >= - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) { - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0; - //clear reestablish_rnti_map - if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres >20){ - for (int ue_id_l = 0; ue_id_l < NUMBER_OF_UE_MAX; ue_id_l++) { - if (reestablish_rnti_map[ue_id_l][0] == rnti) { - // clear currentC-RNTI from map - reestablish_rnti_map[ue_id_l][0] = 0; - reestablish_rnti_map[ue_id_l][1] = 0; - break; - } - } - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rnti, 0, 0,module_idP); - rrc_rlc_remove_ue(&ctxt); - pdcp_remove_UE(&ctxt); - } - for (int ii=0; ii<NUMBER_OF_UE_MAX; ii++) { - LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii]; - if((ulsch != NULL) && (ulsch->rnti == rnti)){ - LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti); - clean_eNb_ulsch(ulsch); - } - } - for (int ii=0; ii<NUMBER_OF_UE_MAX; ii++) { - LTE_eNB_DLSCH_t *dlsch = RC.eNB[module_idP][CC_id]->dlsch[ii][0]; - if((dlsch != NULL) && (dlsch->rnti == rnti)){ - LOG_I(MAC, "clean_eNb_dlsch UE %x \n", rnti); - clean_eNb_dlsch(dlsch); - } - } - - for(int j = 0; j < 10; j++){ - nfapi_ul_config_request_body_t *ul_req_tmp = NULL; - ul_req_tmp = &RC.mac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body; - if(ul_req_tmp){ - int pdu_number = ul_req_tmp->number_of_pdus; - for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){ - if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){ - LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number); - if(pdu_index < pdu_number -1){ - memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); - } - ul_req_tmp->number_of_pdus--; - } - } - } - } - rrc_mac_remove_ue(module_idP,rnti); - } + // refresh UE list based on UEs dropped by PHY in previous subframe + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (UE_list->active[i]) { + + rnti = UE_RNTI(module_idP, i); + CC_id = UE_PCCID(module_idP, i); + + if (((frameP&127) == 0) && (subframeP == 0)) { + LOG_I(MAC, + "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", + rnti, + UE_list->UE_sched_ctrl[i].ul_out_of_sync == + 0 ? "in synch" : "out of sync", + UE_list->UE_template[CC_id][i].phr_info, + UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], + (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, + (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); } + + RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + + subframeP] = -63; + if (i == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME + (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, + RC.eNB[module_idP][CC_id]-> + pusch_stats_bsr[i][(frameP * 10) + subframeP]); + // increment this, it is cleared when we receive an sdu + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; + + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; + LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti, + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i]. + ul_inactivity_timer, + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); + check_ul_failure(module_idP, CC_id, i, frameP, subframeP); + + if (RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) { + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++; + if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >= + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) { + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0; + //clear reestablish_rnti_map + if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres >20){ + for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_ENB; ue_id_l++) { + if (reestablish_rnti_map[ue_id_l][0] == rnti) { + // clear currentC-RNTI from map + reestablish_rnti_map[ue_id_l][0] = 0; + reestablish_rnti_map[ue_id_l][1] = 0; + break; + } + } + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rnti, 0, 0,module_idP); + rrc_rlc_remove_ue(&ctxt); + pdcp_remove_UE(&ctxt); + } + // Note: This should not be done in the MAC! + for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) { + LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii]; + if((ulsch != NULL) && (ulsch->rnti == rnti)){ + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti); + clean_eNb_ulsch(ulsch); + } + } + for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) { + LTE_eNB_DLSCH_t *dlsch = RC.eNB[module_idP][CC_id]->dlsch[ii][0]; + if((dlsch != NULL) && (dlsch->rnti == rnti)){ + void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + LOG_I(MAC, "clean_eNb_dlsch UE %x \n", rnti); + clean_eNb_dlsch(dlsch); + } + } + + for(int j = 0; j < 10; j++){ + nfapi_ul_config_request_body_t *ul_req_tmp = NULL; + ul_req_tmp = &RC.mac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body; + if(ul_req_tmp){ + int pdu_number = ul_req_tmp->number_of_pdus; + for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){ + if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){ + LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number); + if(pdu_index < pdu_number -1){ + memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); + } + ul_req_tmp->number_of_pdus--; + } + } + } + } + rrc_mac_remove_ue(module_idP,rnti); + } + } } + } #if (!defined(PRE_SCD_THREAD)) - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, - NOT_A_RNTI, frameP, subframeP, - module_idP); - pdcp_run(&ctxt); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, + NOT_A_RNTI, frameP, subframeP, + module_idP); + pdcp_run(&ctxt); - rrc_rx_tx(&ctxt, 0, // eNB index, unused in eNB - CC_id); + rrc_rx_tx(&ctxt, CC_id); #endif -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - if (cc[CC_id].MBMS_flag > 0) { - start_meas(&RC.mac[module_idP]->schedule_mch); - mbsfn_status[CC_id] = - schedule_MBMS(module_idP, CC_id, frameP, subframeP); - stop_meas(&RC.mac[module_idP]->schedule_mch); - } + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + if (cc[CC_id].MBMS_flag > 0) { + start_meas(&RC.mac[module_idP]->schedule_mch); + mbsfn_status[CC_id] = schedule_MBMS(module_idP, CC_id, frameP, subframeP); + stop_meas(&RC.mac[module_idP]->schedule_mch); } + } #endif - static int debug_flag=0; - void (*schedule_ulsch_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe); - void (*schedule_ue_spec_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag); - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_DEFAULT){ - schedule_ulsch_p = schedule_ulsch; - schedule_ue_spec_p = schedule_ue_spec; - }else if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - memset(dlsch_ue_select, 0, sizeof(dlsch_ue_select)); - schedule_ulsch_p = schedule_ulsch_fairRR; - schedule_ue_spec_p = schedule_ue_spec_fairRR; - } - if(debug_flag==0){ - LOG_E(MAC,"SCHED_MODE=%d\n",RC.mac[module_idP]->scheduler_mode); - debug_flag=1; - } - // This schedules MIB - if ((subframeP == 0) && (frameP & 3) == 0) - schedule_mib(module_idP, frameP, subframeP); + + static int debug_flag=0; + void (*schedule_ulsch_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe); + void (*schedule_ue_spec_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag); + if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_DEFAULT){ + schedule_ulsch_p = schedule_ulsch; + schedule_ue_spec_p = schedule_dlsch; + }else if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ + memset(dlsch_ue_select, 0, sizeof(dlsch_ue_select)); + schedule_ulsch_p = schedule_ulsch_fairRR; + schedule_ue_spec_p = schedule_ue_spec_fairRR; + } + if(debug_flag==0){ + LOG_E(MAC,"SCHED_MODE=%d\n",RC.mac[module_idP]->scheduler_mode); + debug_flag=1; + } + + // This schedules MIB + + if ((subframeP == 0) && (frameP & 3) == 0) + schedule_mib(module_idP, frameP, subframeP); + if (phy_test == 0){ // This schedules SI for legacy LTE and eMTC starting in subframeP schedule_SI(module_idP, frameP, subframeP); // This schedules Paging in subframeP @@ -829,16 +690,24 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, schedule_CSI(module_idP, frameP, subframeP); // This schedules DLSCH in subframeP schedule_ue_spec_p(module_idP, frameP, subframeP, mbsfn_status); - // Allocate CCEs for good after scheduling is done + } + else{ + schedule_ulsch_phy_test(module_idP,frameP,subframeP); + schedule_ue_spec_phy_test(module_idP,frameP,subframeP,mbsfn_status); + } - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++){ - if(cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP))) - allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2); - } + if (RC.flexran[module_idP]->enabled) + flexran_agent_send_update_stats(module_idP); + + // Allocate CCEs for good after scheduling is done + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + if(cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP))) + allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2); + } - stop_meas(&RC.mac[module_idP]->eNB_scheduler); + stop_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, + VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 73b14af19b6ea9196101195f9ef124a576da57d0..654f69ba91eb83175a96c6b1b0855223575b7e45 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -34,24 +34,20 @@ #include "assertions.h" #include "platform_types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" #include "msc.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" - -#include "LAYER2/MAC/proto.h" +#include "LAYER2/MAC/mac_proto.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" @@ -61,10 +57,14 @@ #include "intertask_interface.h" #endif -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #include "T.h" +#include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; + extern uint8_t nfapi_mode; extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); @@ -118,7 +118,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", ra->rnti); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (ra->rach_resource_type > 0) { LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n", @@ -135,48 +135,35 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = - narrowband_to_first_rb(cc, - ra->msg34_narrowband) + - ra->msg3_first_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = - ra->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = - 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8. - frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = - rvseq[ra->msg3_round]; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = - ((10 * ra->Msg3_frame) + ra->Msg3_subframe) & 7; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = - get_TBS_UL(ra->msg3_mcs, ra->msg3_nb_rb); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb(cc, + ra->msg34_narrowband) + ra->msg3_first_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = ((10 * ra->Msg3_frame) + ra->Msg3_subframe) & 7; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(ra->msg3_mcs, ra->msg3_nb_rb); // Re13 fields - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = - ra->rach_resource_type > 2 ? 2 : 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13. - total_number_of_repetitions = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13. - initial_transmission_sf_io = - (ra->Msg3_frame * 10) + ra->Msg3_subframe; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; } // if (ra->rach_resource_type>0) { else #endif @@ -187,46 +174,36 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, ra->Msg3_subframe); LOG_D(MAC, - "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d)\n", + "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, - ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round); + ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti); - ul_config_pdu = - &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = - ra->msg3_first_rb; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = ra->msg3_first_rb; AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n"); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = - ra->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = - 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8. - frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = - rvseq[ra->msg3_round]; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = - subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = - get_TBS_UL(10, ra->msg3_nb_rb); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10, ra->msg3_nb_rb); ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; // save UL scheduling information for preprocessor for (j = 0; j < ra->msg3_nb_rb; j++) cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; @@ -240,20 +217,19 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = - ra->msg3_first_rb; + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = ra->msg3_first_rb; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; if (nfapi_mode) { oai_nfapi_hi_dci0_req(hi_dci0_req); @@ -294,7 +270,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int rmax = 0; int rep = 0; int reps = 0; @@ -315,11 +291,8 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, if (cc[CC_idP].radioResourceConfigCommon_BR) { - ext4_prach = - cc[CC_idP].radioResourceConfigCommon_BR->ext4-> - prach_ConfigCommon_v1310; - prach_ParametersListCE_r13 = - &ext4_prach->prach_ParametersListCE_r13; + ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; switch (prach_ParametersListCE_r13->list.count) { case 4: @@ -351,110 +324,71 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, // rmax from SIB2 information AssertFatal(rmax < 9, "rmax>8!\n"); - rmax = - 1 << p[ra->rach_resource_type - - 1]->mpdcch_NumRepetition_RA_r13; + rmax = 1 << p[ra->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; // choose r1 by default for RAR (Table 9.1.5-5) rep = 0; // get actual repetition count from Table 9.1.5-3 reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep)); // get narrowband according to higher-layer config - num_nb = - p[ra->rach_resource_type - - 1]->mpdcch_NarrowbandsToMonitor_r13.list.count; - ra->msg2_narrowband = - *p[ra->rach_resource_type - - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[ra-> - preamble_index - % num_nb]; - first_rb = - narrowband_to_first_rb(&cc[CC_idP], ra->msg2_narrowband); + num_nb = p[ra->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.count; + ra->msg2_narrowband = *p[ra->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[ra->preamble_index % num_nb]; + first_rb = narrowband_to_first_rb(&cc[CC_idP], ra->msg2_narrowband); if ((ra->msg2_mpdcch_repetition_cnt == 0) && - (mpdcch_sf_condition - (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) { + (mpdcch_sf_condition(mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) { // MPDCCH configuration for RAR LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming MPDCCH %d repetitions\n", module_idP, frameP, subframeP, reps); - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = - (ra->rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = - ra->msg2_narrowband; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_prb_pairs = 6; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space - AssertFatal(cc[CC_idP]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 - != NULL, + memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space + AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!= NULL, "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = - cc[CC_idP].sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = - (ra->rach_resource_type < 3) ? 1 : 2; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - drms_scrambling_init = cc[CC_idP].physCellId; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - initial_transmission_sf_io = (frameP * 10) + subframeP; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - harq_resource_offset = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1; // N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - allocate_prach_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag - = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag - = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_tx_antenna_ports = 1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1; // N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; ra->msg2_mpdcch_repetition_cnt++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; @@ -492,65 +426,43 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, ra->state = WAITMSG3; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - mac->pdu_index[CC_idP]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - resource_allocation_type = 2; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - resource_block_coding = getRIV(N_RB_DL, first_rb, 6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = - cc[CC_idP]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13-> - startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = - (ra->rach_resource_type < 3) ? 1 : 2;; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13. - initial_transmission_sf_io = (10 * frameP) + subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = - 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req->number_pdu++; mac->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP; @@ -570,19 +482,15 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, mac->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST; mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = - &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> - TX_req - [CC_idP]. - tx_request_body.number_of_pdus]; + &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble TX_req->pdu_index = mac->pdu_index[CC_idP]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = 7; - TX_req->segments[0].segment_data = - cc[CC_idP].RAR_pdu.payload; + TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload; mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti); + set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti); } } } @@ -603,100 +511,73 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, vrb_map[first_rb + 2] = 1; vrb_map[first_rb + 3] = 1; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->RA_rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); // This checks if the above DCI allocation is feasible in current subframe - if (!CCE_allocation_infeasible - (module_idP, CC_idP, 0, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, ra->RA_rnti)) { + if (!CCE_allocation_infeasible(module_idP, CC_idP, 0, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) { LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", frameP, subframeP, ra->RA_rnti); dl_req->number_dci++; dl_req->number_pdu++; - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - mac->pdu_index[CC_idP]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP; // Program UL processing for Msg3 - get_Msg3alloc(&cc[CC_idP], subframeP, frameP, - &ra->Msg3_frame, &ra->Msg3_subframe); + get_Msg3alloc(&cc[CC_idP], subframeP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe); LOG_D(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe); - fill_rar(module_idP, CC_idP, ra, frameP, - cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); + fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); add_msg3(module_idP, CC_idP, ra, frameP, subframeP); ra->state = WAITMSG3; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); @@ -704,10 +585,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, // DL request mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = - &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> - TX_req - [CC_idP]. - tx_request_body.number_of_pdus]; + &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble TX_req->pdu_index = mac->pdu_index[CC_idP]++; TX_req->num_segments = 1; @@ -716,7 +594,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, cc[CC_idP].RAR_pdu.payload; mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti); + set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti); } } // PDCCH CCE allocation is feasible } // Msg2 frame/subframe condition @@ -751,7 +629,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, uint8_t offset; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int rmax = 0; int rep = 0; int reps = 0; @@ -768,63 +646,42 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, if (cc[CC_idP].radioResourceConfigCommon_BR) { - ext4_prach = - cc[CC_idP].radioResourceConfigCommon_BR->ext4-> - prach_ConfigCommon_v1310; - ext4_pucch = - cc[CC_idP].radioResourceConfigCommon_BR->ext4-> - pucch_ConfigCommon_v1310; - prach_ParametersListCE_r13 = - &ext4_prach->prach_ParametersListCE_r13; - pucch_N1PUCCH_AN_InfoList_r13 = - ext4_pucch->n1PUCCH_AN_InfoList_r13; - AssertFatal(prach_ParametersListCE_r13 != NULL, - "prach_ParametersListCE_r13 is null\n"); - AssertFatal(pucch_N1PUCCH_AN_InfoList_r13 != NULL, - "pucch_N1PUCCH_AN_InfoList_r13 is null\n"); + ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + ext4_pucch = cc[CC_idP].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13; + AssertFatal(prach_ParametersListCE_r13 != NULL,"prach_ParametersListCE_r13 is null\n"); + AssertFatal(pucch_N1PUCCH_AN_InfoList_r13 != NULL,"pucch_N1PUCCH_AN_InfoList_r13 is null\n"); // check to verify CE-Level compatibility in SIB2_BR - AssertFatal(prach_ParametersListCE_r13->list.count == - pucch_N1PUCCH_AN_InfoList_r13->list.count, + AssertFatal(prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n"); switch (prach_ParametersListCE_r13->list.count) { case 4: p[3] = prach_ParametersListCE_r13->list.array[3]; n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n"); - pucchreps[3] = - (int) (4 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level3_r13); + pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13); case 3: p[2] = prach_ParametersListCE_r13->list.array[2]; n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!= NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n"); - pucchreps[2] = - (int) (4 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level2_r13); + pucchreps[2] =(int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13); case 2: p[1] = prach_ParametersListCE_r13->list.array[1]; n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n"); - pucchreps[1] = - (int) (1 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level1_r13); + pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13); case 1: p[0] = prach_ParametersListCE_r13->list.array[0]; n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n"); - pucchreps[0] = - (int) (1 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level0_r13); + pucchreps[0] =(int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13); default: AssertFatal(1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", @@ -847,12 +704,11 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - // Get RRCConnectionSetup for Piggyback + /* // Get RRCConnectionSetup for Piggyback rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block - &cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0); // not used in this case - + &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case if(rrc_sdu_length <= 0) { - LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated\n %d",rrc_sdu_length); + LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated (%d)\n",rrc_sdu_length); return; } //AssertFatal(rrc_sdu_length > 0, @@ -861,10 +717,10 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", - module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length); + module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);*/ -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (ra->rach_resource_type > 0) { // Generate DCI + repetitions first @@ -897,80 +753,53 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = - (ra->rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = - ra->msg34_narrowband; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg34_narrowband; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - mpdcch_tansmission_type = 1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; AssertFatal(cc[CC_idP]. sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = - cc[CC_idP].sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0; // t-C-RNTI dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = - (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (ra->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; /// Check this is still N_id_cell for type2 common - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - initial_transmission_sf_io = (frameP * 10) + subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // check if not getRIV(N_RB_DL,first_rb,6); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of Msg4, 208 bits with N1A_PRB=3 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = - ra->harq_pid; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = ra->harq_pid; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - harq_resource_offset = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1; // N1A_PRB=3; => 208 bits - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = - 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag - = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag - = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = - 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_tx_antenna_ports = 1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; ra->msg4_mpdcch_repetition_cnt++; dl_req_body->number_pdu++; dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; @@ -993,11 +822,24 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(1 == 0, "TDD case not done yet\n"); } } // mpdcch_repetition_count == reps - if ((ra->Msg4_frame == frameP) - && (ra->Msg4_subframe == subframeP)) { + if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { // Program PDSCH + // Get RRCConnectionSetup for Piggyback + /*rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0); // not used in this case*/ + + rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case + + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", + module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length); + + AssertFatal(rrc_sdu_length > 0, + "[MAC][eNB Scheduler] CCCH not allocated\n"); + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n", module_idP, CC_idP, frameP, subframeP, @@ -1005,62 +847,42 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(1 == 0, "Msg4 generation not finished for BL/CE UE\n"); - dl_config_pdu = - &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - mac->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->rnti; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); // check that this isn't getRIV(6,0,6) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = - cc[CC_idP]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13-> - startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = - (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13. - initial_transmission_sf_io = (10 * frameP) + subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = - 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req_body->number_pdu++; dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; @@ -1072,18 +894,15 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, lcid = 0; - UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = - 0; + UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; msg4_header = 1 + 6 + 1; // CR header, CR CE, SDU header if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header; + msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header; msg4_post_padding = 0; } else { msg4_padding = 0; - msg4_post_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; + msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; } LOG_D(MAC, @@ -1103,10 +922,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, msg4_post_padding); memcpy((void *) &mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload[0][(unsigned - char) - offset], + DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); // DL request @@ -1115,17 +931,12 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, mac->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST; TX_req = - &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> - TX_req - [CC_idP]. - tx_request_body.number_of_pdus]; + &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; TX_req->pdu_length = rrc_sdu_length; TX_req->pdu_index = mac->pdu_index[CC_idP]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = rrc_sdu_length; - TX_req->segments[0].segment_data = - mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0]; + TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0]; mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; // Program ACK/NAK for Msg4 PDSCH @@ -1138,41 +949,26 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, ul_req_body = &ul_req->ul_config_request_body; ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel8.rnti = ra->rnti; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = ra->rnti; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel13.ue_type = - (ra->rach_resource_type < 3) ? 1 : 2; - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel13.empty_symbols = 0; - ul_config_pdu->uci_harq_pdu.ue_information. - ue_information_rel13.total_number_of_repetitions = - pucchreps[ra->rach_resource_type - 1]; - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel13.repetition_number = - 0; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[ra->rach_resource_type - 1]; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0; ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4); ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - LOG_D(MAC,"UL_req_tmp[CC_idP:%d][ackNAK_absSF mod 10:%d] ra->Msg3_frame:%d ra->Msg3_subframe:%d + 4 sfn_sf:%d\n", CC_idP, ackNAK_absSF%10, ra->Msg3_frame, ra->Msg3_subframe, NFAPI_SFNSF2DEC(ul_req->sfn_sf)); // Note need to keep sending this across reptitions!!!! Not really for PUCCH, to ask small-cell forum, we'll see for the other messages, maybe parameters change across repetitions and FAPI has to provide for that if (cc[CC_idP].tdd_Config == NULL) { // FDD case ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG; - ul_config_pdu->uci_harq_pdu. - harq_information.harq_information_rel8_fdd. - n_pucch_1_0 = - n1pucchan[ra->rach_resource_type - 1]; + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = n1pucchan[ra->rach_resource_type - 1]; // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => @@ -1192,27 +988,43 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, if (opt_enabled == 1) { trace_pdu(1, (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload - [0], rrc_sdu_length, UE_id, 3, + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), mac->frame, mac->subframe, 0, 0); LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", - module_idP, CC_idP, frameP, UE_RNTI(module_idP, - UE_id), + module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); } if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); + set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); } } // Msg4 frame/subframe } // msg4_mpdcch_repetition_count } // rach_resource_type > 0 else #endif - { // This is normal LTE case - if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { + { + // This is normal LTE case + LOG_D(MAC, "Panos-D: generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d, frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP); + if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { + + // Get RRCConnectionSetup for Piggyback + /*rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0); // not used in this case*/ + + rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case + + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", + module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length); + + AssertFatal(rrc_sdu_length > 0, + "[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length); + + + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n", module_idP, CC_idP, frameP, subframeP, ra->rnti); @@ -1266,19 +1078,15 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process, - &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding); + &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding); AssertFatal(dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.resource_block_coding < 8192, "resource_block_coding %u < 8192\n", dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.resource_block_coding); - if (!CCE_allocation_infeasible - (module_idP, CC_idP, 1, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, ra->rnti)) { + if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) { dl_req_body->number_dci++; dl_req_body->number_pdu++; @@ -1300,18 +1108,14 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, // put HARQ process round to 0 ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - - UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = - 0; + UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header; + msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header; msg4_post_padding = 0; } else { msg4_padding = 0; - msg4_post_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; + msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; } LOG_D(MAC, @@ -1330,11 +1134,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, msg4_padding, // no padding msg4_post_padding); - memcpy((void *) &mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload[0][(unsigned - char) - offset], + memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); // DLSCH Config @@ -1368,9 +1168,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, rrc_sdu_length, mac->pdu_index[CC_idP], mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload - [0]); + DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); mac->pdu_index[CC_idP]++; dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf; @@ -1383,8 +1181,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, CC_idP, ra->rnti, (frameP * 10) + subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.cce_idx); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), @@ -1396,9 +1193,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, if (opt_enabled == 1) { trace_pdu(1, (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload - [0], rrc_sdu_length, UE_id, 3, + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), mac->frame, mac->subframe, 0, 0); LOG_D(OPT, @@ -1408,7 +1203,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, rrc_sdu_length); } if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); + set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); } } // CCE Allocation feasible } // msg4 frame/subframe @@ -1433,7 +1228,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, int round; /* - #ifdef Rel14 + #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) COMMON_channels_t *cc = mac->common_channels; int rmax = 0; @@ -1481,12 +1276,12 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d)\n", - module_idP, CC_idP, frameP, subframeP, ra->harq_pid, round); + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d), UE_id: %d \n", + module_idP, CC_idP, frameP, subframeP, ra->harq_pid, round, UE_id); if (round != 8) { -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (ra->rach_resource_type > 0) { AssertFatal(1 == 0, "Msg4 Retransmissions not handled yet for BL/CE UEs\n"); @@ -1531,6 +1326,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, ra->rnti, round, frameP, subframeP); // DLSCH Config //DJP - fix this pdu_index = -1 + LOG_D(MAC, "Panos:D: check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n"); fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, -1 /* retransmission, no pdu_index */ @@ -1553,9 +1349,9 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, (cc->p_eNB == 1) ? 1 : 2, // transmission mode 1, // num_bf_prb_per_subband 1); // num_bf_vector - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); - } + if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ + set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); + } } else LOG_D(MAC, "msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", @@ -1589,8 +1385,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP); UE_id = find_UE_id(module_idP, ra->rnti); DevAssert(UE_id != -1); - mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. - configured = TRUE; + mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); } } @@ -1643,7 +1438,7 @@ initiate_ra_proc(module_id_t module_idP, sub_frame_t subframeP, uint16_t preamble_index, int16_t timing_offset, uint16_t ra_rnti -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif ) @@ -1654,6 +1449,8 @@ initiate_ra_proc(module_id_t module_idP, COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; RA_t *ra = &cc->ra[0]; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL; PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; @@ -1661,16 +1458,16 @@ initiate_ra_proc(module_id_t module_idP, if (cc->radioResourceConfigCommon_BR && cc->radioResourceConfigCommon_BR->ext4) { - ext4_prach = - cc->radioResourceConfigCommon_BR->ext4-> - prach_ConfigCommon_v1310; - prach_ParametersListCE_r13 = - &ext4_prach->prach_ParametersListCE_r13; + ext4_prach = cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; } + +#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, subframeP, preamble_index); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d PRACH resource type %d\n", module_idP, CC_id, frameP, subframeP, rach_resource_type); @@ -1680,6 +1477,8 @@ initiate_ra_proc(module_id_t module_idP, uint16_t msg2_subframe = subframeP; int offset; +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + if (prach_ParametersListCE_r13 && prach_ParametersListCE_r13->list.count < rach_resource_type) { LOG_E(MAC, @@ -1689,10 +1488,10 @@ initiate_ra_proc(module_id_t module_idP, return; } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); +#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); for (i = 0; i < NB_RA_PROC_MAX; i++) { if (ra[i].state == IDLE) { @@ -1702,7 +1501,7 @@ initiate_ra_proc(module_id_t module_idP, ra[i].state = MSG2; ra[i].timing_offset = timing_offset; ra[i].preamble_subframe = subframeP; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ra[i].rach_resource_type = rach_resource_type; ra[i].msg2_mpdcch_repetition_cnt = 0; ra[i].msg4_mpdcch_repetition_cnt = 0; @@ -1712,6 +1511,7 @@ initiate_ra_proc(module_id_t module_idP, //TODO Fill in other TDD config. What about nfapi_mode? if(cc->tdd_Config!=NULL){ switch(cc->tdd_Config->subframeAssignment){ + default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort(); case 1 : offset = 6; break; @@ -1735,18 +1535,18 @@ initiate_ra_proc(module_id_t module_idP, /* TODO: find better procedure to allocate RNTI */ do { #if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode - static int drnti[NUMBER_OF_UE_MAX] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 }; + static int drnti[MAX_MOBILES_PER_ENB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 }; int j = 0; int nb_ue = 0; - for (j = 0; j < NUMBER_OF_UE_MAX; j++) { + for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { if (UE_RNTI(module_idP, j) > 0) { nb_ue++; } else { break; } } - if (nb_ue >= NUMBER_OF_UE_MAX) { - printf("No more free RNTI available, increase NUMBER_OF_UE_MAX\n"); + if (nb_ue >= MAX_MOBILES_PER_ENB) { + printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n"); abort(); } ra[i].rnti = drnti[nb_ue]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 5b0fc58bb70eb678c6f7a325cc7c1fd361f0f8a2..7aabc30b8194fe7776f7dcae7db8ac44eca51bf9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -30,22 +30,16 @@ */ #include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" @@ -58,11 +52,14 @@ #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 +#include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; // NEED TO ADD schedule_SI_BR for SIB1_BR and SIB23_BR // CCE_allocation_infeasible to be done for EPDCCH/MPDCCH -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #define size_Sj25 2 int Sj25[size_Sj25] = { 0, 3 }; @@ -84,7 +81,6 @@ schedule_SIB1_BR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) //------------------------------------------------------------------------------ { - int8_t bcch_sdu_length; int CC_id; eNB_MAC_INST *eNB = RC.mac[module_idP]; @@ -197,7 +193,7 @@ schedule_SIB1_BR(module_id_t module_idP, n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 1, module_idP, 0); // not used in this case + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, "schedulingInfoSIB1_BR_r13 %d > 18\n", @@ -235,35 +231,28 @@ schedule_SIB1_BR(module_id_t module_idP, memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = - (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = - 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // Rel10 fields @@ -280,10 +269,7 @@ schedule_SIB1_BR(module_id_t module_idP, dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request - TX_req = - &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB-> - TX_req - [CC_id].tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; @@ -315,11 +301,8 @@ schedule_SIB1_BR(module_id_t module_idP, } } -int si_WindowLength_BR_r13tab - [SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] -= { 20, 40, 60, 80, 120, 160, 200 }; -int si_TBS_r13tab[SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] = - { 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 }; +int si_WindowLength_BR_r13tab[SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = { 20, 40, 60, 80, 120, 160, 200 }; +int si_TBS_r13tab[SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] = { 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 }; //------------------------------------------------------------------------------ void @@ -354,65 +337,40 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) continue; else { - - - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 - != NULL, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = - cc->sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; + SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; AssertFatal(schedulingInfoList_BR_r13 != NULL, "sib_v13ext->schedulingInfoList_BR_r13 is null\n"); - SchedulingInfoList_t *schedulingInfoList = - cc->schedulingInfoList; - AssertFatal(schedulingInfoList_BR_r13->list.count == - schedulingInfoList->list.count, + SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; + AssertFatal(schedulingInfoList_BR_r13->list.count == schedulingInfoList->list.count, "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", schedulingInfoList_BR_r13->list.count, schedulingInfoList->list.count); - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13 - <= - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, "si_WindowLength_BR_r13 %d > %d\n", - (int) cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, + (int) cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); // check that SI frequency-hopping is disabled - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 - == - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 == SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n"); - long si_WindowLength_BR_r13 = - si_WindowLength_BR_r13tab[cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; - - long si_RepetitionPattern_r13 = - cc->sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; - AssertFatal(si_RepetitionPattern_r13 <= - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, + long si_WindowLength_BR_r13 = si_WindowLength_BR_r13tab[cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; + + long si_RepetitionPattern_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; + AssertFatal(si_RepetitionPattern_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, "si_RepetitionPattern_r13 %d > %d\n", (int) si_RepetitionPattern_r13, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); // cycle through SIB list for (i = 0; i < schedulingInfoList_BR_r13->list.count; i++) { - long si_Periodicity = - schedulingInfoList->list.array[i]->si_Periodicity; - long si_Narrowband_r13 = - schedulingInfoList_BR_r13->list.array[i]-> - si_Narrowband_r13; - long si_TBS_r13 = - si_TBS_r13tab[schedulingInfoList_BR_r13-> - list.array[i]->si_TBS_r13]; + long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; + long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; + long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; // check if the SI is to be scheduled now int period_in_sf = 80 << si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms @@ -424,7 +382,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, if ((sf_mod_period < si_WindowLength_BR_r13) && ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) { // this SIB is to be scheduled - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 1, module_idP, 0); // not used in this case + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 0); // not used in this case AssertFatal(bcch_sdu_length > 0, "RRC returned 0 bytes for SI-BR %d\n", i); @@ -434,18 +392,14 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, "RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n", bcch_sdu_length, (int) (si_TBS_r13 >> 3), - (int) schedulingInfoList_BR_r13-> - list.array[i]->si_TBS_r13); + (int) schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13); // allocate all 6 PRBs in narrowband for SIB1_BR // check that SIB1 didn't take this narrowband - if (vrb_map[first_rb] > 0) - continue; + if (vrb_map[first_rb] > 0) continue; - first_rb = - narrowband_to_first_rb(cc, - si_Narrowband_r13 - 1); + first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13 - 1); vrb_map[first_rb] = 1; vrb_map[first_rb + 1] = 1; vrb_map[first_rb + 2] = 1; @@ -465,89 +419,54 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req-> - number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + - sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = - si_TBS_r13 >> 3; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = - 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13 >> 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.redundancy_version = rvidx; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag - = 0; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transmission_scheme = - (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_vector = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // Rel10 fields (for PDSCH starting symbol) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10. - pdsch_start = - cc[CC_id]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; // Rel13 fields dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel13.initial_transmission_sf_io = - absSF - sf_mod_period; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request - TX_req = - &eNB->TX_req[CC_id]. - tx_request_body.tx_pdu_list[eNB->TX_req[CC_id]. - tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; - TX_req->segments[0].segment_length = - bcch_sdu_length; - TX_req->segments[0].segment_data = - cc->BCCH_BR_pdu[i + 1].payload; - eNB->TX_req[CC_id].tx_request_body. - number_of_pdus++; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i + 1].payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].sfn_sf = sfn_sf; eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; @@ -586,7 +505,6 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, void schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc; nfapi_dl_config_request_pdu_t *dl_config_pdu; @@ -606,7 +524,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_req = &dl_config_request->dl_config_request_body; cc = &eNB->common_channels[CC_id]; - mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 1, module_idP, 0); // not used in this case + mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length); @@ -615,24 +533,27 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length); if ((frameP & 1023) < 40) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(MAC, "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n", module_idP, frameP, CC_id, mib_sdu_length, (int) cc->mib->message.schedulingInfoSIB1_BR_r13); +#else + LOG_D(MAC, + "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n", + module_idP, frameP, CC_id, mib_sdu_length); +#endif - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = 2 + sizeof(nfapi_dl_config_bch_pdu); - dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; - dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; - dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; + dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; + dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; dl_req->number_pdu++; dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; @@ -641,9 +562,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); // DL request - TX_req = - &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req - [CC_id].tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = 3; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; @@ -692,7 +611,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 1, module_idP, 0); // not used in this case + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 0); // not used in this case if (bcch_sdu_length > 0) { LOG_D(MAC, "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); @@ -753,114 +672,81 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) } - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - new_data_indicator_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - redundancy_version_1 = 0; - - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); dl_config_request->sfn_sf = sfn_sf; - if (!CCE_allocation_infeasible - (module_idP, CC_id, 0, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP, subframeP); dl_req->number_dci++; dl_req->number_pdu++; - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag - = 0; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transmission_scheme = - (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = - 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF - dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_request->sfn_sf = sfn_sf; + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; // Program TX Request - TX_req = - &eNB->TX_req[CC_id]. - tx_request_body.tx_pdu_list[eNB->TX_req[CC_id]. - tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = bcch_sdu_length; - TX_req->segments[0].segment_data = - cc->BCCH_pdu.payload; + TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].sfn_sf = sfn_sf; eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; @@ -896,13 +782,14 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length; eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length; eNB->eNB_stats[CC_id].bcch_mcs = mcs; +//printf("SI %d.%d\n", frameP, subframeP);/////////////////////////////////////////****************************** } else { //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); } } } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) schedule_SIB1_BR(module_idP, frameP, subframeP); schedule_SI_BR(module_idP, frameP, subframeP); #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 0d108894fb0662aa3af0e4cd86a6a327d4dc28f1..3eb28cee594c99a267d2bce2d0550114d1704195 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -29,34 +29,37 @@ */ -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus + +#include "assertions.h" #if defined(ENABLE_ITTI) #include "intertask_interface.h" #endif +#include "ENB_APP/flexran_agent_defs.h" +#include "flexran_agent_ran_api.h" +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include <dlfcn.h> + #include "T.h" #define ENABLE_MAC_PAYLOAD_DEBUG @@ -65,6 +68,40 @@ extern RAN_CONTEXT_t RC; extern uint8_t nfapi_mode; + +// number of active slices for past and current time +int n_active_slices = 1; +int n_active_slices_current = 1; + +// RB share for each slice for past and current time +float avg_slice_percentage=0.25; +float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float total_slice_percentage = 0; +float total_slice_percentage_current = 0; + +// MAX MCS for each slice for past and current time +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, 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] = + { "schedule_ue_spec", + "schedule_ue_spec", + "schedule_ue_spec", + "schedule_ue_spec" + }; + +// The lists of criteria that enforce the sorting policies of the slices +uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; +uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; + +// pointer to the slice specific scheduler +slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; + //------------------------------------------------------------------------------ void add_ue_dlsch_info(module_id_t module_idP, @@ -74,13 +111,13 @@ add_ue_dlsch_info(module_id_t module_idP, { //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); - eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); - // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; - eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; + eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = + UE_RNTI(module_idP, UE_id); + // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; + eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; + eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; - eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; + eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; } @@ -91,32 +128,30 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, //------------------------------------------------------------------------------ { - int next_ue; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + int next_ue; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { - if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_WAITING) { - return next_ue; - } + for (next_ue = UE_list->head; next_ue >= 0; + next_ue = UE_list->next[next_ue]) { + if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == + S_DL_WAITING) { + return next_ue; } + } - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { - if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_BUFFERED) { - eNB_dlsch_info[module_idP][CC_id][next_ue].status = - S_DL_WAITING; - } + for (next_ue = UE_list->head; next_ue >= 0; + next_ue = UE_list->next[next_ue]) { + if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) { + eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING; } + } - return (-1); //next_ue; + return (-1); //next_ue; } //------------------------------------------------------------------------------ -unsigned char +int generate_dlsch_header(unsigned char *mac_header, unsigned char num_sdus, unsigned short *sdu_lengths, @@ -129,188 +164,183 @@ generate_dlsch_header(unsigned char *mac_header, //------------------------------------------------------------------------------ { - SCH_SUBHEADER_FIXED *mac_header_ptr = - (SCH_SUBHEADER_FIXED *) mac_header; - uint8_t first_element = 0, last_size = 0, i; - uint8_t mac_header_control_elements[16], *ce_ptr; + SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *) mac_header; + uint8_t first_element = 0, last_size = 0, i; + uint8_t mac_header_control_elements[16], *ce_ptr; - ce_ptr = &mac_header_control_elements[0]; + ce_ptr = &mac_header_control_elements[0]; - // compute header components + // compute header components - if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element = 1; - last_size = 1; - } + if ((short_padding == 1) || (short_padding == 2)) { + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + first_element = 1; + last_size = 1; + } + + if (short_padding == 2) { + mac_header_ptr->E = 1; + mac_header_ptr++; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + last_size = 1; + } - if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size = 1; + if (drx_cmd != 255) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (drx_cmd != 255) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = DRX_CMD; + last_size = 1; + } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = DRX_CMD; - last_size = 1; + if (timing_advance_cmd != 31) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (timing_advance_cmd != 31) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = TIMING_ADV_CMD; + last_size = 1; + // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; + AssertFatal(timing_advance_cmd < 64, + "timing_advance_cmd %d > 63\n", timing_advance_cmd); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; + LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); + ce_ptr += sizeof(TIMING_ADVANCE_CMD); + //msg("offset %d\n",ce_ptr-mac_header_control_elements); + } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = TIMING_ADV_CMD; - last_size = 1; - // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; - AssertFatal(timing_advance_cmd < 64, - "timing_advance_cmd %d > 63\n", timing_advance_cmd); - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; - LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); - ce_ptr += sizeof(TIMING_ADVANCE_CMD); - //msg("offset %d\n",ce_ptr-mac_header_control_elements); + if (ue_cont_res_id) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; } - if (ue_cont_res_id) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = UE_CONT_RES; + last_size = 1; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = UE_CONT_RES; - last_size = 1; + LOG_T(MAC, + "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], + ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); - LOG_T(MAC, - "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", - ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], - ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); - - memcpy(ce_ptr, ue_cont_res_id, 6); - ce_ptr += 6; - // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + memcpy(ce_ptr, ue_cont_res_id, 6); + ce_ptr += 6; + // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + + for (i = 0; i < num_sdus; i++) { + LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", + num_sdus, sdu_lengths[i]); + + if (first_element > 0) { + mac_header_ptr->E = 1; + /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr += last_size; + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + } else { + first_element = 1; } - //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - - for (i = 0; i < num_sdus; i++) { - LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", - num_sdus, sdu_lengths[i]); - - if (first_element > 0) { - mac_header_ptr->E = 1; - /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr += last_size; - //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - } else { - first_element = 1; - } - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = - (unsigned char) sdu_lengths[i]; - last_size = 2; - } else { - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = - ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = - (unsigned short) sdu_lengths[i] & 0xff; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; - last_size = 3; + if (sdu_lengths[i] < 128) { + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = (unsigned char) sdu_lengths[i]; + last_size = 2; + } else { + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i] & 0xff; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; + last_size = 3; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); + LOG_D(MAC, + "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); #endif - } } + } - /* - - printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - - - if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) { - if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0) - printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L)); - else - printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); - } - */ - if (post_padding > 0) { // we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr += last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; - } else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; - } + /* + + printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - if ((ce_ptr - mac_header_control_elements) > 0) { - // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); - memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); - mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); + + if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) { + if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0) + printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L)); + else + printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); } - //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); + */ + if (post_padding > 0) { // we have lots of padding at the end of the packet + mac_header_ptr->E = 1; + mac_header_ptr += last_size; + // add a padding element + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + mac_header_ptr++; + } else { // no end of packet padding + // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) + mac_header_ptr++; + } - return ((unsigned char *) mac_header_ptr - mac_header); + //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); + if ((ce_ptr - mac_header_control_elements) > 0) { + // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); + memcpy((void *) mac_header_ptr, mac_header_control_elements, + ce_ptr - mac_header_control_elements); + mac_header_ptr += + (unsigned char) (ce_ptr - mac_header_control_elements); + } + //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); + + return ((unsigned char *) mac_header_ptr - mac_header); } //------------------------------------------------------------------------------ @@ -320,616 +350,680 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, //------------------------------------------------------------------------------ { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - unsigned char DAI; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - if (cc->tdd_Config != NULL) { //TDD - DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", - module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); - // Save DAI for Format 0 DCI + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + unsigned char DAI; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + if (cc->tdd_Config != NULL) { //TDD + DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", + module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); + // Save DAI for Format 0 DCI + + switch (cc->tdd_Config->subframeAssignment) { + case 0: + // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) + break; - switch (cc->tdd_Config->subframeAssignment) { - case 0: - // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) - break; + case 1: + switch (subframeP) { + case 0: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; + break; - case 1: - switch (subframeP) { - case 0: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; - break; - - case 4: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; - break; - - case 5: - case 6: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; - - case 9: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; - } + case 4: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + break; - case 2: - // if ((subframeP==3)||(subframeP==8)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 5: + case 6: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 3: + case 9: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + } - //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { - // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; - //} - switch (subframeP) { - case 5: - case 6: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; - - case 7: - case 8: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; - - case 9: - case 0: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; - break; - - default: - break; - } + case 2: + // if ((subframeP==3)||(subframeP==8)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - break; + case 3: - case 4: - // if ((subframeP==8)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { + // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; + //} + switch (subframeP) { + case 5: + case 6: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 5: - // if (subframeP==8) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 7: + case 8: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; - case 6: - // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 9: + case 0: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; + break; - default: - break; - } + default: + break; + } + + break; + + case 4: + // if ((subframeP==8)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; + + case 5: + // if (subframeP==8) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; + + case 6: + // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; + + default: + break; } + } } +//------------------------------------------------------------------------------ +void +schedule_dlsch(module_id_t module_idP, + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) +//------------------------------------------------------------------------------{ +{ + + int i = 0; + + total_slice_percentage=0; + avg_slice_percentage=1.0/n_active_slices; + + // reset the slice percentage for inactive slices + for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { + slice_percentage[i]=0; + } + for (i = 0; i < n_active_slices; i++) { + if (slice_percentage[i] < 0 ){ + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", + module_idP, frameP, subframeP, i, slice_percentage[i]); + slice_percentage[i]=0; + } + total_slice_percentage+=slice_percentage[i]; + } + + for (i = 0; i < n_active_slices; i++) { + + // Load any updated functions + if (update_dl_scheduler[i] > 0 ) { + slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); + update_dl_scheduler[i] = 0 ; + update_dl_scheduler_current[i] = 0; + LOG_N(MAC,"update dl scheduler slice %d\n", i); + } + + if (total_slice_percentage <= 1.0){ // the new total RB share is within the range + + // check if the number of slices has changed, and log + if (n_active_slices_current != n_active_slices ){ + if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", + module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); + + n_active_slices_current = n_active_slices; + + } else { + LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); + n_active_slices = n_active_slices_current; + } + } + + // check if the slice rb share has changed, and log the console + if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); + total_slice_percentage_current= total_slice_percentage; + slice_percentage_current[i] = slice_percentage[i]; + + } + + // check if the slice max MCS, and log the console + if (slice_maxmcs_current[i] != slice_maxmcs[i]){ + if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); + slice_maxmcs_current[i] = slice_maxmcs[i]; + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",module_idP, i, slice_maxmcs[i],slice_maxmcs_current[i]); + slice_maxmcs[i]= slice_maxmcs_current[i]; + } + } + + // check if a new scheduler, and log the console + if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", + module_idP, i, frameP, subframeP, dl_scheduler_type[i]); + update_dl_scheduler_current[i] = update_dl_scheduler[i]; + } + + } else { + // here we can correct the values, e.g. reduce proportionally + + if (n_active_slices == n_active_slices_current){ + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", + module_idP, i, total_slice_percentage_current, total_slice_percentage); + if (slice_percentage[i] >= avg_slice_percentage){ + slice_percentage[i]-=0.1; + total_slice_percentage-=0.1; + } + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", + module_idP, i, total_slice_percentage_current, total_slice_percentage, + n_active_slices, n_active_slices_current ); + n_active_slices = n_active_slices_current; + slice_percentage[i] = slice_percentage_current[i]; + } + } + + // Check for new sorting policy + if (sorting_policy_current[i] != sorting_policy[i]) { + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, sorting_policy_current[i], sorting_policy[i]); + sorting_policy_current[i] = sorting_policy[i]; + } + + // Run each enabled slice-specific schedulers one by one + slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); + } + +} // changes to pre-processor for eMTC //------------------------------------------------------------------------------ void -schedule_ue_spec(module_id_t module_idP, +schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { - - - uint8_t CC_id; - int UE_id; - unsigned char aggregation; - mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = - 0, header_len_dtch_last = 0; - unsigned char ta_len = 0; - unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; - uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = - 0, post_padding = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - unsigned char round = 0; - unsigned char harq_pid = 0; - eNB_UE_STATS *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; - - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list = &eNB->UE_list; - int continue_flag = 0; - int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; - UE_sched_ctrl *ue_sched_ctl; - int mcs; - int i; - int min_rb_unit[MAX_NUM_CCs]; - int N_RB_DL[MAX_NUM_CCs]; - int total_nb_available_rb[MAX_NUM_CCs]; - int N_RBG[MAX_NUM_CCs]; - nfapi_dl_config_request_body_t *dl_req; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - int tdd_sfa; - int ta_update; + int CC_id; + int UE_id; + int aggregation; + mac_rlc_status_resp_t rlc_status; + int ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX]; + int lcid, offset, num_sdus = 0; + int nb_rb, nb_rb_temp, nb_available_rb; + uint16_t sdu_lengths[NB_RB_MAX]; + int TBS, j, rnti, padding = 0, post_padding = 0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + int round = 0; + int harq_pid = 0; + eNB_UE_STATS *eNB_UE_stats = NULL; + int sdu_length_total = 0; + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + int continue_flag = 0; + int32_t normalized_rx_power, target_rx_power; + int tpc = 1; + UE_sched_ctrl *ue_sched_ctl; + int mcs; + int i; + int min_rb_unit[MAX_NUM_CCs]; + int N_RB_DL[MAX_NUM_CCs]; + int total_nb_available_rb[MAX_NUM_CCs]; + int N_RBG[MAX_NUM_CCs]; + nfapi_dl_config_request_body_t *dl_req; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + int tdd_sfa; + int ta_update; + int header_length_last; + int header_length_total; #if 0 - if (UE_list->head == -1) { - return; - } + 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); + start_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); - // for TDD: check that we have to act here, otherwise return - if (cc[0].tdd_Config) { - tdd_sfa = cc[0].tdd_Config->subframeAssignment; - switch (subframeP) { - case 0: - // always continue - break; - case 1: - return; - break; - case 2: - return; - break; - case 3: - if ((tdd_sfa != 2) && (tdd_sfa != 5)) - return; - break; - case 4: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 5: - break; - case 6: - case 7: - if ((tdd_sfa != 3)&& (tdd_sfa != 4) && (tdd_sfa != 5)) - return; - break; - case 8: - if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 9: - if (tdd_sfa == 0) - return; - break; - - } - } + // for TDD: check that we have to act here, otherwise return + if (cc[0].tdd_Config) { + tdd_sfa = cc[0].tdd_Config->subframeAssignment; + switch (subframeP) { + case 0: + // always continue + break; + case 1: + return; + break; + case 2: + return; + break; + case 3: + if ((tdd_sfa != 2) && (tdd_sfa != 5)) + return; + break; + case 4: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 5: + break; + case 6: + case 7: + if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) + return; + break; + case 8: + if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 9: + if (tdd_sfa == 0) + return; + break; - //weight = get_ue_weight(module_idP,UE_id); - aggregation = 2; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); - min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); - // get number of PRBs less those used by common channels - total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; - for (i = 0; i < N_RB_DL[CC_id]; i++) - if (cc[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; - - N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); - - // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; } + } + //weight = get_ue_weight(module_idP,UE_id); + aggregation = 2; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + // get number of PRBs less those used by common channels + total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; + for (i = 0; i < N_RB_DL[CC_id]; i++) + if (cc[CC_id].vrb_map[i] != 0) + total_nb_available_rb[CC_id]--; + + N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + + // store the global enb stats: + eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; + eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; + eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; + } /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor(module_idP, + slice_idP, frameP, subframeP, N_RBG, mbsfn_flag); stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - if (mbsfn_flag[CC_id]>0) + if (mbsfn_flag[CC_id] > 0) continue; - for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - - continue_flag=0; // reset the flag to allow allocation for the remaining UEs - rnti = UE_RNTI(module_idP,UE_id); + for (UE_id = UE_list->head; UE_id >= 0; + UE_id = UE_list->next[UE_id]) { + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs + rnti = UE_RNTI(module_idP, UE_id); eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - if (rnti==NOT_A_RNTI) { - LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs); - continue_flag=1; + if (rnti == NOT_A_RNTI) { + LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", + UE_id, UE_list->num_UEs); + continue_flag = 1; } - if (eNB_UE_stats==NULL) { - LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n"); - continue_flag=1; + if (eNB_UE_stats == NULL) { + LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); + continue_flag = 1; } + if (!ue_slice_membership(UE_id, slice_idP)) + continue; - if (continue_flag != 1){ - switch(get_tmode(module_idP,CC_id,UE_id)){ - case 1: - case 2: - case 7: - aggregation = get_aggregation(get_bw_index(module_idP,CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC, "Unsupported transmission mode %d\n", - get_tmode(module_idP, CC_id, UE_id)); - aggregation = 2; - } - } - /* if (continue_flag != 1 */ - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated - CCE_allocation_infeasible(module_idP, CC_id, 1, 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); - continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 - } + if (continue_flag != 1) { + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + aggregation = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; + case 3: + aggregation = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + default: + LOG_W(MAC, "Unsupported transmission mode %d\n", + get_tmode(module_idP, CC_id, UE_id)); + aggregation = 2; + } + } + /* if (continue_flag != 1 */ + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + CCE_allocation_infeasible(module_idP, CC_id, 1, 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); + continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 + } - if (cc[CC_id].tdd_Config != NULL) { //TDD - set_ue_dai(subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); - // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); - } + if (cc[CC_id].tdd_Config != NULL) { //TDD + set_ue_dai(subframeP, + UE_id, + CC_id, + cc[CC_id].tdd_Config->subframeAssignment, + UE_list); + // update UL DAI after DLSCH scheduling + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + } - if (continue_flag == 1) { - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, S_DL_NONE); - continue; - } + if (continue_flag == 1) { + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, S_DL_NONE); + continue; + } #warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed #if 0 - /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */ - /* if we don't add it, next allocations may succeed but overall allocations may fail */ - /* will be removed at the end of this function */ - add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) { - 0}, rnti, 1, aggregation, 1, format1, 0); + /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */ + /* if we don't add it, next allocations may succeed but overall allocations may fail */ + /* will be removed at the end of this function */ + add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) { + 0}, rnti, 1, aggregation, 1, format1, 0); #endif - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; + nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - round = ue_sched_ctl->round[CC_id][harq_pid]; + round = ue_sched_ctl->round[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = - mac_eNB_get_rrc_status(module_idP, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < - RRC_CONNECTED) - continue; + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; - sdu_length_total = 0; - num_sdus = 0; + header_length_total = 0; + sdu_length_total = 0; + num_sdus = 0; - /* - DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), - eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); - */ - if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - else { - eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + /* + DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), + eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); + */ + if (nfapi_mode) { + eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } + else { // this operation is also done in the preprocessor + eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + } - // store stats - //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - // initializing the rb allocation indicator for each UE - for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] - = 0; - } + // store stats + //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; + + // initializing the rb allocation indicator for each UE + for (j = 0; j < N_RBG[CC_id]; j++) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + } + + LOG_D(MAC, + "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, + nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], + eNB_UE_stats->dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + + + /* process retransmission */ + + if (round != 8) { + + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], + nb_rb); + + if (nb_rb <= nb_available_rb) { + if (cc[CC_id].tdd_Config != NULL) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id].DAI, subframeP); LOG_D(MAC, - "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, - nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], - eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); - - - - /* process retransmission */ - - if (round != 8) { - - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - TBS = - get_TBS_DL(UE_list-> - UE_template[CC_id][UE_id].oldmcs1[harq_pid], - nb_rb); - - if (nb_rb <= nb_available_rb) { - if (cc[CC_id].tdd_Config != NULL) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI,subframeP); - LOG_D(MAC, - "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].DAI); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - if (UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j]) - printf - ("WARN: rballoc_subband not free for retrans?\n"); - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j=0; j<N_RBG[CC_id]; j++) { - eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - */ - - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - default: - LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); - - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req-> - number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + - sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index - (module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = - rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.new_data_indicator_1 = - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = - UE_list->UE_template[CC_id][UE_id]. - oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_1 = - round & 3; - - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - (UE_list->UE_template[CC_id][UE_id].DAI - - 1), - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - } else { - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - - } - if (!CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 - /* retransmission, no pdu_index */ - , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", - eNB->pdu_index[CC_id], round); - - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - // No TX request for retransmission (check if null request for FAPI) - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", - frameP, subframeP, UE_id, rnti); - } - } - - - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - - //eNB_UE_stats->dlsch_trials[round]++; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_retransmission += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = - nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id]. - total_rbs_used_retx += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = - eNB_UE_stats->dlsch_mcs1; - } else { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - module_idP, frameP, CC_id, UE_id); - } - } else { /* This is a potentially new SDU opportunity */ - - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload - - if (ue_sched_ctl->ta_timer == 0) { - ta_update = ue_sched_ctl->ta_update; - /* if we send TA then set timer to not send it for a while */ - if (ta_update != 31) - ue_sched_ctl->ta_timer = 20; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; + "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", + CC_id, subframeP, UE_id, + UE_list->UE_template[CC_id][UE_id].DAI); + } + + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) + printf("WARN: rballoc_subband not free for retrans?\n"); + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; } else { - ta_update = 31; + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; } + } + + j = j + 1; + } + } + + nb_available_rb -= nb_rb; + /* + eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + + for(j=0; j<N_RBG[CC_id]; j++) { + eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } + */ + + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + default: + LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; + + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + } else { + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + + } + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 + /* retransmission, no pdu_index */ + , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", + eNB->pdu_index[CC_id], round); + + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu-> + dci_dl_pdu.dci_dl_pdu_rel8. + cce_idx); + // No TX request for retransmission (check if null request for FAPI) + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP, subframeP, UE_id, rnti); + } + } + + + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, + S_DL_SCHEDULED); + + //eNB_UE_stats->dlsch_trials[round]++; + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + } else { + LOG_D(MAC, + "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + module_idP, frameP, CC_id, UE_id); + } + } else { /* This is a potentially new SDU opportunity */ + rlc_status.bytes_in_buffer = 0; - ta_len = (ta_update != 31) ? 2 : 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - header_len_dcch = 2; // 2 bytes DCCH SDU subheader + // add the length for all the control elements (timing adv, drx, etc) : header + payload - if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size + if (ue_sched_ctl->ta_timer == 0) { + ta_update = ue_sched_ctl->ta_update; + /* if we send TA then set timer to not send it for a while */ + if (ta_update != 31) ue_sched_ctl->ta_timer = 20; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + } else { + ta_update = 31; + } - sdu_lengths[0] = 0; + ta_len = (ta_update != 31) ? 2 : 0; + + // RLC data on DCCH + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + TBS - ta_len - header_length_total - sdu_length_total - 3 +#ifdef Rel14 + ,0, 0 +#endif + ); + + sdu_lengths[0] = 0; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, subframeP, CC_id, + TBS - ta_len - header_length_total - sdu_length_total - 3); + + sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + TBS, //not used + (char *)&dlsch_buffer[0] +#ifdef Rel14 + ,0, 0 +#endif + ); - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC, - "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, subframeP, CC_id, - TBS - header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used - (char *) - &dlsch_buffer - [0]); pthread_mutex_lock(&rrc_release_freelist); if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){ uint16_t release_total = 0; @@ -947,17 +1041,17 @@ schedule_ue_spec(module_id_t module_idP, rrc_release_info.RRC_release_ctrl[release_num].flag = 3; LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); break; - } - } + } + } } } if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2){ if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){ for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){ if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){ - rrc_release_info.RRC_release_ctrl[release_num].flag = 4; - LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); - break; + rrc_release_info.RRC_release_ctrl[release_num].flag = 4; + LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); + break; } } } @@ -980,596 +1074,599 @@ schedule_ue_spec(module_id_t module_idP, } } } - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), - T_INT(sdu_lengths[0])); - LOG_D(MAC, - "[eNB %d][DCCH] CC_id %d frame %d subframe %d UE_id %d/%x Got %d bytes bytes_in_buffer %d from release_num %d\n", - module_idP, CC_id, frameP, subframeP, UE_id, rnti, sdu_lengths[0],rlc_status.bytes_in_buffer,rrc_release_info.num_UEs); - - sdu_length_total = sdu_lengths[0]; - sdu_lcids[0] = DCCH; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] - += sdu_lengths[0]; - num_sdus = 1; + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), + T_INT(sdu_lengths[0])); + + LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", + module_idP, CC_id, sdu_lengths[0]); + + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; + + header_length_last = 1 + 1 + (sdu_lengths[0] >= 128); + header_length_total += header_length_last; + + num_sdus = 1; + #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); + LOG_T(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[0]); - for (j = 0; j < sdu_lengths[0]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } + for (j = 0; j < sdu_lengths[0]; j++) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - } else { - header_len_dcch = 0; - sdu_length_total = 0; - } - } - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and - // DCCH SDU - sdu_lengths[num_sdus] = 0; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, CC_id, - TBS - header_len_dcch - sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used - (char *) - &dlsch_buffer - [sdu_length_total]); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); - - sdu_lcids[num_sdus] = DCCH1; - sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH1] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] - += sdu_lengths[num_sdus]; - num_sdus++; + } + } + + // RLC data on DCCH1 + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + TBS - ta_len - header_length_total - sdu_length_total - 3 +#ifdef Rel14 + ,0, 0 +#endif + ); + + // DCCH SDU + sdu_lengths[num_sdus] = 0; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, CC_id, + TBS - ta_len - header_length_total - sdu_length_total - 3); + + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total] +#ifdef Rel14 + ,0, 0 +#endif + ); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); + + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = DCCH1; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + + num_sdus++; + #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); + LOG_T(MAC, + "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[num_sdus]); - for (j = 0; j < sdu_lengths[num_sdus]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } + for (j = 0; j < sdu_lengths[num_sdus]; j++) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - } - } - // assume the max dtch header size, and adjust it later - header_len_dtch = 0; - header_len_dtch_last = 0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active - - header_len_dtch += 3; - header_len_dtch_last = 3; - LOG_D(MAC, - "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_len_dcch - - sdu_length_total - header_len_dtch); - - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - - header_len_dcch - - sdu_length_total - - header_len_dtch); - - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, frameP, - TBS - header_len_dcch - - sdu_length_total - header_len_dtch, lcid, - header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used - (char - *) - &dlsch_buffer - [sdu_length_total]); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(lcid), T_INT(sdu_lengths[num_sdus])); - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, sdu_lengths[num_sdus], lcid); - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - 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[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } - num_sdus++; - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } // no data for this LCID - else { - header_len_dtch -= 3; - } - } // no TBS left - else { - header_len_dtch -= 3; - break; - } + } + } + + // TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list). + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + // TODO: check if the lcid is active + + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, frameP, lcid, TBS, + TBS - ta_len - header_length_total - sdu_length_total - 3); + + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_length_total - sdu_length_total - 3 +#ifdef Rel14 + ,0, 0 +#endif + ); + + + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, frameP, + TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, + header_length_total); + + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total] +#ifdef Rel14 + ,0, 0 +#endif + ); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(lcid), T_INT(sdu_lengths[num_sdus])); + + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, sdu_lengths[num_sdus], lcid); + + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + + num_sdus++; + + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } + } else { + // no TBS left + break; + } + } + + /* last header does not have length field */ + if (header_length_total) { + header_length_total -= header_length_last; + header_length_total++; + } + + // there is at least one SDU or TA command + // if (num_sdus > 0 ){ + if (ta_len + sdu_length_total + header_length_total > 0) { + + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 + + mcs = eNB_UE_stats->dlsch_mcs1; + + if (mcs == 0) { + nb_rb = 4; // don't let the TBS get too small + } else { + nb_rb = min_rb_unit[CC_id]; + } + + TBS = get_TBS_DL(mcs, nb_rb); + + while (TBS < sdu_length_total + header_length_total + ta_len) { + nb_rb += min_rb_unit[CC_id]; // + + if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs + // (can happen if N_RB_DL is odd) + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + nb_rb = nb_available_rb; + break; + } + + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + } + + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; } - if (header_len_dtch == 0) - header_len_dtch_last = 0; - // there is at least one SDU - // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + - header_len_dtch) > 0) { - - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field - } else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU - } - - mcs = eNB_UE_stats->dlsch_mcs1; - - if (mcs == 0) { - nb_rb = 4; // don't let the TBS get too small - } else { - nb_rb = min_rb_unit[CC_id]; - } - TBS = get_TBS_DL(mcs, nb_rb); - - while (TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) { - nb_rb += min_rb_unit[CC_id]; // - - if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_available_rb); - nb_rb = nb_available_rb; - break; - } - - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - // decrease mcs until TBS falls below required length - while ((TBS > - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) && (mcs > 0)) { - mcs--; - TBS = get_TBS_DL(mcs, nb_rb); - } - - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) - && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) - && (mcs < 28)) - || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) - && (mcs <= 15)))) { - mcs++; - TBS = get_TBS_DL(mcs, nb_rb); - } - - LOG_D(MAC, - "dlsch_mcs before and after the rate matching = (%d, %d)\n", - eNB_UE_stats->dlsch_mcs1, mcs); + } + + j = j + 1; + } + } + + // decrease mcs until TBS falls below required length + while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { + mcs--; + TBS = get_TBS_DL(mcs, nb_rb); + } + + // if we have decreased too much or we don't have enough RBs, increase MCS + while ((TBS < sdu_length_total + header_length_total + ta_len) + && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) + && (mcs < 28)) + || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) + && (mcs <= 15)))) { + mcs++; + TBS = get_TBS_DL(mcs, nb_rb); + } + + LOG_D(MAC, + "dlsch_mcs before and after the rate matching = (%d, %d)\n", + eNB_UE_stats->dlsch_mcs1, mcs); #ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); + LOG_D(MAC, + "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif - if ((TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len) <= 2) { - padding = - (TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len); - post_padding = 0; - } else { - padding = 0; - - // adjust the header len - if (header_len_dtch == 0) { - header_len_dcch = header_len_dcch_tmp; - } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - } - - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header - } - - offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); - - //#ifdef DEBUG_eNB_SCHEDULER - if (ta_update != 31) { - LOG_D(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", - module_idP, frameP, UE_id, CC_id, - sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], offset, ta_update, padding, - post_padding, mcs, TBS, nb_rb, - header_len_dcch, header_len_dtch); - } - //#endif + if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { + padding = TBS - header_length_total - sdu_length_total - ta_len; + post_padding = 0; + } else { + padding = 0; + post_padding = 1; + } + + offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, post_padding); + + //#ifdef DEBUG_eNB_SCHEDULER + if (ta_update != 31) { + LOG_D(MAC, + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n", + module_idP, frameP, UE_id, CC_id, + sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], offset, ta_update, padding, + post_padding, mcs, TBS, nb_rb, + header_length_total); + } + //#endif #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); + LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } + for (i = 0; i < 16; i++) { + LOG_T(MAC, "%x.", dlsch_buffer[i]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); - // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + // cycle through SDUs and place in dlsch_buffer + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], + dlsch_buffer, sdu_length_total); + // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - // 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); - } +#if 0 + // 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); + } +#endif + // fill remainder of DLSCH with 0 + 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] = 0; + } - if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), - eNB->frame, eNB->subframe,0,0); - LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS); - } + if (opt_enabled == 1) { + trace_pdu(1, (uint8_t *) + UE_list->DLSCH_pdu[CC_id][0][UE_id]. + payload[0], TBS, module_idP, 3, + UE_RNTI(module_idP, UE_id), eNB->frame, + eNB->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + module_idP, CC_id, frameP, + UE_RNTI(module_idP, UE_id), TBS); + } - 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)); + 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)); UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - add_ue_dlsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_DL_SCHEDULED); - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1; - - 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; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS- sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1; - - if (cc[CC_id].tdd_Config != NULL) { // TDD - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI,subframeP); - } + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, + S_DL_SCHEDULED); + // store stats + eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; + eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; + + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].num_mac_sdu_tx = num_sdus; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; + + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; + + if (cc[CC_id].tdd_Config != NULL) { // TDD + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id].DAI, + subframeP); + } // do PUCCH power control - // this is the normalized RX power - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + // this is the normalized RX power + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ + /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id]; target_rx_power = 208; - - // this assumes accumulated tpc + + // 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; - if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around - if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { + 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; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around + if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; - - if (normalized_rx_power>(target_rx_power+4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-4)) { - tpc = 2; //+1 - tpc_accumulated++; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 } else { - tpc = 1; //0 + tpc = 1; //0 } - - LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP,frameP, subframeP,harq_pid,tpc, - tpc_accumulated,normalized_rx_power,target_rx_power); - } // Po_PUCCH has been updated + LOG_D(MAC, + "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, + normalized_rx_power, target_rx_power); + + } // Po_PUCCH has been updated else { - tpc = 1; //0 - } // time to do TPC update + tpc = 1; //0 + } // time to do TPC update else { - tpc = 1; //0 + tpc = 1; //0 } - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; //deactivate second codeword - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", - module_idP,CC_id,harq_pid, - (UE_list->UE_template[CC_id][UE_id].DAI-1), + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), mcs); } else { - LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", - module_idP,CC_id,harq_pid,mcs); - + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP, CC_id, harq_pid, mcs); + } - LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu); - if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) { + LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", + dl_req->number_pdu); + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, rnti)) { ue_sched_ctl->round[CC_id][harq_pid] = 0; dl_req->number_dci++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + // Toggle NDI for next time - LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP,subframeP,UE_id, - rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); - - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + LOG_D(MAC, + "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP, subframeP, UE_id, rnti, + harq_pid, + UE_list-> + UE_template[CC_id][UE_id].oldNDI[harq_pid]); + + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n"); - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); - - fill_nfapi_dlsch_config(eNB,dl_req, - TBS, - eNB->pdu_index[CC_id], - rnti, - 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(mcs), - 0, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, - 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is NULL\n"); + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, + "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); + + fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(mcs), 0, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, - (frameP*10)+subframeP, - TBS, - eNB->pdu_index[CC_id], - eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]); - - LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",eNB->pdu_index[CC_id]); + (frameP * 10) + subframeP, + TBS, eNB->pdu_index[CC_id], + eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]); + + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", + eNB->pdu_index[CC_id]); eNB->pdu_index[CC_id]++; - program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); - } - else { - LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", - frameP,subframeP,UE_id,rnti); + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", + frameP, subframeP, UE_id, rnti); } - } else { // There is no data from RLC or MAC header, so don't schedule + } else { // There is no data from RLC or MAC header, so don't schedule - } + } } - if (cc[CC_id].tdd_Config != NULL){ // TDD - set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); + if (cc[CC_id].tdd_Config != NULL) { // TDD + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); } - } // UE_id loop - } // CC_id loop - + } // UE_id loop + } // CC_id loop - fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_flag); - stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT); + fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); + stop_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); } //------------------------------------------------------------------------------ void -fill_DLSCH_dci( - module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - int* mbsfn_flagP) +fill_DLSCH_dci(module_id_t module_idP, + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) //------------------------------------------------------------------------------ { // loop over all allocated UEs and compute frequency allocations for PDSCH - int UE_id = -1; - uint8_t /* first_rb, */ nb_rb=3; - rnti_t rnti; + int UE_id = -1; + uint8_t /* first_rb, */ nb_rb = 3; + rnti_t rnti; //unsigned char *vrb_map; - uint8_t rballoc_sub[25]; + uint8_t rballoc_sub[25]; //uint8_t number_of_subbands=13; //unsigned char round; - unsigned char harq_pid; - int i; - int CC_id; - eNB_MAC_INST *eNB =RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - int N_RBG; - int N_RB_DL; + unsigned char harq_pid; + int i; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + int N_RBG; + int N_RB_DL; COMMON_channels_t *cc; + start_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - LOG_D(MAC,"Doing fill DCI for CC_id %d\n",CC_id); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); - if (mbsfn_flagP[CC_id]>0) + if (mbsfn_flagP[CC_id] > 0) continue; - cc = &eNB->common_channels[CC_id]; - N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + cc = &eNB->common_channels[CC_id]; + N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); // UE specific DCIs - for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - LOG_T(MAC,"CC_id %d, UE_id: %d => status %d\n",CC_id,UE_id,eNB_dlsch_info[module_idP][CC_id][UE_id].status); + for (UE_id = UE_list->head; UE_id >= 0; + UE_id = UE_list->next[UE_id]) { + LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, + eNB_dlsch_info[module_idP][CC_id][UE_id].status); if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag - eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; - rnti = UE_RNTI(module_idP,UE_id); + // clear scheduling flag + eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; + rnti = UE_RNTI(module_idP, UE_id); harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - nb_rb = 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]; + /// Synchronizing rballoc with rballoc_sub + for (i = 0; i < N_RBG; i++) { + rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; + } - - /// Synchronizing rballoc with rballoc_sub - for(i=0; i<N_RBG; i++) { - rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; - } - - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; - nfapi_dl_config_request_pdu_t* dl_config_pdu; + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_pdu_t *dl_config_pdu; - for (i=0;i<DL_req[CC_id].dl_config_request_body.number_pdu;i++) { - dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; - if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)&& - (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) && - (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); + for (i = 0; + i < DL_req[CC_id].dl_config_request_body.number_pdu; + i++) { + dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; - } - else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)&& - (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) && - (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type==0)) { - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); - } - } + } else + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); + } } } } - stop_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); + } + + stop_meas(&eNB->fill_DLSCH_dci); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); } //------------------------------------------------------------------------------ @@ -1579,37 +1676,35 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, //------------------------------------------------------------------------------ { - int UE_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; + int UE_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; - if (rntiP == SI_RNTI) { - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", - module_idP, CC_id, frameP); + if (rntiP == SI_RNTI) { + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", + module_idP, CC_id, frameP); - return ((unsigned char *) &eNB->common_channels[CC_id]. - BCCH_pdu.payload[0]); - } + return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]); + } - if (rntiP==P_RNTI) { - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); + if (rntiP==P_RNTI) { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); - return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); - } + return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); + } UE_id = find_UE_id(module_idP,rntiP); - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", - module_idP, frameP, CC_id, rntiP, UE_id); - return ((unsigned char *) &eNB-> - UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); - } else { - LOG_E(MAC, - "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", - module_idP, frameP, CC_id, rntiP); - return NULL; - } + if (UE_id != -1) { + LOG_D(MAC, + "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", + module_idP, frameP, CC_id, rntiP, UE_id); + return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); + } else { + LOG_E(MAC, + "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", + module_idP, frameP, CC_id, rntiP); + return NULL; + } } @@ -1621,27 +1716,25 @@ update_ul_dci(module_id_t module_idP, //------------------------------------------------------------------------------ { - nfapi_hi_dci0_request_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; - int i; + nfapi_hi_dci0_request_t *HI_DCI0_req = + &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = + &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; + int i; - if (cc->tdd_Config != NULL) { // TDD - for (i = 0; - i < - HI_DCI0_req->hi_dci0_request_body.number_of_dci + - HI_DCI0_req->hi_dci0_request_body.number_of_hi; i++) { + if (cc->tdd_Config != NULL) { // TDD + for (i = 0; + i <HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_hi; + i++) { - if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = - (daiP - 1) & 3; + if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; - } } + } } @@ -1652,64 +1745,64 @@ set_ue_dai(sub_frame_t subframeP, UE_list_t * UE_list) //------------------------------------------------------------------------------ { - switch (tdd_config) { - case 0: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) - || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + switch (tdd_config) { + case 0: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) + || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 1: - if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) - || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 1: + if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) + || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 2: - if ((subframeP == 4) || (subframeP == 5)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 2: + if ((subframeP == 4) || (subframeP == 5)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 3: - if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 3: + if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 4: - if ((subframeP == 0) || (subframeP == 6)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 4: + if ((subframeP == 0) || (subframeP == 6)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 5: - if (subframeP == 9) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 5: + if (subframeP == 9) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 6: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) - || (subframeP == 6) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 6: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) + || (subframeP == 6) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - default: - UE_list->UE_template[CC_id][UE_id].DAI = 0; - LOG_N(MAC, "unknow TDD config %d\n", tdd_config); - break; - } + default: + UE_list->UE_template[CC_id][UE_id].DAI = 0; + LOG_N(MAC, "unknow TDD config %d\n", tdd_config); + break; + } } void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) @@ -1730,22 +1823,22 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) #ifdef FORMAT1C int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ const int GAP_MAP [9][2] = { - {-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/ - {4, 0}, /* N_RB_DL [11] */ - {8, 0}, /* N_RB_DL [12-19] */ - {12, 0}, /* N_RB_DL [20-26] */ - {18, 0}, /* N_RB_DL [27-44] */ - {27, 0}, /* N_RB_DL [45-49] */ - {27, 9}, /* N_RB_DL [50-63] */ - {32, 16}, /* N_RB_DL [64-79] */ - {48, 16} /* N_RB_DL [80-110] */ - }; + {-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/ + {4, 0}, /* N_RB_DL [11] */ + {8, 0}, /* N_RB_DL [12-19] */ + {12, 0}, /* N_RB_DL [20-26] */ + {18, 0}, /* N_RB_DL [27-44] */ + {27, 0}, /* N_RB_DL [45-49] */ + {27, 9}, /* N_RB_DL [50-63] */ + {32, 16}, /* N_RB_DL [64-79] */ + {48, 16} /* N_RB_DL [80-110] */ + }; uint8_t n_rb_step = 0; uint8_t n_gap = 0; uint8_t n_vrb_dl = 0; uint8_t Lcrbs = 0; uint16_t rb_bit = 168; /* RB bit number value is unsure */ - #endif +#endif start_meas(&eNB->schedule_pch); @@ -1754,310 +1847,312 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) vrb_map = (void*)&cc->vrb_map; n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - for (uint16_t i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (UE_PF_PO[CC_id][i].enable_flag != TRUE) { continue; } if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { - pcch_sdu_length = mac_rrc_data_req(module_idP, + pcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, PCCH,1, &cc->PCCH_pdu.payload[0], - 1, - module_idP, i); // used for ue index - if (pcch_sdu_length == 0) { - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); - continue; - } - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); + if (pcch_sdu_length == 0) { + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); + continue; + } + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); #ifdef FORMAT1C - //NO SIB - if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { + //NO SIB + if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { #if 0 - case 6: - n_gap = n_rb_dl/2; /* expect: 3 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ - first_rb = 0; - break; - case 15: - n_gap = GAP_MAP[2][0]; /* expect: 8 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ - first_rb = 6; - break; + case 6: + n_gap = n_rb_dl/2; /* expect: 3 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ + first_rb = 0; + break; + case 15: + n_gap = GAP_MAP[2][0]; /* expect: 8 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ + first_rb = 6; + break; #endif - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 10; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 24; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 10; + break; + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + first_rb = 24; + break; + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { #if 0 - case 6: - n_gap = n_rb_dl/2; /* expect: 3 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ - first_rb = 0; - break; - case 15: - n_gap = GAP_MAP[2][0]; /* expect: 8 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ - first_rb = 10; - break; + case 6: + n_gap = n_rb_dl/2; /* expect: 3 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ + first_rb = 0; + break; + case 15: + n_gap = GAP_MAP[2][0]; /* expect: 8 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ + first_rb = 10; + break; #endif - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 14; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 28; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 52; - break; - } - } - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= TBStable1C[0]) { - mcs=0; - } else if (pcch_sdu_length <= TBStable1C[1]) { - mcs=1; - } else if (pcch_sdu_length <= TBStable1C[2]) { - mcs=2; - } else if (pcch_sdu_length <= TBStable1C[3]) { - mcs=3; - } else if (pcch_sdu_length <= TBStable1C[4]) { - mcs=4; - } else if (pcch_sdu_length <= TBStable1C[5]) { - mcs=5; - } else if (pcch_sdu_length <= TBStable1C[6]) { - mcs=6; - } else if (pcch_sdu_length <= TBStable1C[7]) { - mcs=7; - } else if (pcch_sdu_length <= TBStable1C[8]) { - mcs=8; - } else if (pcch_sdu_length <= TBStable1C[9]) { - mcs=9; - } else { - /* unexpected: pcch sdb size is over max value*/ - LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", - module_idP, frameP,CC_id, pcch_sdu_length); - return; - } - rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; - /* calculate N_RB_STEP and Lcrbs */ - if (n_rb_dl < 50) { - n_rb_step = 2; - Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); - } else { - n_rb_step = 4; - Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); - } - for(i = 0;i < Lcrbs ;i++){ - vrb_map[first_rb+i] = 1; - } + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 14; + break; + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + first_rb = 28; + break; + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + first_rb = 52; + break; + } + } + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= TBStable1C[0]) { + mcs=0; + } else if (pcch_sdu_length <= TBStable1C[1]) { + mcs=1; + } else if (pcch_sdu_length <= TBStable1C[2]) { + mcs=2; + } else if (pcch_sdu_length <= TBStable1C[3]) { + mcs=3; + } else if (pcch_sdu_length <= TBStable1C[4]) { + mcs=4; + } else if (pcch_sdu_length <= TBStable1C[5]) { + mcs=5; + } else if (pcch_sdu_length <= TBStable1C[6]) { + mcs=6; + } else if (pcch_sdu_length <= TBStable1C[7]) { + mcs=7; + } else if (pcch_sdu_length <= TBStable1C[8]) { + mcs=8; + } else if (pcch_sdu_length <= TBStable1C[9]) { + mcs=9; + } else { + /* unexpected: pcch sdb size is over max value*/ + LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", + module_idP, frameP,CC_id, pcch_sdu_length); + return; + } + rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; + /* calculate N_RB_STEP and Lcrbs */ + if (n_rb_dl < 50) { + n_rb_step = 2; + Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); + } else { + n_rb_step = 4; + Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); + } + for(i = 0;i < Lcrbs ;i++){ + vrb_map[first_rb+i] = 1; + } #else - //NO SIB - if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { - case 25: - first_rb = 10; - break; - case 50: - first_rb = 24; - break; - case 100: - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { - case 25: - first_rb = 14; - break; - case 50: - first_rb = 28; - break; - case 100: - first_rb = 52; - break; - } - } + //NO SIB + if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { + case 25: + first_rb = 10; + break; + case 50: + first_rb = 24; + break; + case 100: + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { + case 25: + first_rb = 14; + break; + case 50: + first_rb = 28; + break; + case 100: + first_rb = 52; + break; + } + } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= get_TBS_DL(0,3)) { - mcs=0; - } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { - mcs=1; - } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { - mcs=2; - } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { - mcs=3; - } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { - mcs=4; - } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { - mcs=5; - } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { - mcs=6; - } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { - mcs=7; - } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { - mcs=8; - } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { - mcs=9; - } + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= get_TBS_DL(0,3)) { + mcs=0; + } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { + mcs=1; + } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { + mcs=2; + } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { + mcs=3; + } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { + mcs=4; + } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { + mcs=5; + } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { + mcs=6; + } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { + mcs=7; + } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { + mcs=8; + } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { + mcs=9; + } #endif - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); #ifdef FORMAT1C - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; #else - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; +#endif + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + + // Rel10 fields +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; +#endif + // Rel13 fields +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; #endif - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; - - if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { - LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; + + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { + LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; #ifdef FORMAT1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); #else - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized #endif - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; - - eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = pcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = pcch_sdu_length; - TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - } else { - LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP); - continue; - } + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + + eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = pcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pcch_sdu_length; + TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + } else { + LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP); + continue; + } - if (opt_enabled == 1) { - trace_pdu(1, - &eNB->common_channels[CC_id].PCCH_pdu.payload[0], - pcch_sdu_length, - 0xffff, - PCCH, - P_RNTI, - eNB->frame, - eNB->subframe, - 0, - 0); - LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); + if (opt_enabled == 1) { + trace_pdu(1, + &eNB->common_channels[CC_id].PCCH_pdu.payload[0], + pcch_sdu_length, + 0xffff, + PCCH, + P_RNTI, + eNB->frame, + eNB->subframe, + 0, + 0); + LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); + } + eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; + eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; + eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; + eNB->eNB_stats[CC_id].pcch_mcs=mcs; + //paging first_rb log + LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", + module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); + + pthread_mutex_lock(&ue_pf_po_mutex); + memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); + pthread_mutex_unlock(&ue_pf_po_mutex); } - eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; - eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; - eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; - eNB->eNB_stats[CC_id].pcch_mcs=mcs; - //paging first_rb log - LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", - module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); - - pthread_mutex_lock(&ue_pf_po_mutex); - memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); - pthread_mutex_unlock(&ue_pf_po_mutex); - } } } /* this might be misleading when pcch is inactive */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 85d6a84c6f520eecc0dd0dc745235d99e259b06a..6bb4e9aab0fb146a58cd52be245cb53ca39034a5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -32,22 +32,17 @@ #include <stdlib.h> #include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "PHY/phy_extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/MAC/eNB_scheduler_fairRR.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#include "RRC/LITE/extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "rlc.h" @@ -608,7 +603,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, subframeP, N_RBG[CC_id], nb_rbs_required, - nb_rbs_required_remaining, rballoc_sub, MIMO_mode_indicator); @@ -1270,7 +1264,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, header_len_dcch = 2; // 2 bytes DCCH SDU subheader if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch) +#ifdef Rel14 + ,0, 0 +#endif + ); // transport block set size sdu_lengths[0] = 0; @@ -1282,7 +1280,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used (char *) &dlsch_buffer - [0]); + [0] +#ifdef Rel14 + ,0, 0 +#endif + ); pthread_mutex_lock(&rrc_release_freelist); if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){ uint16_t release_total = 0; @@ -1367,7 +1369,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, } // check for DCCH1 and update header information (assume 2 byte sub-header) if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total) +#ifdef Rel14 + ,0, 0 +#endif + ); // transport block set size less allocations for timing advance and // DCCH SDU sdu_lengths[num_sdus] = 0; @@ -1379,7 +1385,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used (char *) &dlsch_buffer - [sdu_length_total]); + [sdu_length_total] +#ifdef Rel14 + ,0, 0 +#endif + ); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), @@ -1437,7 +1447,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, TBS - ta_len - header_len_dcch - sdu_length_total - - header_len_dtch); + header_len_dtch +#ifdef Rel14 + ,0, 0 +#endif + ); if (rlc_status.bytes_in_buffer > 0) { @@ -1452,7 +1466,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, (char *) &dlsch_buffer - [sdu_length_total]); + [sdu_length_total] +#ifdef Rel14 + ,0, 0 +#endif + ); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), @@ -2043,10 +2061,13 @@ void ulsch_scheduler_pre_ue_select_fairRR( } } // + int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + if ( UE_id > last_ulsch_ue_id[CC_id] && ((ulsch_ue_select[CC_id].ue_num+ue_first_num[CC_id]) < ulsch_ue_max_num[CC_id]) ) { - if ( UE_list->UE_template[CC_id][UE_id].ul_total_buffer > 0 ) { + if ( bytes_to_schedule > 0 ) { first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; - first_ue_total[CC_id][ue_first_num[CC_id]] = UE_list->UE_template[CC_id][UE_id].ul_total_buffer; + first_ue_total[CC_id][ue_first_num[CC_id]] = bytes_to_schedule; ue_first_num[CC_id]++; continue; } @@ -2154,7 +2175,11 @@ void ulsch_scheduler_pre_ue_select_fairRR( HI_DCI0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; //SR BSR UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - if ( (UE_list->UE_template[CC_id][UE_id].ul_total_buffer > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) || + + int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + + if ( (bytes_to_schedule > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) || ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) ){ hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; @@ -2169,8 +2194,8 @@ void ulsch_scheduler_pre_ue_select_fairRR( HI_DCI0_req->number_of_dci++; ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_FIRST; - if(UE_list->UE_template[CC_id][UE_id].ul_total_buffer > 0) - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = UE_list->UE_template[CC_id][UE_id].ul_total_buffer; + if(bytes_to_schedule > 0) + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = bytes_to_schedule; else if(UE_list->UE_template[CC_id][UE_id].ul_SR > 0) ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0; ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id; @@ -2350,18 +2375,21 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, mcs = 10; } if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST ) { + int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0 ) { rb_table_index = 2; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); - while ( (((UE_template->phr_info - tx_power) < 0 ) || (tbs > UE_template->ul_total_buffer)) && (mcs > 3) ) { + while ( (((UE_template->phr_info - tx_power) < 0 ) || (tbs > bytes_to_schedule)) && (mcs > 3) ) { mcs--; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); } - while ( (tbs < UE_template->ul_total_buffer) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) && + while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { rb_table_index++; tbs = get_TBS_UL(mcs,rb_table[rb_table_index])<<3; @@ -2374,7 +2402,7 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, if ( rb_table[rb_table_index] <= average_rbs ) { // assigne RBS( nb_rb) first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index]; - UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = rb_table[rb_table_index]; + UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = rb_table[rb_table_index]; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } @@ -2387,21 +2415,21 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, break; } first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index]; - UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = rb_table[rb_table_index]; + UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = rb_table[rb_table_index]; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } }else { // assigne RBS( 3 RBs) first_rb[CC_id] = first_rb[CC_id] + 3; - UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = 3; + UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; } }else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE ) { // assigne RBS( 3 RBs) first_rb[CC_id] = first_rb[CC_id] + 3; - UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = 3; + UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; } @@ -2675,7 +2703,10 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL); - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer; + int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = bytes_to_schedule; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); status = mac_eNB_get_rrc_status(module_idP,rnti); @@ -2888,6 +2919,9 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, // increment first rb for next UE allocation first_rb[CC_id]+=rb_table[rb_table_index]; if(ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST) { + UE_template->scheduled_ul_bytes += get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]); + UE_template->ul_SR = 0; +#if 0 LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index])); if(ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0){ if (UE_template->ul_total_buffer > get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index])) @@ -2899,6 +2933,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_template->ul_SR = 0; } LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer); +#endif } if((ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE) && (ULSCH_first_end == 0)) { ULSCH_first_end = 1; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 7ce5a5b12c3e4f737de710c27dada2c647ab5ced..bcaa30e3c1f5e30919f3717263dda5ba97006eb6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -29,40 +29,37 @@ */ -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" +#include "assertions.h" #if defined(ENABLE_ITTI) #include "intertask_interface.h" #endif -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 +#include "common/ran_context.h" extern RAN_CONTEXT_t RC; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int8_t get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area) @@ -545,8 +542,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", module_idP, CC_id, frameP, subframeP, i, j); - mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0], 1, // this is eNB - module_idP, // index + mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0], i); // this is the mbsfn sync area index if (mcch_sdu_length > 0) { @@ -589,7 +585,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, TBS = get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // do not let mcch and mtch multiplexing when relaying is active // for sync area 1, so not transmit data //if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) { @@ -636,7 +632,12 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, TBS - header_len_mcch - header_len_msi - - sdu_length_total - header_len_mtch); + sdu_length_total - header_len_mtch +#ifdef Rel14 + ,0, 0 +#endif + ); + LOG_D(MAC, "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", MTCH, frameP, subframeP, rlc_status.bytes_in_buffer); @@ -650,9 +651,15 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0, //not used (char *) - &mch_buffer - [sdu_length_total]); - //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]); + &mch_buffer[sdu_length_total] +#ifdef Rel14 + ,0, + 0 +#endif + ); + + + //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(MAX_MOBILES_PER_ENB+1)), (char*)&mch_buffer[sdu_length_total]); LOG_I(MAC, "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n", module_idP, CC_id, sdu_lengths[num_sdus], MTCH); @@ -669,7 +676,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, header_len_mtch = 0; } } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // } #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c new file mode 100644 index 0000000000000000000000000000000000000000..cd403a146f57baff562fe797483348f25a221d10 --- /dev/null +++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c @@ -0,0 +1,353 @@ +/* + * 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 eNB_scheduler_dlsch.c + * \brief procedures related to eNB for the DLSCH transport channel + * \author Navid Nikaein and Raymond Knopp + * \date 2010 - 2014 + * \email: navid.nikaein@eurecom.fr + * \version 1.0 + * @ingroup _mac + + */ + +#include "assertions.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" + +#include "SCHED/sched_eNB.h" + +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_extern.h" +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "OCG.h" +#include "OCG_extern.h" + +#include "SIMULATION/TOOLS/sim.h" // for taus + +#include "T.h" + +extern RAN_CONTEXT_t RC; + +//------------------------------------------------------------------------------ +void +schedule_ue_spec_phy_test( + module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP, + int* mbsfn_flag +) +//------------------------------------------------------------------------------ +{ + uint8_t CC_id; + int UE_id=0; + uint16_t N_RB_DL; + uint16_t TBS; + uint16_t nb_rb; + + unsigned char harq_pid = subframeP%5; + uint16_t rnti = 0x1235; + uint32_t rb_alloc = 0x1FFFFFFF; + int32_t tpc = 1; + int32_t mcs = 28; + int32_t cqi = 15; + int32_t ndi = subframeP/5; + int32_t dai = 0; + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + nfapi_dl_config_request_body_t *dl_req; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id); + + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + + if (mbsfn_flag[CC_id]>0) + continue; + + nb_rb = conv_nprb(0,rb_alloc,N_RB_DL); + //printf("////////////////////////////////////*************************nb_rb = %d\n",nb_rb); + TBS = get_TBS_DL(mcs,nb_rb); + + LOG_D(PHY,"schedule_ue_spec_phy_test: subframe %d/%d: nb_rb=%d, TBS=%d, mcs=%d (rb_alloc=%x, N_RB_DL=%d)\n",frameP,subframeP,nb_rb,TBS,mcs,rb_alloc,N_RB_DL); + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),cqi,format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rb_alloc; + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = dai; + LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP,CC_id,harq_pid,dai,mcs); + } else { + LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP,CC_id,harq_pid,mcs); + + } + LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu); + if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) { + + + //ue_sched_ctl->round[CC_id][harq_pid] = 0; + dl_req->number_dci++; + dl_req->number_pdu++; + + // Toggle NDI for next time + /* + LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP,subframeP,UE_id, + rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); + + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; + UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n"); + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); + */ + + + + fill_nfapi_dlsch_config(eNB, + dl_req, + TBS, + eNB->pdu_index[CC_id], + rnti, + 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag + rb_alloc, // resource_block_coding + getQm(mcs), + 0, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + PDSCH_ConfigDedicated__p_a_dB0, + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, + (frameP*10)+subframeP, + TBS, + eNB->pdu_index[CC_id], + eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]); + } + else { + LOG_W(MAC,"[eNB_scheduler_phytest] DCI allocation infeasible!\n"); + } + } +} + +void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) +{ + uint16_t first_rb[MAX_NUM_CCs]; + int UE_id = 0; + uint8_t aggregation = 2; + rnti_t rnti = 0x1235; + uint8_t mcs = 0; + uint8_t harq_pid = 0; + uint32_t cqi_req = 0,cshift,ndi,tpc = 1; + int32_t normalized_rx_power; + int32_t target_rx_power= 178; + int CC_id = 0; + int nb_rb = 96; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list=&eNB->UE_list; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *UE_sched_ctrl; + int sched_frame=frameP; + int sched_subframe = (subframeP+4)%10; + + if (sched_subframe<subframeP) sched_frame++; + + nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + + //nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[0];; + nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req[CC_id].ul_config_request_body; + + + eNB->UL_req[CC_id].sfn_sf = (sched_frame<<4) + sched_subframe; + eNB->HI_DCI0_req[CC_id][subframeP].sfn_sf = (frameP<<4)+subframeP; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + //rnti = UE_RNTI(module_idP,UE_id); + //leave out first RB for PUCCH + first_rb[CC_id] = 1; + // loop over all active UEs + + // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel + + UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; + harq_pid = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframe); + + LOG_D(MAC,"Scheduling for frame %d, subframe %d => harq_pid %d\n",sched_frame,sched_subframe,harq_pid); + + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->TBS_UL[harq_pid]; + + + + //power control + //compute the expected ULSCH RX power (for the stats) + + // this is the normalized RX power and this should be constant (regardless of mcs + normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; + + // new transmission + + ndi = 1-UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid]=ndi; + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs; + UE_template->mcs_UL[harq_pid] = mcs;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs; + // buffer_occupancy = UE_template->ul_total_buffer; + + + + UE_template->TBS_UL[harq_pid] = get_TBS_UL(mcs,nb_rb); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = get_TBS_UL(mcs,nb_rb); + // buffer_occupancy -= TBS; + + + + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = nb_rb; + UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + + UE_sched_ctrl->ul_scheduled |= (1<<harq_pid); + + // adjust total UL buffer status by TBS, wait for UL sdus to do final update + //UE_template->ul_total_buffer = UE_template->TBS_UL[harq_pid]; + // Cyclic shift for DM RS + cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + // save it for a potential retransmission + UE_template->cshift[harq_pid] = cshift; + + hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_hi]; + memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = nb_rb; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = mcs; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframe]; + + + eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci++; + + + // Add UL_config PDUs + fill_nfapi_ulsch_config_request_rel8(&ul_req->ul_config_pdu_list[ul_req->number_of_pdus], + cqi_req, + cc, + 0,//UE_template->physicalConfigDedicated, + get_tmode(module_idP,CC_id,UE_id), + eNB->ul_handle, + rnti, + first_rb[CC_id], // resource_block_start + nb_rb, // number_of_resource_blocks + mcs, + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL(mcs,nb_rb) + ); +#ifdef Rel14 + if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req->ul_config_pdu_list[ul_req->number_of_pdus], + UE_template->rach_resource_type>2 ? 2 : 1, + 1, //total_number_of_repetitions + 1, //repetition_number + (frameP*10)+subframeP); + } +#endif + ul_req->number_of_pdus = 1; + eNB->ul_handle++; + + + + add_ue_ulsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_UL_SCHEDULED); + + // increment first rb for next UE allocation + first_rb[CC_id]+= nb_rb; + + + } // loop of CC_id +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 13da611c966537d6882a522182f918b446d92c16..1ac70037235e8a8df48ca7dd3c088d1c295d2285 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -30,23 +30,18 @@ */ #include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" - -#include "LAYER2/MAC/proto.h" +#include "LAYER2/MAC/mac_proto.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" @@ -62,212 +57,214 @@ #define DEBUG_eNB_SCHEDULER 1 extern uint16_t frame_cnt; +#include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; + +extern int n_active_slices; + int choose(int n, int k) { - int res = 1; - int res2 = 1; - int i; + int res = 1; + int res2 = 1; + int i; - if (k > n) - return (0); - if (n == k) - return (1); + if (k > n) + return (0); + if (n == k) + return (1); - for (i = n; i > k; i--) - res *= i; - for (i = 2; i <= (n - k); i++) - res2 *= i; + for (i = n; i > k; i--) + res *= i; + for (i = 2; i <= (n - k); i++) + res2 *= i; - return (res / res2); + return (res / res2); } // Patented algorithm from Yang et al, US Patent 2009, "Channel Quality Indexing and Reverse Indexing" void reverse_index(int N, int M, int r, int *v) { - int BaseValue = 0; - int IncreaseValue, ThresholdValue; - int sumV; - int i; - - r = choose(N, M) - 1 - r; - memset((void *) v, 0, M * sizeof(int)); - - sumV = 0; - i = M; - while (i > 0 && r > 0) { - IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2, i - 1); - ThresholdValue = BaseValue + IncreaseValue; - if (r >= ThresholdValue) { - v[i - 1]++; - BaseValue = ThresholdValue; - } else { - r = r - BaseValue; - sumV += v[i - 1]; - i--; - BaseValue = 0; - } + int BaseValue = 0; + int IncreaseValue, ThresholdValue; + int sumV; + int i; + + r = choose(N, M) - 1 - r; + memset((void *) v, 0, M * sizeof(int)); + + sumV = 0; + i = M; + while (i > 0 && r > 0) { + IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2, i - 1); + ThresholdValue = BaseValue + IncreaseValue; + if (r >= ThresholdValue) { + v[i - 1]++; + BaseValue = ThresholdValue; + } else { + r = r - BaseValue; + sumV += v[i - 1]; + i--; + BaseValue = 0; } + } } int to_prb(int dl_Bandwidth) { - int prbmap[6] = { 6, 15, 25, 50, 75, 100 }; + int prbmap[6] = { 6, 15, 25, 50, 75, 100 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); - return (prbmap[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); + return (prbmap[dl_Bandwidth]); } int to_rbg(int dl_Bandwidth) { - int rbgmap[6] = { 6, 8, 13, 17, 19, 25 }; + int rbgmap[6] = { 6, 8, 13, 17, 19, 25 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); - return (rbgmap[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); + return (rbgmap[dl_Bandwidth]); } int get_phich_resource_times6(COMMON_channels_t * cc) { - int phichmap[4] = { 1, 3, 6, 12 }; - AssertFatal(cc != NULL, "cc is null\n"); - AssertFatal(cc->mib != NULL, "cc->mib is null\n"); - AssertFatal((cc->mib->message.phich_Config.phich_Resource >= 0) && - (cc->mib->message.phich_Config.phich_Resource < 4), - "phich_Resource %d not in 0..3\n", - (int) cc->mib->message.phich_Config.phich_Resource); - - return (phichmap[cc->mib->message.phich_Config.phich_Resource]); + int phichmap[4] = { 1, 3, 6, 12 }; + AssertFatal(cc != NULL, "cc is null\n"); + AssertFatal(cc->mib != NULL, "cc->mib is null\n"); + AssertFatal((cc->mib->message.phich_Config.phich_Resource >= 0) && + (cc->mib->message.phich_Config.phich_Resource < 4), + "phich_Resource %d not in 0..3\n", + (int) cc->mib->message.phich_Config.phich_Resource); + + return (phichmap[cc->mib->message.phich_Config.phich_Resource]); } uint16_t mac_computeRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs) { - uint16_t RIV; + uint16_t RIV; - if (Lcrbs <= (1 + (N_RB_DL >> 1))) - RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; - else - RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); + if (Lcrbs <= (1 + (N_RB_DL >> 1))) RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; + else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); - return (RIV); + return (RIV); } uint8_t getQm(uint8_t mcs) { - if (mcs < 10) - return (2); - else if (mcs < 17) - return (4); - else - return (6); + if (mcs < 10) return (2); + else if (mcs < 17) return (4); + else return (6); } void -get_Msg3alloc(COMMON_channels_t * cc, - sub_frame_t current_subframe, - frame_t current_frame, frame_t * frame, - sub_frame_t * subframe) +get_Msg3alloc(COMMON_channels_t *cc, + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe) { - // Fill in other TDD Configuration!!!! + // Fill in other TDD Configuration!!!! - if (cc->tdd_Config == NULL) { // FDD - *subframe = current_subframe + 6; + if (cc->tdd_Config == NULL) { // FDD + *subframe = current_subframe + 6; - if (*subframe > 9) { - *subframe = *subframe - 10; - *frame = (current_frame + 1) & 1023; - } else { - *frame = current_frame; - } - } else { // TDD - if (cc->tdd_Config->subframeAssignment == 1) { - switch (current_subframe) { - - case 0: - *subframe = 7; - *frame = current_frame; - break; - - case 4: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 5: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 9: - *subframe = 7; - *frame = (current_frame + 1) & 1023; - break; - } - } else if (cc->tdd_Config->subframeAssignment == 3) { - switch (current_subframe) { - - case 0: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - *subframe = 3; - *frame = (current_frame + 1) & 1023; - break; - - case 8: - *subframe = 4; - *frame = (current_frame + 1) & 1023; - break; - - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; - } - } else if (cc->tdd_Config->subframeAssignment == 4) { - switch (current_subframe) { - - case 0: - case 4: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - *subframe = 3; - *frame = (current_frame + 1) & 1023; - break; - - case 8: - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; - } - } else if (cc->tdd_Config->subframeAssignment == 5) { - switch (current_subframe) { - - case 0: - case 4: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - case 8: - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; - } - } + if (*subframe > 9) { + *subframe = *subframe - 10; + *frame = (current_frame + 1) & 1023; + } else { + *frame = current_frame; + } + } else { // TDD + if (cc->tdd_Config->subframeAssignment == 1) { + switch (current_subframe) { + + case 0: + *subframe = 7; + *frame = current_frame; + break; + + case 4: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 5: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 9: + *subframe = 7; + *frame = (current_frame + 1) & 1023; + break; + } + } else if (cc->tdd_Config->subframeAssignment == 3) { + switch (current_subframe) { + + case 0: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 7: + *subframe = 3; + *frame = (current_frame + 1) & 1023; + break; + + case 8: + *subframe = 4; + *frame = (current_frame + 1) & 1023; + break; + + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; + } + } else if (cc->tdd_Config->subframeAssignment == 4) { + switch (current_subframe) { + + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 7: + *subframe = 3; + *frame = (current_frame + 1) & 1023; + break; + + case 8: + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; + } + } else if (cc->tdd_Config->subframeAssignment == 5) { + switch (current_subframe) { + + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 7: + case 8: + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; + } } + } } @@ -278,306 +275,285 @@ get_Msg3allocret(COMMON_channels_t * cc, frame_t current_frame, frame_t * frame, sub_frame_t * subframe) { - if (cc->tdd_Config == NULL) { //FDD - /* always retransmit in n+8 */ - *subframe = current_subframe + 8; + if (cc->tdd_Config == NULL) { //FDD + /* always retransmit in n+8 */ + *subframe = current_subframe + 8; - if (*subframe > 9) { - *subframe = *subframe - 10; - *frame = (current_frame + 1) & 1023; - } else { - *frame = current_frame; - } + if (*subframe > 9) { + *subframe = *subframe - 10; + *frame = (current_frame + 1) & 1023; } else { - if (cc->tdd_Config->subframeAssignment == 1) { - // original PUSCH in 2, PHICH in 6 (S), ret in 2 - // original PUSCH in 3, PHICH in 9, ret in 3 - // original PUSCH in 7, PHICH in 1 (S), ret in 7 - // original PUSCH in 8, PHICH in 4, ret in 8 - *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 3) { - // original PUSCH in 2, PHICH in 8, ret in 2 next frame - // original PUSCH in 3, PHICH in 9, ret in 3 next frame - // original PUSCH in 4, PHICH in 0, ret in 4 next frame - *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 4) { - // original PUSCH in 2, PHICH in 8, ret in 2 next frame - // original PUSCH in 3, PHICH in 9, ret in 3 next frame - *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 5) { - // original PUSCH in 2, PHICH in 8, ret in 2 next frame - *frame = (current_frame + 1) & 1023; - } + *frame = current_frame; } + } else { + if (cc->tdd_Config->subframeAssignment == 1) { + // original PUSCH in 2, PHICH in 6 (S), ret in 2 + // original PUSCH in 3, PHICH in 9, ret in 3 + // original PUSCH in 7, PHICH in 1 (S), ret in 7 + // original PUSCH in 8, PHICH in 4, ret in 8 + *frame = (current_frame + 1) & 1023; + } else if (cc->tdd_Config->subframeAssignment == 3) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + // original PUSCH in 3, PHICH in 9, ret in 3 next frame + // original PUSCH in 4, PHICH in 0, ret in 4 next frame + *frame = (current_frame + 1) & 1023; + } else if (cc->tdd_Config->subframeAssignment == 4) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + // original PUSCH in 3, PHICH in 9, ret in 3 next frame + *frame = (current_frame + 1) & 1023; + } else if (cc->tdd_Config->subframeAssignment == 5) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + *frame = (current_frame + 1) & 1023; + } + } } uint8_t subframe2harqpid(COMMON_channels_t * cc, frame_t frame, sub_frame_t subframe) { - uint8_t ret = 255; + uint8_t ret = 255; - AssertFatal(cc != NULL, "cc is null\n"); - - if (cc->tdd_Config == NULL) { // FDD - ret = (((frame << 1) + subframe) & 7); - } else { - switch (cc->tdd_Config->subframeAssignment) { - case 1: - if ((subframe == 2) || - (subframe == 3) || (subframe == 7) || (subframe == 8)) - switch (subframe) { - case 2: - case 3: - ret = (subframe - 2); - break; - - case 7: - case 8: - ret = (subframe - 5); - break; - - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - break; - } - - break; + AssertFatal(cc != NULL, "cc is null\n"); + if (cc->tdd_Config == NULL) { // FDD + ret = (((frame << 1) + subframe) & 7); + } else { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + if ((subframe == 2) || + (subframe == 3) || (subframe == 7) || (subframe == 8)) + switch (subframe) { case 2: - AssertFatal((subframe == 2) || (subframe == 7), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - - ret = (subframe / 7); - break; - case 3: - AssertFatal((subframe > 1) && (subframe < 5), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; - - case 4: - AssertFatal((subframe > 1) && (subframe < 4), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; - - case 5: - AssertFatal(subframe == 2, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; - + ret = (subframe - 2); + break; + case 7: + case 8: + ret = (subframe - 5); + break; default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Unsupported TDD mode %d\n", - (int) cc->tdd_Config->subframeAssignment); + AssertFatal(1 == 0, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + break; } - } - return ret; -} -uint8_t -get_Msg3harqpid(COMMON_channels_t * cc, - frame_t frame, sub_frame_t current_subframe) -{ - uint8_t ul_subframe = 0; - uint32_t ul_frame = 0; - - if (cc->tdd_Config == NULL) { // FDD - ul_subframe = - (current_subframe > - 3) ? (current_subframe - 4) : (current_subframe + 6); - ul_frame = (current_subframe > 3) ? ((frame + 1) & 1023) : frame; - } else { - switch (cc->tdd_Config->subframeAssignment) { - case 1: - switch (current_subframe) { - case 9: - case 0: - ul_subframe = 7; - break; + break; - case 5: - case 7: - ul_subframe = 2; - break; + case 2: + AssertFatal((subframe == 2) || (subframe == 7), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); - } + ret = (subframe / 7); + break; - break; + case 3: + AssertFatal((subframe > 1) && (subframe < 5), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; - case 3: - switch (current_subframe) { - case 0: - case 5: - case 6: - ul_subframe = 2; - break; - - case 7: - ul_subframe = 3; - break; - - case 8: - ul_subframe = 4; - break; - - case 9: - ul_subframe = 2; - break; - } - - break; - - case 4: - switch (current_subframe) { - case 0: - case 5: - case 6: - case 8: - case 9: - ul_subframe = 2; - break; - - case 7: - ul_subframe = 3; - break; - } - - break; - - case 5: - ul_subframe = 2; - break; + case 4: + AssertFatal((subframe > 1) && (subframe < 4), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; - default: - LOG_E(PHY, - "get_Msg3_harq_pid: Unsupported TDD configuration %d\n", + case 5: + AssertFatal(subframe == 2, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, (int) cc->tdd_Config->subframeAssignment); - AssertFatal(1 == 0, - "get_Msg3_harq_pid: Unsupported TDD configuration"); - break; - } + ret = (subframe - 2); + break; + + default: + AssertFatal(1 == 0, + "subframe2_harq_pid, Unsupported TDD mode %d\n", + (int) cc->tdd_Config->subframeAssignment); + } + } + return ret; +} + +uint8_t +get_Msg3harqpid(COMMON_channels_t * cc, + frame_t frame, sub_frame_t current_subframe) +{ + uint8_t ul_subframe = 0; + uint32_t ul_frame = 0; + + if (cc->tdd_Config == NULL) { // FDD + ul_subframe = + (current_subframe > + 3) ? (current_subframe - 4) : (current_subframe + 6); + ul_frame = (current_subframe > 3) ? ((frame + 1) & 1023) : frame; + } else { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + switch (current_subframe) { + case 9: + case 0: + ul_subframe = 7; + break; + case 5: + case 7: + ul_subframe = 2; + break; + } + break; + case 3: + switch (current_subframe) { + case 0: + case 5: + case 6: + ul_subframe = 2; + break; + case 7: + ul_subframe = 3; + break; + case 8: + ul_subframe = 4; + break; + case 9: + ul_subframe = 2; + break; + } + break; + case 4: + switch (current_subframe) { + case 0: + case 5: + case 6: + case 8: + case 9: + ul_subframe = 2; + break; + case 7: + ul_subframe = 3; + break; + } + break; + case 5: + ul_subframe = 2; + break; + default: + LOG_E(PHY, + "get_Msg3_harq_pid: Unsupported TDD configuration %d\n", + (int) cc->tdd_Config->subframeAssignment); + AssertFatal(1 == 0, + "get_Msg3_harq_pid: Unsupported TDD configuration"); + break; } + } - return (subframe2harqpid(cc, ul_frame, ul_subframe)); + return (subframe2harqpid(cc, ul_frame, ul_subframe)); } uint32_t pdcchalloc2ulframe(COMMON_channels_t * ccP, uint32_t frame, uint8_t n) { - uint32_t ul_frame; - - if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 - ul_frame = (frame + (n == 1 ? 0 : 1)); - else if ((ccP->tdd_Config) && - (ccP->tdd_Config->subframeAssignment == 6) && - ((n == 0) || (n == 1) || (n == 5) || (n == 6))) - ul_frame = (frame + (n >= 5 ? 1 : 0)); - else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 - ul_frame = (frame + 1); - else - ul_frame = (frame + (n >= 6 ? 1 : 0)); - - LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, - ul_frame); - return ul_frame; + uint32_t ul_frame; + + if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 + ul_frame = (frame + (n == 1 ? 0 : 1)); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + ((n == 0) || (n == 1) || (n == 5) || (n == 6))) + ul_frame = (frame + (n >= 5 ? 1 : 0)); + else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 + ul_frame = (frame + 1); + else + ul_frame = (frame + (n >= 6 ? 1 : 0)); + + LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, + ul_frame); + return ul_frame; } uint8_t pdcchalloc2ulsubframe(COMMON_channels_t * ccP, uint8_t n) { - uint8_t ul_subframe; - - if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 - ul_subframe = ((n + 6) % 10); - else if ((ccP->tdd_Config) && - (ccP->tdd_Config->subframeAssignment == 6) && - ((n == 0) || (n == 1) || (n == 5) || (n == 6))) - ul_subframe = ((n + 7) % 10); - else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 - ul_subframe = ((n + 5) % 10); - else - ul_subframe = ((n + 4) % 10); - - LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); - return ul_subframe; + uint8_t ul_subframe; + + if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 + ul_subframe = ((n + 6) % 10); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + ((n == 0) || (n == 1) || (n == 5) || (n == 6))) + ul_subframe = ((n + 7) % 10); + else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 + ul_subframe = ((n + 5) % 10); + else + ul_subframe = ((n + 4) % 10); + + LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); + return ul_subframe; } int is_UL_sf(COMMON_channels_t * ccP, sub_frame_t subframeP) { - // if FDD return dummy value - if (ccP->tdd_Config == NULL) - return (0); - - switch (ccP->tdd_Config->subframeAssignment) { - case 1: - switch (subframeP) { - case 0: - case 4: - case 5: - case 9: - return (0); - break; - - case 2: - case 3: - case 7: - case 8: - return (1); - break; - - default: - return (0); - break; - } - break; - - case 3: - if ((subframeP <= 1) || (subframeP >= 5)) - return (0); - else if ((subframeP > 1) && (subframeP < 5)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; + // if FDD return dummy value + if (ccP->tdd_Config == NULL) + return (0); + switch (ccP->tdd_Config->subframeAssignment) { + case 1: + switch (subframeP) { + case 0: case 4: - if ((subframeP <= 1) || (subframeP >= 4)) - return (0); - else if ((subframeP > 1) && (subframeP < 4)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; - case 5: - if ((subframeP <= 1) || (subframeP >= 3)) - return (0); - else if ((subframeP > 1) && (subframeP < 3)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; - + case 9: + return (0); + break; + case 2: + case 3: + case 7: + case 8: + return (1); + break; default: - AssertFatal(1 == 0, - "subframe %d Unsupported TDD configuration %d\n", - subframeP, (int) ccP->tdd_Config->subframeAssignment); - break; + return (0); + break; } + break; + case 3: + if ((subframeP <= 1) || (subframeP >= 5)) + return (0); + else if ((subframeP > 1) && (subframeP < 5)) + return (1); + else + AssertFatal(1 == 0, "Unknown subframe number\n"); + break; + case 4: + if ((subframeP <= 1) || (subframeP >= 4)) + return (0); + else if ((subframeP > 1) && (subframeP < 4)) + return (1); + else + AssertFatal(1 == 0, "Unknown subframe number\n"); + break; + case 5: + if ((subframeP <= 1) || (subframeP >= 3)) + return (0); + else if ((subframeP > 1) && (subframeP < 3)) + return (1); + else + AssertFatal(1 == 0, "Unknown subframe number\n"); + break; + default: + AssertFatal(1 == 0, + "subframe %d Unsupported TDD configuration %d\n", + subframeP, (int) ccP->tdd_Config->subframeAssignment); + break; + } } int is_S_sf(COMMON_channels_t * ccP, sub_frame_t subframeP) @@ -632,183 +608,183 @@ uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe){ uint16_t get_pucch1_absSF(COMMON_channels_t * cc, uint16_t dlsch_absSF) { - uint16_t sf, f, nextf; + uint16_t sf, f, nextf; - if (cc->tdd_Config == NULL) { //FDD n+4 - return ((dlsch_absSF + 4) % 10240); - } else { - sf = dlsch_absSF % 10; - f = dlsch_absSF / 10; - nextf = (f + 1) & 1023; - - switch (cc->tdd_Config->subframeAssignment) { - case 0: - if ((sf == 0) || (sf == 5)) - return ((10 * f) + sf + 4)% 10240; // ACK/NAK in SF 4,9 same frame - else if (sf == 6) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame - else if (sf == 1) - return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 0\n", - sf); - - break; - case 1: - if ((sf == 5) || (sf == 6)) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame - else if (sf == 9) - return ((10 * nextf) + 3)% 10240; // ACK/NAK in SF 3 next frame - else if ((sf == 0) || (sf == 1)) - return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame - else if (sf == 4) + if (cc->tdd_Config == NULL) { //FDD n+4 + return ((dlsch_absSF + 4) % 10240); + } else { + sf = dlsch_absSF % 10; + f = dlsch_absSF / 10; + nextf = (f + 1) & 1023; + + switch (cc->tdd_Config->subframeAssignment) { + case 0: + if ((sf == 0) || (sf == 5)) + return ((10 * f) + sf + 4)% 10240; // ACK/NAK in SF 4,9 same frame + else if (sf == 6) + return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame + else if (sf == 1) + return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 0\n", + sf); + + break; + case 1: + if ((sf == 5) || (sf == 6)) + return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame + else if (sf == 9) + return ((10 * nextf) + 3)% 10240; // ACK/NAK in SF 3 next frame + else if ((sf == 0) || (sf == 1)) + return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame + else if (sf == 4) return ((10 * f) + 8)% 10240; // ACK/NAK in SF 8 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 1\n", - sf); - break; - case 2: - if ((sf == 4) || (sf == 5) || (sf == 6) || (sf == 8)) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame - else if (sf == 9) - return ((10 * nextf) + 7)% 10240; // ACK/NAK in SF 7 next frame - else if ((sf == 0) || (sf == 1) || (sf == 3)) - return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 2\n", - sf); - break; - case 3: - if ((sf == 5) || (sf == 6) || (sf == 7) || (sf == 8) - || (sf == 9)) - return ((10 * nextf) + ((sf-1) >> 1))% 10240; // ACK/NAK in 2,3,4 resp. next frame - else if (sf == 1) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in 2 next frame - else if (sf == 0) - return ((10 * f) + 4)% 10240; // ACK/NAK in 4 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 3\n", - sf); - break; - case 4: - if ((sf == 6) || (sf == 7) || (sf == 8) || (sf == 9)) - return (((10 * nextf) + 3) % 10240); // ACK/NAK in SF 3 next frame - else if ((sf == 0) || (sf == 1) || (sf == 4) || (sf == 5)) - return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 2 next frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 4\n", - sf); - break; - case 5: - if ((sf == 0) || (sf == 1) || (sf == 3) || (sf == 4) - || (sf == 5) || (sf == 6) || (sf == 7) || (sf == 8)) - return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 3 next frame - else if (sf == 9) - return (((10 * (1 + nextf)) + 2) % 10240); // ACK/NAK in SF 2 next frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 5\n", - sf); - break; - case 6: - if ((sf == 5) || (sf == 6)) - return ((10 * f) + sf + 7)% 10240; // ACK/NAK in SF 2,3 next frame - else if (sf == 9) - return ((10 * nextf) + 4)% 10240; // ACK/NAK in SF 4 next frame - else if ((sf == 1) || (sf == 0)) - return ((10 * f) + sf + 7)% 10240; // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 6\n", - sf); - break; - default: - AssertFatal(1 == 0, "Illegal TDD subframe Assigment %d\n", - (int) cc->tdd_Config->subframeAssignment); - break; - } + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 1\n", + sf); + break; + case 2: + if ((sf == 4) || (sf == 5) || (sf == 6) || (sf == 8)) + return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame + else if (sf == 9) + return ((10 * nextf) + 7)% 10240; // ACK/NAK in SF 7 next frame + else if ((sf == 0) || (sf == 1) || (sf == 3)) + return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 2\n", + sf); + break; + case 3: + if ((sf == 5) || (sf == 6) || (sf == 7) || (sf == 8) + || (sf == 9)) + return ((10 * nextf) + ((sf-1) >> 1))% 10240; // ACK/NAK in 2,3,4 resp. next frame + else if (sf == 1) + return ((10 * nextf) + 2)% 10240; // ACK/NAK in 2 next frame + else if (sf == 0) + return ((10 * f) + 4)% 10240; // ACK/NAK in 4 same frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 3\n", + sf); + break; + case 4: + if ((sf == 6) || (sf == 7) || (sf == 8) || (sf == 9)) + return (((10 * nextf) + 3) % 10240); // ACK/NAK in SF 3 next frame + else if ((sf == 0) || (sf == 1) || (sf == 4) || (sf == 5)) + return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 2 next frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 4\n", + sf); + break; + case 5: + if ((sf == 0) || (sf == 1) || (sf == 3) || (sf == 4) + || (sf == 5) || (sf == 6) || (sf == 7) || (sf == 8)) + return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 3 next frame + else if (sf == 9) + return (((10 * (1 + nextf)) + 2) % 10240); // ACK/NAK in SF 2 next frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 5\n", + sf); + break; + case 6: + if ((sf == 5) || (sf == 6)) + return ((10 * f) + sf + 7)% 10240; // ACK/NAK in SF 2,3 next frame + else if (sf == 9) + return ((10 * nextf) + 4)% 10240; // ACK/NAK in SF 4 next frame + else if ((sf == 1) || (sf == 0)) + return ((10 * f) + sf + 7)% 10240; // ACK/NAK in SF 7 same frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 6\n", + sf); + break; + default: + AssertFatal(1 == 0, "Illegal TDD subframe Assigment %d\n", + (int) cc->tdd_Config->subframeAssignment); + break; } - AssertFatal(1 == 0, "Shouldn't get here\n"); + } + AssertFatal(1 == 0, "Shouldn't get here\n"); } void get_srs_pos(COMMON_channels_t * cc, uint16_t isrs, uint16_t * psrsPeriodicity, uint16_t * psrsOffset) { - if (cc->tdd_Config) { // TDD - AssertFatal(isrs >= 10, "2 ms SRS periodicity not supported"); + if (cc->tdd_Config) { // TDD + AssertFatal(isrs >= 10, "2 ms SRS periodicity not supported"); - if ((isrs > 9) && (isrs < 15)) { - *psrsPeriodicity = 5; - *psrsOffset = isrs - 10; - } - if ((isrs > 14) && (isrs < 25)) { - *psrsPeriodicity = 10; - *psrsOffset = isrs - 15; - } - if ((isrs > 24) && (isrs < 45)) { - *psrsPeriodicity = 20; - *psrsOffset = isrs - 25; - } - if ((isrs > 44) && (isrs < 85)) { - *psrsPeriodicity = 40; - *psrsOffset = isrs - 45; - } - if ((isrs > 84) && (isrs < 165)) { - *psrsPeriodicity = 80; - *psrsOffset = isrs - 85; - } - if ((isrs > 164) && (isrs < 325)) { - *psrsPeriodicity = 160; - *psrsOffset = isrs - 165; - } - if ((isrs > 324) && (isrs < 645)) { - *psrsPeriodicity = 320; - *psrsOffset = isrs - 325; - } + if ((isrs > 9) && (isrs < 15)) { + *psrsPeriodicity = 5; + *psrsOffset = isrs - 10; + } + if ((isrs > 14) && (isrs < 25)) { + *psrsPeriodicity = 10; + *psrsOffset = isrs - 15; + } + if ((isrs > 24) && (isrs < 45)) { + *psrsPeriodicity = 20; + *psrsOffset = isrs - 25; + } + if ((isrs > 44) && (isrs < 85)) { + *psrsPeriodicity = 40; + *psrsOffset = isrs - 45; + } + if ((isrs > 84) && (isrs < 165)) { + *psrsPeriodicity = 80; + *psrsOffset = isrs - 85; + } + if ((isrs > 164) && (isrs < 325)) { + *psrsPeriodicity = 160; + *psrsOffset = isrs - 165; + } + if ((isrs > 324) && (isrs < 645)) { + *psrsPeriodicity = 320; + *psrsOffset = isrs - 325; + } - AssertFatal(isrs <= 644, "Isrs out of range %d>644\n", isrs); - } // TDD - else { // FDD - if (isrs < 2) { - *psrsPeriodicity = 2; - *psrsOffset = isrs; - } - if ((isrs > 1) && (isrs < 7)) { - *psrsPeriodicity = 5; - *psrsOffset = isrs - 2; - } - if ((isrs > 6) && (isrs < 17)) { - *psrsPeriodicity = 10; - *psrsOffset = isrs - 7; - } - if ((isrs > 16) && (isrs < 37)) { - *psrsPeriodicity = 20; - *psrsOffset = isrs - 17; - } - if ((isrs > 36) && (isrs < 77)) { - *psrsPeriodicity = 40; - *psrsOffset = isrs - 37; - } - if ((isrs > 76) && (isrs < 157)) { - *psrsPeriodicity = 80; - *psrsOffset = isrs - 77; - } - if ((isrs > 156) && (isrs < 317)) { - *psrsPeriodicity = 160; - *psrsOffset = isrs - 157; - } - if ((isrs > 316) && (isrs < 637)) { - *psrsPeriodicity = 320; - *psrsOffset = isrs - 317; - } - AssertFatal(isrs <= 636, "Isrs out of range %d>636\n", isrs); + AssertFatal(isrs <= 644, "Isrs out of range %d>644\n", isrs); + } // TDD + else { // FDD + if (isrs < 2) { + *psrsPeriodicity = 2; + *psrsOffset = isrs; + } + if ((isrs > 1) && (isrs < 7)) { + *psrsPeriodicity = 5; + *psrsOffset = isrs - 2; + } + if ((isrs > 6) && (isrs < 17)) { + *psrsPeriodicity = 10; + *psrsOffset = isrs - 7; + } + if ((isrs > 16) && (isrs < 37)) { + *psrsPeriodicity = 20; + *psrsOffset = isrs - 17; + } + if ((isrs > 36) && (isrs < 77)) { + *psrsPeriodicity = 40; + *psrsOffset = isrs - 37; + } + if ((isrs > 76) && (isrs < 157)) { + *psrsPeriodicity = 80; + *psrsOffset = isrs - 77; + } + if ((isrs > 156) && (isrs < 317)) { + *psrsPeriodicity = 160; + *psrsOffset = isrs - 157; + } + if ((isrs > 316) && (isrs < 637)) { + *psrsPeriodicity = 320; + *psrsOffset = isrs - 317; } + AssertFatal(isrs <= 636, "Isrs out of range %d>636\n", isrs); + } } void @@ -816,83 +792,83 @@ get_csi_params(COMMON_channels_t * cc, struct CQI_ReportPeriodic *cqi_ReportPeriodic, uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H) { - uint16_t cqi_PMI_ConfigIndex = - cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; - uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; - - AssertFatal(cqi_ReportPeriodic != NULL, - "cqi_ReportPeriodic is null!\n"); - - if (cc->tdd_Config == NULL) { //FDD - if (cqi_PMI_ConfigIndex <= 1) { // 2 ms CQI_PMI period - *Npd = 2; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex; - } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period - *Npd = 5; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 2; - } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period - *Npd = 10; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 7; - } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period - *Npd = 20; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 17; - } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period - *Npd = 40; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 37; - } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period - *Npd = 80; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 77; - } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period - *Npd = 160; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 157; - } else if (cqi_PMI_ConfigIndex > 317) { - - if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period - *Npd = 32; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; - } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period - *Npd = 64; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; - } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period - *Npd = 128; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; - } - } - } else { // TDD - if (cqi_PMI_ConfigIndex == 0) { // all UL subframes - *Npd = 1; - *N_OFFSET_CQI = 0; - } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period - *Npd = 5; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 1; - } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period - *Npd = 10; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 6; - } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period - *Npd = 20; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 16; - } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period - *Npd = 40; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 36; - } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period - *Npd = 80; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 76; - } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period - *Npd = 160; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 156; - } + uint16_t cqi_PMI_ConfigIndex = + cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; + uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; + + AssertFatal(cqi_ReportPeriodic != NULL, + "cqi_ReportPeriodic is null!\n"); + + if (cc->tdd_Config == NULL) { //FDD + if (cqi_PMI_ConfigIndex <= 1) { // 2 ms CQI_PMI period + *Npd = 2; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex; + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + *Npd = 5; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 2; + } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period + *Npd = 10; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 7; + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + *Npd = 20; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 17; + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + *Npd = 40; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 37; + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + *Npd = 80; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 77; + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + *Npd = 160; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 157; + } else if (cqi_PMI_ConfigIndex > 317) { + + if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period + *Npd = 32; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; + } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period + *Npd = 64; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; + } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period + *Npd = 128; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; + } } + } else { // TDD + if (cqi_PMI_ConfigIndex == 0) { // all UL subframes + *Npd = 1; + *N_OFFSET_CQI = 0; + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + *Npd = 5; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 1; + } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period + *Npd = 10; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 6; + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + *Npd = 20; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 16; + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + *Npd = 40; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 36; + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + *Npd = 80; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 76; + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + *Npd = 160; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 156; + } + } - // get H - if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. - present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) - *H = 1 + - (Jtab[cc->mib->message.dl_Bandwidth] * - cqi_ReportPeriodic->choice.setup. - cqi_FormatIndicatorPeriodic.choice.subbandCQI.k); - else - *H = 1; + // get H + if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. + present == + CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) + *H = 1 + + (Jtab[cc->mib->message.dl_Bandwidth] * + cqi_ReportPeriodic->choice.setup. + cqi_FormatIndicatorPeriodic.choice.subbandCQI.k); + else + *H = 1; } uint8_t @@ -901,127 +877,129 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, CQI_ReportModeAperiodic_t * cqi_ReportModeAperiodic) { - int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; - int N = Ntab[cc->mib->message.dl_Bandwidth]; - int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; - int L = Ltab_uesel[cc->mib->message.dl_Bandwidth]; - - AssertFatal(cqi_ReportModeAperiodic != NULL, - "cqi_ReportPeriodic is null!\n"); - - switch (*cqi_ReportModeAperiodic) { - case CQI_ReportModeAperiodic_rm12: - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n", - tmode); - AssertFatal(cc->p_eNB <= 4, - "only up to 4 antenna ports supported here\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + (N << 1)); - else if (ri == 2 && cc->p_eNB == 2) - return (8 + N); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + (N << 2)); - else if (ri > 1 && cc->p_eNB == 4) - return (8 + (N << 2)); - break; - case CQI_ReportModeAperiodic_rm20: - // Table 5.2.2.6.3-1 (36.212) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 - || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n", - tmode); - AssertFatal(tmode != 9 - && tmode != 10, - "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); - return (4 + 2 + L); - break; - case CQI_ReportModeAperiodic_rm22: - // Table 5.2.2.6.3-2 (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n", - tmode); - AssertFatal(tmode != 9 - && tmode != 10, - "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + 2 + 0 + 0 + L + 4); - if (ri == 2 && cc->p_eNB == 2) - return (4 + 2 + 4 + 2 + L + 2); - if (ri == 1 && cc->p_eNB == 4) - return (4 + 2 + 0 + 0 + L + 8); - if (ri >= 2 && cc->p_eNB == 4) - return (4 + 2 + 4 + 2 + L + 8); - break; - case CQI_ReportModeAperiodic_rm30: - // Table 5.2.2.6.2-1 (36.212) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 - || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n", - tmode); - AssertFatal(tmode != 8 && tmode != 9 - && tmode != 10, - "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); - return (4 + (N << 1)); - break; - case CQI_ReportModeAperiodic_rm31: - // Table 5.2.2.6.2-2 (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n", - tmode); - AssertFatal(tmode != 8 && tmode != 9 - && tmode != 10, - "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + (N << 1) + 0 + 0 + 2); - else if (ri == 2 && cc->p_eNB == 2) - return (4 + (N << 1) + 4 + (N << 1) + 1); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + (N << 1) + 0 + 0 + 4); - else if (ri >= 2 && cc->p_eNB == 4) - return (4 + (N << 1) + 4 + (N << 1) + 4); - break; - case CQI_ReportModeAperiodic_rm32_v1250: - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n", - tmode); - AssertFatal(1 == 0, - "CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); - break; - case CQI_ReportModeAperiodic_rm10_v1310: - // Table 5.2.2.6.1-1F/G (36.212) - if (ri == 1) - return (4); // F - else - return (7); // G - break; - case CQI_ReportModeAperiodic_rm11_v1310: - // Table 5.2.2.6.1-1H (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n", - tmode); - AssertFatal(cc->p_eNB <= 4, - "only up to 4 antenna ports supported here\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + 0 + 2); - else if (ri == 2 && cc->p_eNB == 2) - return (4 + 4 + 1); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + 0 + 4); - else if (ri > 1 && cc->p_eNB == 4) - return (4 + 4 + 4); + int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; + int N = Ntab[cc->mib->message.dl_Bandwidth]; + int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; + int L = Ltab_uesel[cc->mib->message.dl_Bandwidth]; + + AssertFatal(cqi_ReportModeAperiodic != NULL, + "cqi_ReportPeriodic is null!\n"); + + switch (*cqi_ReportModeAperiodic) { + case CQI_ReportModeAperiodic_rm12: + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n", + tmode); + AssertFatal(cc->p_eNB <= 4, + "only up to 4 antenna ports supported here\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + (N << 1)); + else if (ri == 2 && cc->p_eNB == 2) + return (8 + N); + else if (ri == 1 && cc->p_eNB == 4) + return (4 + (N << 2)); + else if (ri > 1 && cc->p_eNB == 4) + return (8 + (N << 2)); + break; + case CQI_ReportModeAperiodic_rm20: + // Table 5.2.2.6.3-1 (36.212) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 + || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n", + tmode); + AssertFatal(tmode != 9 + && tmode != 10, + "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); + return (4 + 2 + L); + break; + case CQI_ReportModeAperiodic_rm22: + // Table 5.2.2.6.3-2 (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n", + tmode); + AssertFatal(tmode != 9 + && tmode != 10, + "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + 2 + 0 + 0 + L + 4); + if (ri == 2 && cc->p_eNB == 2) + return (4 + 2 + 4 + 2 + L + 2); + if (ri == 1 && cc->p_eNB == 4) + return (4 + 2 + 0 + 0 + L + 8); + if (ri >= 2 && cc->p_eNB == 4) + return (4 + 2 + 4 + 2 + L + 8); + break; + case CQI_ReportModeAperiodic_rm30: + // Table 5.2.2.6.2-1 (36.212) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 + || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n", + tmode); + AssertFatal(tmode != 8 && tmode != 9 + && tmode != 10, + "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); + return (4 + (N << 1)); + break; + case CQI_ReportModeAperiodic_rm31: + // Table 5.2.2.6.2-2 (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n", + tmode); + AssertFatal(tmode != 8 && tmode != 9 + && tmode != 10, + "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + (N << 1) + 0 + 0 + 2); + else if (ri == 2 && cc->p_eNB == 2) + return (4 + (N << 1) + 4 + (N << 1) + 1); + else if (ri == 1 && cc->p_eNB == 4) + return (4 + (N << 1) + 0 + 0 + 4); + else if (ri >= 2 && cc->p_eNB == 4) + return (4 + (N << 1) + 4 + (N << 1) + 4); + break; +#if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) + case CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n", + tmode); + AssertFatal(1 == 0, + "CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); + break; + case CQI_ReportModeAperiodic_rm10_v1310: + // Table 5.2.2.6.1-1F/G (36.212) + if (ri == 1) + return (4); // F + else + return (7); // G + break; + case CQI_ReportModeAperiodic_rm11_v1310: + // Table 5.2.2.6.1-1H (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n", + tmode); + AssertFatal(cc->p_eNB <= 4, + "only up to 4 antenna ports supported here\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + 0 + 2); + else if (ri == 2 && cc->p_eNB == 2) + return (4 + 4 + 1); + else if (ri == 1 && cc->p_eNB == 4) + return (4 + 0 + 4); + else if (ri > 1 && cc->p_eNB == 4) + return (4 + 4 + 4); - break; - } - AssertFatal(1 == 0, "Shouldn't get here\n"); - return (0); + break; +#endif /* #if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) */ + } + AssertFatal(1 == 0, "Shouldn't get here\n"); + return (0); } uint8_t @@ -1029,550 +1007,444 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, COMMON_channels_t * cc, uint8_t tmode, struct CQI_ReportPeriodic * cqi_ReportPeriodic) { - int no_pmi = 0; - // Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)}; - - uint8_t Ltab[6] = { 0, 1, 2, 2, 2, 2 }; - uint8_t ri = sched_ctl->periodic_ri_received[CC_idP]; - - AssertFatal(cqi_ReportPeriodic != NULL, - "cqi_ReportPeriodic is null!\n"); - AssertFatal(cqi_ReportPeriodic->present != - CQI_ReportPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); - AssertFatal(cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present != - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); - - switch (tmode) { - case 1: - case 2: - case 5: - case 6: - case 7: - no_pmi = 1; - break; - default: - no_pmi = 0; - } - - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. - present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) - || (sched_ctl->feedback_cnt[CC_idP] == 0)) { - // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities - if (no_pmi == 1) - return (4); - else if ((cc->p_eNB == 2) && (ri == 1)) - return (6); - else if ((cc->p_eNB == 2) && (ri == 2)) - return (8); - else if ((cc->p_eNB == 4) && (ri == 1)) - return (8); - else if ((cc->p_eNB == 4) && (ri == 2)) - return (11); - else - AssertFatal(1 == 0, - "illegal combination p %d, ri %d, no_pmi %d\n", - cc->p_eNB, ri, no_pmi); - } else if (cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) - { - if ((no_pmi == 1) || ri == 1) - return (4 + Ltab[cc->mib->message.dl_Bandwidth]); - else - return (7 + Ltab[cc->mib->message.dl_Bandwidth]); - } + int no_pmi = 0; + // Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)}; - AssertFatal(1 == 0, - "Shouldn't get here : cqi_ReportPeriodic->present %d\n", - cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present); -} + uint8_t Ltab[6] = { 0, 1, 2, 2, 2, 2 }; + uint8_t ri = sched_ctl->periodic_ri_received[CC_idP]; -void -fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t * dl_config_pdu, - uint8_t aggregation_level, - uint16_t rnti, - uint8_t rnti_type, - uint8_t harq_process, - uint8_t tpc, - uint16_t resource_block_coding, - uint8_t mcs, uint8_t ndi, uint8_t rv, - uint8_t vrb_flag) -{ - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = - NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - aggregation_level; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rnti_type; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_process; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = - resource_block_coding; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = vrb_flag; -} + AssertFatal(cqi_ReportPeriodic != NULL, + "cqi_ReportPeriodic is null!\n"); + AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice. + setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + + switch (tmode) { + case 1: + case 2: + case 5: + case 6: + case 7: + no_pmi = 1; + break; + default: + no_pmi = 0; + } + + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) + || (sched_ctl->feedback_cnt[CC_idP] == 0)) { + // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities + if (no_pmi == 1) return (4); + else if ((cc->p_eNB == 2) && (ri == 1)) return (6); + else if ((cc->p_eNB == 2) && (ri == 2)) return (8); + else if ((cc->p_eNB == 4) && (ri == 1)) return (8); + else if ((cc->p_eNB == 4) && (ri == 2)) return (11); + else + AssertFatal(1 == 0, + "illegal combination p %d, ri %d, no_pmi %d\n", + cc->p_eNB, ri, no_pmi); + } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { + if ((no_pmi == 1) || ri == 1) return (4 + Ltab[cc->mib->message.dl_Bandwidth]); + else return (7 + Ltab[cc->mib->message.dl_Bandwidth]); + } + + AssertFatal(1 == 0, + "Shouldn't get here : cqi_ReportPeriodic->present %d\n", + cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present); +} + + + +void +fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t aggregation_level, + uint16_t rnti, + uint8_t rnti_type, + uint8_t harq_process, + uint8_t tpc, + uint16_t resource_block_coding, + uint8_t mcs, + uint8_t ndi, + uint8_t rv, + uint8_t vrb_flag) +{ + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation_level; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rnti_type; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_process; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = vrb_flag; +} void program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, frame_t frameP, sub_frame_t subframeP, uint8_t cce_idx) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list = &eNB->UE_list; - rnti_t rnti = UE_RNTI(module_idP, UE_idP); - nfapi_ul_config_request_body_t *ul_req; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - - int use_simultaneous_pucch_pusch = 0; - nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL; - nfapi_ul_config_harq_information *harq_information = NULL; - -#if defined(Rel10) || defined(Rel14) - - if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated-> - ext2) - && (UE_list->UE_template[CC_idP][UE_idP]. - physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) - && (UE_list->UE_template[CC_idP][UE_idP]. - physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020-> - simultaneousPUCCH_PUSCH_r10) - && (*UE_list->UE_template[CC_idP][UE_idP]. - physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020-> - simultaneousPUCCH_PUSCH_r10 == - PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) - use_simultaneous_pucch_pusch = 1; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + rnti_t rnti = UE_RNTI(module_idP, UE_idP); + nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + int use_simultaneous_pucch_pusch = 0; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL; + nfapi_ul_config_harq_information *harq_information = NULL; + +#if (RRC_VERSION >= MAKE_VERSION(10, 2, 0)) + + if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2) + && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) + && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10) + && (*UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) + use_simultaneous_pucch_pusch = 1; #endif - // pucch1 and pusch feedback is similar, namely in n+k subframes from now - // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k - int16_t ul_absSF = - get_pucch1_absSF(&cc[CC_idP], subframeP + (10 * frameP)); - - if ((ul_config_pdu = has_ul_grant(module_idP, CC_idP, - ul_absSF, rnti)) == NULL) { - // no UL grant so - // Program ACK/NAK alone Format 1a/b or 3 - - ul_req = - &RC.mac[module_idP]->UL_req_tmp[CC_idP][ul_absSF % - 10]. - ul_config_request_body; - ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - // Do PUCCH - fill_nfapi_uci_acknak(module_idP, - CC_idP, - rnti, (frameP * 10) + subframeP, cce_idx); - } else { - /* there is already an existing UL grant so update it if needed - * on top of some other UL resource (PUSCH,combined SR/CQI/HARQ on PUCCH, etc) - */ - switch (ul_config_pdu->pdu_type) { - - /* [ulsch] to [ulsch + harq] or [ulsch + harq on pucch] */ - - case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: - if (use_simultaneous_pucch_pusch == 1) { - // Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE - harq_information = - &ul_config_pdu->ulsch_uci_harq_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; - LOG_D(MAC, - "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n", - frameP, subframeP); - } else { - // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE - ulsch_harq_information = - &ul_config_pdu->ulsch_harq_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet - LOG_D(MAC, - "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n", - frameP, subframeP); - } - break; - case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 1, - "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active"); - break; - case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 0, - "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); - break; - - /* [ulsch + cqi] to [ulsch + cqi + harq] */ - - case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: - // Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE - ulsch_harq_information = - &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - /* TODO: check this - when converting from nfapi_ul_config_ulsch_cqi_ri_pdu to - * nfapi_ul_config_ulsch_cqi_harq_ri_pdu, shouldn't we copy initial_transmission_parameters - * from the one to the other? - * Those two types are not compatible. 'initial_transmission_parameters' is not at the - * place in both. - */ - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet - break; - case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 0, - "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE, simultaneous_pucch_pusch is active\n"); - break; - - /* [ulsch + cqi on pucch] to [ulsch + cqi on pucch + harq on pucch] */ - - case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: - // convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE - harq_information = - &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; - break; - case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 1, - "Cannot be NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); - break; - - /* [sr] to [sr + harq] */ - - case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - harq_information = - &ul_config_pdu->uci_sr_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: - /* nothing to do */ - break; - - /* [cqi] to [cqi + harq] */ - - case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; - harq_information = - &ul_config_pdu->uci_cqi_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: - /* nothing to do */ - break; - - /* [cqi + sr] to [cqr + sr + harq] */ - - case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; - harq_information = - &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: - /* nothing to do */ - break; - } + // pucch1 and pusch feedback is similar, namely in n+k subframes from now + // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k + int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP], subframeP + (10 * frameP)); + + if ((ul_config_pdu = has_ul_grant(module_idP, CC_idP,ul_absSF, rnti)) == NULL) { + // no UL grant so + // Program ACK/NAK alone Format 1a/b or 3 + + ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][ul_absSF %10].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + // Do PUCCH + fill_nfapi_uci_acknak(module_idP, + CC_idP, + rnti, (frameP * 10) + subframeP, cce_idx); + } else { + /* there is already an existing UL grant so update it if needed + * on top of some other UL resource (PUSCH,combined SR/CQI/HARQ on PUCCH, etc) + */ + switch (ul_config_pdu->pdu_type) { + + /* [ulsch] to [ulsch + harq] or [ulsch + harq on pucch] */ + + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + if (use_simultaneous_pucch_pusch == 1) { + // Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; + LOG_D(MAC, + "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n", + frameP, subframeP); + } else { + // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + LOG_D(MAC, + "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n", + frameP, subframeP); + } + break; + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 1, + "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active"); + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 0, + "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + break; + + /* [ulsch + cqi] to [ulsch + cqi + harq] */ + + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + // Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + /* TODO: check this - when converting from nfapi_ul_config_ulsch_cqi_ri_pdu to + * nfapi_ul_config_ulsch_cqi_harq_ri_pdu, shouldn't we copy initial_transmission_parameters + * from the one to the other? + * Those two types are not compatible. 'initial_transmission_parameters' is not at the + * place in both. + */ + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 0, + "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE, simultaneous_pucch_pusch is active\n"); + break; + + /* [ulsch + cqi on pucch] to [ulsch + cqi on pucch + harq on pucch] */ + + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + // convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; + break; + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 1, + "Cannot be NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + break; + + /* [sr] to [sr + harq] */ + + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; + break; + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + /* nothing to do */ + break; + /* [cqi] to [cqi + harq] */ + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_harq_pdu.harq_information; + break; + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + /* nothing to do */ + break; + /* [cqi + sr] to [cqr + sr + harq] */ + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information; + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + /* nothing to do */ + break; } + } - if (ulsch_harq_information) - fill_nfapi_ulsch_harq_information(module_idP, CC_idP, - rnti, ulsch_harq_information,subframeP); + if (ulsch_harq_information) fill_nfapi_ulsch_harq_information(module_idP, CC_idP, rnti, ulsch_harq_information, subframeP); - if (harq_information) - fill_nfapi_harq_information(module_idP, CC_idP, - rnti, - (frameP * 10) + subframeP, - harq_information, cce_idx); + if (harq_information) fill_nfapi_harq_information(module_idP, CC_idP, + rnti, + (frameP * 10) + subframeP, + harq_information, cce_idx); } uint8_t get_V_UL_DAI(module_id_t module_idP, int CC_idP, uint16_t rntiP,sub_frame_t subframeP) { - nfapi_hi_dci0_request_body_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_pdu_list[0]; - - for (int i = 0; i < HI_DCI0_req->number_of_dci; i++) { - if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - return (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8. - dl_assignment_index); - } - return (4); // this is rule from Section 7.3 in 36.213 + nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[0]; + + for (int i = 0; i < HI_DCI0_req->number_of_dci; i++) { + if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + return (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index); + } + return (4); // this is rule from Section 7.3 in 36.213 } void -fill_nfapi_ulsch_harq_information(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - nfapi_ul_config_ulsch_harq_information - * harq_information, - sub_frame_t subframeP) +fill_nfapi_ulsch_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + nfapi_ul_config_ulsch_harq_information *harq_information, + sub_frame_t subframeP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - UE_list_t *UE_list = &eNB->UE_list; - - int UE_id = find_UE_id(module_idP, rntiP); - - PUSCH_ConfigDedicated_t *puschConfigDedicated; - // PUSCH_ConfigDedicated_v1020_t *puschConfigDedicated_v1020; - // PUSCH_ConfigDedicated_v1130_t *puschConfigDedicated_v1130; - // PUSCH_ConfigDedicated_v1250_t *puschConfigDedicated_v1250; - - AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); - AssertFatal(UE_list != NULL, "UE_list is null\n"); - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated for rnti %x is null\n", rntiP); - AssertFatal((puschConfigDedicated = (PUSCH_ConfigDedicated_t *) - UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated->pusch_ConfigDedicated) != NULL, - "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n", - rntiP); -#if defined(Rel14) || defined(Rel14) - /* if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020; - #endif - #ifdef Rel14 - if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4) puschConfigDedicated_v1130 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4->pusch_ConfigDedicated_v1130; - if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5) puschConfigDedicated_v1250 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5->pusch_ConfigDedicated_v1250; - */ + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + UE_list_t *UE_list = &eNB->UE_list; + + int UE_id = find_UE_id(module_idP, rntiP); + + PUSCH_ConfigDedicated_t *puschConfigDedicated; + // PUSCH_ConfigDedicated_v1020_t *puschConfigDedicated_v1020; + // PUSCH_ConfigDedicated_v1130_t *puschConfigDedicated_v1130; + // PUSCH_ConfigDedicated_v1250_t *puschConfigDedicated_v1250; + + AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); + AssertFatal(UE_list != NULL, "UE_list is null\n"); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated for rnti %x is null\n", rntiP); + AssertFatal((puschConfigDedicated = (PUSCH_ConfigDedicated_t *) + UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pusch_ConfigDedicated) != NULL, + "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n", + rntiP); +#if (RRC_VERSION >= MAKE_VERSION(10, 2, 0)) + /* if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020; + #endif + #if (RRC_VERSION >= MAKE_VERSION(11, 3, 0)) + if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4) puschConfigDedicated_v1130 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4->pusch_ConfigDedicated_v1130; + #endif + #if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) + if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5) puschConfigDedicated_v1250 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5->pusch_ConfigDedicated_v1250; + #endif + */ #endif - harq_information->harq_information_rel10.delta_offset_harq = - puschConfigDedicated->betaOffset_ACK_Index; - AssertFatal(UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated != NULL, - "pucch_ConfigDedicated is null!\n"); - if ((UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated->pucch_ConfigDedicated-> - tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated->pucch_ConfigDedicated-> - tdd_AckNackFeedbackMode == - PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - harq_information->harq_information_rel10.ack_nack_mode = 1; // multiplexing - else - harq_information->harq_information_rel10.ack_nack_mode = 0; // bundling - - switch (get_tmode(module_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 5: - case 6: - case 7: - if (cc->tdd_Config == NULL) // FDD - harq_information->harq_information_rel10.harq_size = 1; - else { - if (harq_information->harq_information_rel10.ack_nack_mode == - 1) - harq_information->harq_information_rel10.harq_size = - get_V_UL_DAI(module_idP, CC_idP, rntiP,subframeP); - else - harq_information->harq_information_rel10.harq_size = 1; - } - break; - default: // for any other TM we need 2 bits harq - if (cc->tdd_Config == NULL) { - harq_information->harq_information_rel10.harq_size = 2; - } else { - if (harq_information->harq_information_rel10.ack_nack_mode == - 1) - harq_information->harq_information_rel10.harq_size = - get_V_UL_DAI(module_idP, CC_idP, rntiP,subframeP); - else - harq_information->harq_information_rel10.harq_size = 2; - } - break; - } // get Tmode + harq_information->harq_information_rel10.delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index; + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, + "pucch_ConfigDedicated is null!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) + harq_information->harq_information_rel10.ack_nack_mode = 1; // multiplexing + else + harq_information->harq_information_rel10.ack_nack_mode = 0; // bundling + + switch (get_tmode(module_idP, CC_idP, UE_id)) { + case 1: + case 2: + case 5: + case 6: + case 7: + if (cc->tdd_Config == NULL) // FDD + harq_information->harq_information_rel10.harq_size = 1; + else { + if (harq_information->harq_information_rel10.ack_nack_mode == 1) + harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP, subframeP); + else + harq_information->harq_information_rel10.harq_size = 1; + } + break; + default: // for any other TM we need 2 bits harq + if (cc->tdd_Config == NULL) { + harq_information->harq_information_rel10.harq_size = 2; + } else { + if (harq_information->harq_information_rel10.ack_nack_mode == 1) + harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP, subframeP); + else + harq_information->harq_information_rel10.harq_size = 2; + } + break; + } // get Tmode } void -fill_nfapi_harq_information(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - uint16_t absSFP, - nfapi_ul_config_harq_information * - harq_information, uint8_t cce_idxP) +fill_nfapi_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + nfapi_ul_config_harq_information *harq_information, + uint8_t cce_idxP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - UE_list_t *UE_list = &eNB->UE_list; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + UE_list_t *UE_list = &eNB->UE_list; - int UE_id = find_UE_id(module_idP, rntiP); + int UE_id = find_UE_id(module_idP, rntiP); - AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); - AssertFatal(UE_list != NULL, "UE_list is null\n"); + AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); + AssertFatal(UE_list != NULL, "UE_list is null\n"); #if 0 - /* TODO: revisit, don't use Assert, it's perfectly possible to - * have physicalConfigDedicated NULL here - */ - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated for rnti %x is null\n", rntiP); + /* TODO: revisit, don't use Assert, it's perfectly possible to + * have physicalConfigDedicated NULL here + */ + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated for rnti %x is null\n", rntiP); #endif - harq_information->harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; - harq_information->harq_information_rel11.num_ant_ports = 1; + harq_information->harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; + harq_information->harq_information_rel11.num_ant_ports = 1; - switch (get_tmode(module_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 5: - case 6: - case 7: - if (cc->tdd_Config != NULL) { -// AssertFatal(UE_list-> -// UE_template[CC_idP] -// [UE_id].physicalConfigDedicated-> -// pucch_ConfigDedicated != NULL, -// "pucch_ConfigDedicated is null for TDD!\n"); - if (UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL){ - if ((UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated != NULL) - && (UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode == - PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - { - harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK - harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing - } else { - harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK - harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling - } - } else { - harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK - harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling - } - harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; - LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[module_idP][CC_idP]->frame_parms; - harq_information->harq_information_rel10_tdd.n_pucch_1_0 = get_Np(frame_parms->N_RB_DL,cce_idxP,0) + - cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; - harq_information-> - harq_information_rel10_tdd.number_of_pucch_resources = 1; - } else { - harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; - harq_information-> - harq_information_rel9_fdd.number_of_pucch_resources = 1; - harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK - harq_information->harq_information_rel9_fdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon. - n1PUCCH_AN + cce_idxP; - } - break; - default: // for any other TM we need 2 bits harq - if (cc->tdd_Config != NULL) { - AssertFatal(UE_list-> - UE_template[CC_idP] - [UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated != NULL, - "pucch_ConfigDedicated is null for TDD!\n"); - if ((UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode == - PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - { - harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing - } else { - harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling - } - harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; - harq_information->harq_information_rel10_tdd.harq_size = 2; - harq_information->harq_information_rel10_tdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon. - n1PUCCH_AN + cce_idxP; - harq_information-> - harq_information_rel10_tdd.number_of_pucch_resources = 1; - } else { - harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; - harq_information-> - harq_information_rel9_fdd.number_of_pucch_resources = 1; - harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b - harq_information->harq_information_rel9_fdd.harq_size = 2; - harq_information->harq_information_rel9_fdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon. - n1PUCCH_AN + cce_idxP; - } - break; - } // get Tmode + switch (get_tmode(module_idP, CC_idP, UE_id)) { + case 1: + case 2: + case 5: + case 6: + case 7: + if (cc->tdd_Config != NULL) { +// AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, +// "pucch_ConfigDedicated is null for TDD!\n"); + if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL + && UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL + && (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) + { + harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + } else { + harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[module_idP][CC_idP]->frame_parms; + harq_information->harq_information_rel10_tdd.n_pucch_1_0 = get_Np(frame_parms->N_RB_DL,cce_idxP,0) + + cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; + } else { + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + } + break; + default: // for any other TM we need 2 bits harq + if (cc->tdd_Config != NULL) { + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, + "pucch_ConfigDedicated is null for TDD!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + } else { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + harq_information->harq_information_rel10_tdd.harq_size = 2; + harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; + } else { + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b + harq_information->harq_information_rel9_fdd.harq_size = 2; + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + } + break; + } // get Tmode } uint16_t fill_nfapi_uci_acknak(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, uint16_t absSFP, uint8_t cce_idxP) + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + uint8_t cce_idxP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - - int ackNAK_absSF = get_pucch1_absSF(cc, absSFP); - nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; - nfapi_ul_config_request_body_t *ul_req_body = &ul_req->ul_config_request_body; - nfapi_ul_config_request_pdu_t *ul_config_pdu = - &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = - rntiP; - - fill_nfapi_harq_information(module_idP, CC_idP, - rntiP, - absSFP, - &ul_config_pdu->uci_harq_pdu. - harq_information, cce_idxP); - LOG_D(MAC, - "Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n", - rntiP, absSFP / 10, absSFP % 10, ackNAK_absSF / 10, - ackNAK_absSF % 10, cce_idxP, - ul_config_pdu->uci_harq_pdu. - harq_information.harq_information_rel9_fdd.n_pucch_1_0); - - ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req->sfn_sf = (ackNAK_absSF/10) << 4 | ackNAK_absSF%10; - - return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + int ackNAK_absSF = get_pucch1_absSF(cc, absSFP); + nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; + nfapi_ul_config_request_body_t *ul_req_body = &ul_req->ul_config_request_body; + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rntiP; + + fill_nfapi_harq_information(module_idP, CC_idP, + rntiP, + absSFP, + &ul_config_pdu->uci_harq_pdu.harq_information, cce_idxP); + LOG_D(MAC, + "Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n", + rntiP, absSFP / 10, absSFP % 10, ackNAK_absSF / 10, + ackNAK_absSF % 10, cce_idxP, + ul_config_pdu->uci_harq_pdu. + harq_information.harq_information_rel9_fdd.n_pucch_1_0); + + ul_req_body->number_of_pdus++; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->sfn_sf = (ackNAK_absSF/10) << 4 | ackNAK_absSF%10; + + return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); } void @@ -1602,197 +1474,137 @@ fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, uint8_t num_bf_prb_per_subband, uint8_t num_bf_vector) { - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = - resource_allocation_type; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.virtual_resource_block_assignment_flag = - virtual_resource_block_assignment_flag; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = - resource_block_coding; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = - redundancy_version; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = - transport_blocks; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - transport_block_to_codeword_swap_flag; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = - transmission_scheme; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - number_of_layers; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = - number_of_subbands; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = - ue_category_capacity; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = - delta_power_offset_index; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - transmission_mode; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = - num_bf_prb_per_subband; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; - dl_req->number_pdu++; + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_req->number_pdu++; } uint16_t -fill_nfapi_tx_req(nfapi_tx_request_body_t * tx_req_body, - uint16_t absSF, uint16_t pdu_length, - int16_t pdu_index, uint8_t * pdu) +fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body, + uint16_t absSF, + uint16_t pdu_length, + int16_t pdu_index, + uint8_t *pdu) { - nfapi_tx_request_pdu_t *TX_req = - &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; - LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", - tx_req_body->number_of_pdus, pdu_length); - TX_req->pdu_length = pdu_length; - TX_req->pdu_index = pdu_index; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = pdu_length; - TX_req->segments[0].segment_data = pdu; - tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - tx_req_body->number_of_pdus++; - - return (((absSF / 10) << 4) + (absSF % 10)); + nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; + LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", + tx_req_body->number_of_pdus, pdu_length); + + TX_req->pdu_length = pdu_length; + TX_req->pdu_index = pdu_index; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pdu_length; + TX_req->segments[0].segment_data = pdu; + tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req_body->number_of_pdus++; + + return (((absSF / 10) << 4) + (absSF % 10)); } void -fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t * - ul_config_pdu, uint8_t cqi_req, - COMMON_channels_t * cc, - struct PhysicalConfigDedicated - *physicalConfigDedicated, - uint8_t tmode, uint32_t handle, - uint16_t rnti, - uint8_t resource_block_start, - uint8_t - number_of_resource_blocks, - uint8_t mcs, - uint8_t cyclic_shift_2_for_drms, - uint8_t - frequency_hopping_enabled_flag, - uint8_t frequency_hopping_bits, - uint8_t new_data_indication, - uint8_t redundancy_version, - uint8_t harq_process_number, - uint8_t ul_tx_mode, - uint8_t current_tx_nb, - uint8_t n_srs, uint16_t size) +fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint8_t cqi_req, + COMMON_channels_t *cc, + struct PhysicalConfigDedicated *physicalConfigDedicated, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t mcs, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) { - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = - resource_block_start; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = - number_of_resource_blocks; - if (mcs < 11) - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - else if (mcs < 21) - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 4; - else if(mcs < 29) - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 6; - else - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = - cyclic_shift_2_for_drms; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8. - frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = - frequency_hopping_bits; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = - new_data_indication; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = - redundancy_version; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = - harq_process_number; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = ul_tx_mode; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = current_tx_nb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = n_srs; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = size; - - if (cqi_req == 1) { - // Add CQI portion - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.report_type = 1; - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.number_of_cc = 1; - LOG_D(MAC, "report_type %d\n", - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.report_type); - - if (cc->p_eNB <= 2 - && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 - || tmode == 10)) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; - else if (cc->p_eNB <= 2) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; - else if (cc->p_eNB == 4) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; - - AssertFatal(physicalConfigDedicated->cqi_ReportConfig != NULL, - "physicalConfigDedicated->cqi_ReportConfig is null!\n"); - AssertFatal(physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportModeAperiodic != NULL, - "physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n"); - AssertFatal(physicalConfigDedicated->pusch_ConfigDedicated != NULL, - "physicalConfigDedicated->puschConfigDedicated is null!\n"); - - for (int ri = 0; - ri < - (1 << ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size); ri++) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = - get_dl_cqi_pmi_size_pusch(cc, tmode, 1 + ri, - physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); - - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = - physicalConfigDedicated->pusch_ConfigDedicated-> - betaOffset_CQI_Index; - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = - physicalConfigDedicated->pusch_ConfigDedicated-> - betaOffset_RI_Index; - } + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = resource_block_start; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = number_of_resource_blocks; + if (mcs < 11) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + else if (mcs < 21) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 4; + else if(mcs < 29) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 6; + else ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = cyclic_shift_2_for_drms; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = frequency_hopping_bits; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = new_data_indication; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = redundancy_version; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = harq_process_number; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = ul_tx_mode; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = current_tx_nb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = n_srs; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = size; + + if (cqi_req == 1) { + // Add CQI portion + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type = 1; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); + + if (cc->p_eNB <= 2 + && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; + else if (cc->p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; + else if (cc->p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; + + AssertFatal(physicalConfigDedicated->cqi_ReportConfig != NULL,"physicalConfigDedicated->cqi_ReportConfig is null!\n"); + AssertFatal(physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic != NULL,"physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n"); + AssertFatal(physicalConfigDedicated->pusch_ConfigDedicated != NULL,"physicalConfigDedicated->puschConfigDedicated is null!\n"); + + for (int ri = 0; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + ri++) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = get_dl_cqi_pmi_size_pusch(cc,tmode,1 + ri,physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); + + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; + } } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * ul_config_pdu, uint8_t ue_type, @@ -1801,34 +1613,29 @@ fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * uint16_t repetition_number, uint16_t initial_transmission_sf_io) { - // Re13 fields - - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ue_type; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = - total_number_of_repetitions; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = - repetition_number; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = - initial_transmission_sf_io; + // Re13 fields + + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ue_type; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = total_number_of_repetitions; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = repetition_number; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = initial_transmission_sf_io; } int get_numnarrowbands(long dl_Bandwidth) { - int nb_tab[6] = { 1, 2, 4, 8, 12, 16 }; + int nb_tab[6] = { 1, 2, 4, 8, 12, 16 }; - AssertFatal(dl_Bandwidth < 7 - || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); - return (nb_tab[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 7 || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); + return (nb_tab[dl_Bandwidth]); } int get_numnarrowbandbits(long dl_Bandwidth) { - int nbbits_tab[6] = { 0, 1, 2, 3, 4, 4 }; + int nbbits_tab[6] = { 0, 1, 2, 3, 4, 4 }; - AssertFatal(dl_Bandwidth < 7 - || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); - return (nbbits_tab[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 7 || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); + return (nbbits_tab[dl_Bandwidth]); } //This implements the frame/subframe condition for first subframe of MPDCCH transmission (Section 9.1.5 36.213, Rel 13/14) @@ -1840,111 +1647,96 @@ mpdcch_sf_condition(eNB_MAC_INST * eNB, int CC_id, frame_t frameP, sub_frame_t subframeP, int rmax, MPDCCH_TYPES_t mpdcch_type, int UE_id) { - struct PRACH_ConfigSIB_v1310 *ext4_prach = - eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> - ext4->prach_ConfigCommon_v1310; + struct PRACH_ConfigSIB_v1310 *ext4_prach = + eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> + ext4->prach_ConfigCommon_v1310; - int T; - EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; + int T; + EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; - switch (mpdcch_type) { - case TYPE0: - AssertFatal(1 == 0, "MPDCCH Type 0 not handled yet\n"); - break; - case TYPE1: - AssertFatal(1 == 0, "MPDCCH Type 1 not handled yet\n"); - break; - case TYPE1A: - AssertFatal(1 == 0, "MPDCCH Type 1A not handled yet\n"); - break; - case TYPE2: // RAR - AssertFatal(ext4_prach->mpdcch_startSF_CSS_RA_r13 != NULL, - "mpdcch_startSF_CSS_RA_r13 is null\n"); - AssertFatal(rmax > 0, "rmax is 0!\b"); - if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD - T = rmax * - startSF_fdd_RA_times2[ext4_prach-> + switch (mpdcch_type) { + case TYPE0: + AssertFatal(1 == 0, "MPDCCH Type 0 not handled yet\n"); + break; + case TYPE1: + AssertFatal(1 == 0, "MPDCCH Type 1 not handled yet\n"); + break; + case TYPE1A: + AssertFatal(1 == 0, "MPDCCH Type 1A not handled yet\n"); + break; + case TYPE2: // RAR + AssertFatal(ext4_prach->mpdcch_startSF_CSS_RA_r13 != NULL, + "mpdcch_startSF_CSS_RA_r13 is null\n"); + AssertFatal(rmax > 0, "rmax is 0!\b"); + if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD + T = rmax *startSF_fdd_RA_times2[ext4_prach-> mpdcch_startSF_CSS_RA_r13-> choice.fdd_r13] >> 1; - else //TDD - T = rmax * - startSF_tdd_RA[ext4_prach-> + else //TDD + T = rmax *startSF_tdd_RA[ext4_prach-> mpdcch_startSF_CSS_RA_r13->choice.tdd_r13]; - break; - case TYPE2A: - AssertFatal(1 == 0, "MPDCCH Type 2A not handled yet\n"); - break; - case TYPEUESPEC: - epdcch_setconfig_r11 = - eNB->UE_list.UE_template[CC_id][UE_id]. - physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11. - choice.setup.setConfigToAddModList_r11->list.array[0]; - - AssertFatal(epdcch_setconfig_r11 != NULL, - " epdcch_setconfig_r11 is null for UE specific \n"); - AssertFatal(epdcch_setconfig_r11->ext2 != NULL, - " ext2 doesn't exist in epdcch config ' \n"); - - if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD - T = rmax * - startSF_fdd_RA_times2[epdcch_setconfig_r11-> - ext2->mpdcch_config_r13->choice. - setup.mpdcch_StartSF_UESS_r13.choice. - fdd_r13] >> 1; - else //TDD - T = rmax * - startSF_tdd_RA[epdcch_setconfig_r11-> - ext2->mpdcch_config_r13->choice. - setup.mpdcch_StartSF_UESS_r13.choice. - tdd_r13]; - - break; - default: - return (0); - } + break; + case TYPE2A: + AssertFatal(1 == 0, "MPDCCH Type 2A not handled yet\n"); + break; + case TYPEUESPEC: + epdcch_setconfig_r11 = + eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + + AssertFatal(epdcch_setconfig_r11 != NULL, + " epdcch_setconfig_r11 is null for UE specific \n"); + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, + " ext2 doesn't exist in epdcch config ' \n"); + + if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD + T = rmax *startSF_fdd_RA_times2[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.fdd_r13] >> 1; + else //TDD + T = rmax *startSF_tdd_RA[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.tdd_r13]; + break; + default: + return (0); + } - AssertFatal(T > 0, "T is 0!\n"); - if (((10 * frameP) + subframeP) % T == 0) - return (1); - else - return (0); + AssertFatal(T > 0, "T is 0!\n"); + if (((10 * frameP) + subframeP) % T == 0) return (1); + else return (0); } int narrowband_to_first_rb(COMMON_channels_t * cc, int nb_index) { - switch (cc->mib->message.dl_Bandwidth) { - case 0: // 6 PRBs, N_NB=1, i_0=0 - return (0); - break; - case 3: // 50 PRBs, N_NB=8, i_0=1 - return ((int) (1 + (6 * nb_index))); - break; - case 5: // 100 PRBs, N_NB=16, i_0=2 - return ((int) (2 + (6 * nb_index))); - break; - case 1: // 15 PRBs N_NB=2, i_0=1 - if (nb_index > 0) - return (1); - else - return (0); - break; - case 2: // 25 PRBs, N_NB=4, i_0=0 - if (nb_index > 1) - return (1 + (6 * nb_index)); - else - return ((6 * nb_index)); - break; - case 4: // 75 PRBs, N_NB=12, i_0=1 - if (nb_index > 5) - return (2 + (6 * nb_index)); - else - return (1 + (6 * nb_index)); - break; - default: - AssertFatal(1 == 0, "Impossible dl_Bandwidth %d\n", - (int) cc->mib->message.dl_Bandwidth); - break; - } + switch (cc->mib->message.dl_Bandwidth) { + case 0: // 6 PRBs, N_NB=1, i_0=0 + return (0); + break; + case 3: // 50 PRBs, N_NB=8, i_0=1 + return ((int) (1 + (6 * nb_index))); + break; + case 5: // 100 PRBs, N_NB=16, i_0=2 + return ((int) (2 + (6 * nb_index))); + break; + case 1: // 15 PRBs N_NB=2, i_0=1 + if (nb_index > 0) + return (1); + else + return (0); + break; + case 2: // 25 PRBs, N_NB=4, i_0=0 + if (nb_index > 1) + return (1 + (6 * nb_index)); + else + return ((6 * nb_index)); + break; + case 4: // 75 PRBs, N_NB=12, i_0=1 + if (nb_index > 5) + return (2 + (6 * nb_index)); + else + return (1 + (6 * nb_index)); + break; + default: + AssertFatal(1 == 0, "Impossible dl_Bandwidth %d\n", + (int) cc->mib->message.dl_Bandwidth); + break; + } } #endif @@ -1952,23 +1744,23 @@ int narrowband_to_first_rb(COMMON_channels_t * cc, int nb_index) void init_ue_sched_info(void) //------------------------------------------------------------------------------ { - module_id_t i, j, k; - - for (i = 0; i < NUMBER_OF_eNB_MAX; i++) { - for (k = 0; k < MAX_NUM_CCs; k++) { - for (j = 0; j < NUMBER_OF_UE_MAX; j++) { - // init DL - eNB_dlsch_info[i][k][j].weight = 0; - eNB_dlsch_info[i][k][j].subframe = 0; - eNB_dlsch_info[i][k][j].serving_num = 0; - eNB_dlsch_info[i][k][j].status = S_DL_NONE; - // init UL - eNB_ulsch_info[i][k][j].subframe = 0; - eNB_ulsch_info[i][k][j].serving_num = 0; - eNB_ulsch_info[i][k][j].status = S_UL_NONE; - } - } + module_id_t i, j, k; + + for (i = 0; i < NUMBER_OF_eNB_MAX; i++) { + for (k = 0; k < MAX_NUM_CCs; k++) { + for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { + // init DL + eNB_dlsch_info[i][k][j].weight = 0; + eNB_dlsch_info[i][k][j].subframe = 0; + eNB_dlsch_info[i][k][j].serving_num = 0; + eNB_dlsch_info[i][k][j].status = S_DL_NONE; + // init UL + eNB_ulsch_info[i][k][j].subframe = 0; + eNB_ulsch_info[i][k][j].serving_num = 0; + eNB_ulsch_info[i][k][j].status = S_UL_NONE; + } } + } } @@ -1977,958 +1769,822 @@ void init_ue_sched_info(void) unsigned char get_ue_weight(module_id_t module_idP, int CC_idP, int ue_idP) //------------------------------------------------------------------------------ { - return (eNB_dlsch_info[module_idP][CC_idP][ue_idP].weight); + return (eNB_dlsch_info[module_idP][CC_idP][ue_idP].weight); } //------------------------------------------------------------------------------ int find_UE_id(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { - int UE_id; - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - if (UE_list->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == - rntiP) { - return (UE_id); - } + int UE_id; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (UE_list->active[UE_id] != TRUE) + continue; + if (UE_list->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == + rntiP) { + return (UE_id); } + } - return (-1); + return (-1); } //------------------------------------------------------------------------------ int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { - int RA_id; - AssertFatal(RC.mac[mod_idP], "RC.mac[%d] is null\n", mod_idP); + int RA_id; + AssertFatal(RC.mac[mod_idP], "RC.mac[%d] is null\n", mod_idP); - RA_t *ra = (RA_t *) & RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; + RA_t *ra = (RA_t *) & RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; - for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { - LOG_D(MAC, - "Checking RA_id %d for %x : state %d\n", - RA_id, rntiP, ra[RA_id].state); + for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { + LOG_D(MAC, + "Checking RA_id %d for %x : state %d\n", + RA_id, rntiP, ra[RA_id].state); - if (ra[RA_id].state != IDLE && - ra[RA_id].rnti == rntiP) - return (RA_id); - } - return (-1); + if (ra[RA_id].state != IDLE && + ra[RA_id].rnti == rntiP) + return (RA_id); + } + return (-1); } //------------------------------------------------------------------------------ int UE_num_active_CC(UE_list_t * listP, int ue_idP) //------------------------------------------------------------------------------ { - return (listP->numactiveCCs[ue_idP]); + return (listP->numactiveCCs[ue_idP]); } //------------------------------------------------------------------------------ int UE_PCCID(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]); + if (!RC.mac || !RC.mac[mod_idP]) return 0; + return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]); } //------------------------------------------------------------------------------ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - rnti_t rnti = - RC.mac[mod_idP]-> - UE_list.UE_template[UE_PCCID(mod_idP, ue_idP)][ue_idP].rnti; + if (!RC.mac || !RC.mac[mod_idP]) return 0; + rnti_t rnti = + RC.mac[mod_idP]-> + UE_list.UE_template[UE_PCCID(mod_idP, ue_idP)][ue_idP].rnti; - if (rnti > 0) { - return (rnti); - } + if (rnti > 0) { + return (rnti); + } - LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); - //display_backtrace(); - return (NOT_A_RNTI); + LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); + //display_backtrace(); + return (NOT_A_RNTI); } //------------------------------------------------------------------------------ boolean_t is_UE_active(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - return (RC.mac[mod_idP]->UE_list.active[ue_idP]); -} - -/* -uint8_t find_active_UEs(module_id_t module_idP,int CC_id){ - - module_id_t ue_mod_id = 0; - rnti_t rnti = 0; - uint8_t nb_active_ue = 0; - - for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) { - - if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].ul_active==TRUE)){ - - if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti - nb_active_ue++; - } - else { // this ue is removed at the phy => remove it at the mac as well - mac_remove_ue(module_idP, CC_id, ue_mod_id); - } - } - } - return(nb_active_ue); + if (!RC.mac || !RC.mac[mod_idP]) return 0; + return (RC.mac[mod_idP]->UE_list.active[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 = 3; + 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); - } + 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); + LOG_D(MAC, "Aggregation level %d (cqi %d, bw_index %d, format %d)\n", 1 << aggregation, cqi, bw_index, dci_fmt); - return 1 << aggregation; + return 1 << aggregation; } void dump_ue_list(UE_list_t * listP, int ul_flag) { - int j; + int j; - if (ul_flag == 0) { - for (j = listP->head; j >= 0; j = listP->next[j]) { - LOG_T(MAC, "node %d => %d\n", j, listP->next[j]); - } - } else { - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { - LOG_T(MAC, "node %d => %d\n", j, listP->next_ul[j]); - } + if (ul_flag == 0) { + for (j = listP->head; j >= 0; j = listP->next[j]) { + LOG_T(MAC, "node %d => %d\n", j, listP->next[j]); + } + } else { + for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + LOG_T(MAC, "node %d => %d\n", j, listP->next_ul[j]); } + } } int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif - ) + ) { - int UE_id; - int i, j; - - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - - LOG_D(MAC, - "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", - mod_idP, cc_idP, rntiP, UE_list->avail, UE_list->num_UEs); - dump_ue_list(UE_list, 0); - - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] == TRUE) - continue; - UE_id = i; - memset(&UE_list->UE_template[cc_idP][UE_id], 0, - sizeof(UE_TEMPLATE)); - UE_list->UE_template[cc_idP][UE_id].rnti = rntiP; - UE_list->UE_template[cc_idP][UE_id].configured = FALSE; - UE_list->numactiveCCs[UE_id] = 1; - UE_list->numactiveULCCs[UE_id] = 1; - UE_list->pCC_id[UE_id] = cc_idP; - UE_list->ordered_CCids[0][UE_id] = cc_idP; - UE_list->ordered_ULCCids[0][UE_id] = cc_idP; - UE_list->num_UEs++; - UE_list->active[UE_id] = TRUE; + int UE_id; + int i, j; + + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + + LOG_D(MAC, + "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", + mod_idP, cc_idP, rntiP, UE_list->avail, UE_list->num_UEs); + dump_ue_list(UE_list, 0); + + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (UE_list->active[i] == TRUE) + continue; + UE_id = i; + memset(&UE_list->UE_template[cc_idP][UE_id], 0, + sizeof(UE_TEMPLATE)); + UE_list->UE_template[cc_idP][UE_id].rnti = rntiP; + UE_list->UE_template[cc_idP][UE_id].configured = FALSE; + UE_list->numactiveCCs[UE_id] = 1; + UE_list->numactiveULCCs[UE_id] = 1; + UE_list->pCC_id[UE_id] = cc_idP; + UE_list->ordered_CCids[0][UE_id] = cc_idP; + UE_list->ordered_ULCCids[0][UE_id] = cc_idP; + UE_list->num_UEs++; + UE_list->active[UE_id] = TRUE; #if defined(USRP_REC_PLAY) // not specific to record/playback ? - UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; + UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; #endif -#ifdef Rel14 - UE_list->UE_template[cc_idP][UE_id].rach_resource_type = - rach_resource_type; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + UE_list->UE_template[cc_idP][UE_id].rach_resource_type = + rach_resource_type; #endif - memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, - sizeof(UE_sched_ctrl)); - memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0, - sizeof(eNB_UE_STATS)); + memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, + sizeof(UE_sched_ctrl)); + memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0, + sizeof(eNB_UE_STATS)); UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ta_update = 31; - for (j = 0; j < 8; j++) { - UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j == 0) ? 1 : 0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0 - UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j == harq_pidP) ? 0 : 1; // 1st transmission is with Msg3; - UE_list->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8; - UE_list->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0; - } + UE_list->UE_sched_ctrl[UE_id].ta_update = 31; - eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING; - eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING; - LOG_D(MAC, "[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n", - mod_idP, UE_id, cc_idP, rntiP); - dump_ue_list(UE_list, 0); - return (UE_id); + for (j = 0; j < 8; j++) { + UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j == 0) ? 1 : 0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0 + UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j == harq_pidP) ? 0 : 1; // 1st transmission is with Msg3; + UE_list->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8; + UE_list->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0; } - printf("MAC: cannot add new UE for rnti %x\n", rntiP); - LOG_E(MAC, - "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n"); + eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING; + eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING; + LOG_D(MAC, "[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n", + mod_idP, UE_id, cc_idP, rntiP); dump_ue_list(UE_list, 0); - return (-1); + return (UE_id); + } + + printf("MAC: cannot add new UE for rnti %x\n", rntiP); + LOG_E(MAC, + "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n"); + dump_ue_list(UE_list, 0); + return (-1); } //------------------------------------------------------------------------------ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { - int i; - int j; - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - int UE_id = find_UE_id(mod_idP,rntiP); - int pCC_id; - - if (UE_id == -1) { - LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP); - return 0; - } - - pCC_id = UE_PCCID(mod_idP,UE_id); - LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP); - dump_ue_list(UE_list,0); - - UE_list->active[UE_id] = FALSE; - UE_list->num_UEs--; - - if (UE_list->head == UE_id) UE_list->head=UE_list->next[UE_id]; - else UE_list->next[prev(UE_list,UE_id,0)]=UE_list->next[UE_id]; - if (UE_list->head_ul == UE_id) UE_list->head_ul=UE_list->next_ul[UE_id]; - else UE_list->next_ul[prev(UE_list,UE_id,0)]=UE_list->next_ul[UE_id]; - - // clear all remaining pending transmissions - /* UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0; - - UE_list->UE_template[pCC_id][UE_id].ul_SR = 0; - UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI; - UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE; - */ - memset (&UE_list->UE_template[pCC_id][UE_id],0,sizeof(UE_TEMPLATE)); - - UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_retx = 0; - for ( j = 0; j < NB_RB_MAX; j++ ) { - UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_tx[j] = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_tx[j] = 0; - } - UE_list->eNB_UE_stats[pCC_id][UE_id].num_retransmission = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_sdu_bytes = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_rx = 0; - for ( j = 0; j < NB_RB_MAX; j++ ) { - UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_rx[j] = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_rx[j] = 0; - } - UE_list->eNB_UE_stats[pCC_id][UE_id].num_errors_rx = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes_rx = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus_rx = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_errors_rx = 0; - - eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; - - eNB_ulsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; - - // check if this has an RA process active - if(find_RA_id(mod_idP, pCC_id, rntiP) != -1) { - cancel_ra_proc(mod_idP, pCC_id, 0, rntiP); - } + int i; + int j; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + int UE_id = find_UE_id(mod_idP,rntiP); + int pCC_id; + + if (UE_id == -1) { + LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP); + return 0; + } + + pCC_id = UE_PCCID(mod_idP,UE_id); + + LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP); + dump_ue_list(UE_list,0); + + UE_list->active[UE_id] = FALSE; + UE_list->num_UEs--; + + if (UE_list->head == UE_id) UE_list->head=UE_list->next[UE_id]; + else UE_list->next[prev(UE_list,UE_id,0)]=UE_list->next[UE_id]; + if (UE_list->head_ul == UE_id) UE_list->head_ul=UE_list->next_ul[UE_id]; + else UE_list->next_ul[prev(UE_list,UE_id,0)]=UE_list->next_ul[UE_id]; + + // clear all remaining pending transmissions + /* UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0; + UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0; + UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0; + UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0; + + UE_list->UE_template[pCC_id][UE_id].ul_SR = 0; + UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI; + UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE; + */ + memset (&UE_list->UE_template[pCC_id][UE_id],0,sizeof(UE_TEMPLATE)); + + UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_retx = 0; + for ( j = 0; j < NB_RB_MAX; j++ ) { + UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_tx[j] = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_tx[j] = 0; + } + UE_list->eNB_UE_stats[pCC_id][UE_id].num_retransmission = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_sdu_bytes = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_rx = 0; + for ( j = 0; j < NB_RB_MAX; j++ ) { + UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_rx[j] = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_rx[j] = 0; + } + UE_list->eNB_UE_stats[pCC_id][UE_id].num_errors_rx = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes_rx = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus_rx = 0; + UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_errors_rx = 0; + + eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; + eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; + + eNB_ulsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; + eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; + + // check if this has an RA process active + if(find_RA_id(mod_idP, pCC_id, rntiP) != -1) { + cancel_ra_proc(mod_idP, pCC_id, 0, rntiP); + } - pthread_mutex_lock(&rrc_release_freelist); - if(rrc_release_info.num_UEs > 0){ - uint16_t release_total = 0; - for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ - release_total++; - }else{ - continue; - } - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rntiP){ - rrc_release_info.RRC_release_ctrl[release_num].flag = 0; - rrc_release_info.num_UEs--; - release_total--; - } - if(release_total >= rrc_release_info.num_UEs){ - break; - } + pthread_mutex_lock(&rrc_release_freelist); + if(rrc_release_info.num_UEs > 0){ + uint16_t release_total = 0; + for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ + if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ + release_total++; + }else{ + continue; + } + if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rntiP){ + rrc_release_info.RRC_release_ctrl[release_num].flag = 0; + rrc_release_info.num_UEs--; + release_total--; + } + if(release_total >= rrc_release_info.num_UEs){ + break; } } - pthread_mutex_unlock(&rrc_release_freelist); - - return 0; + } + pthread_mutex_unlock(&rrc_release_freelist); + + return 0; } int prev(UE_list_t * listP, int nodeP, int ul_flag) { - int j; + int j; - if (ul_flag == 0) { - if (nodeP == listP->head) { - return (nodeP); - } + if (ul_flag == 0) { + if (nodeP == listP->head) { + return (nodeP); + } - for (j = listP->head; j >= 0; j = listP->next[j]) { - if (listP->next[j] == nodeP) { - return (j); - } - } - } else { - if (nodeP == listP->head_ul) { - return (nodeP); - } + for (j = listP->head; j >= 0; j = listP->next[j]) { + if (listP->next[j] == nodeP) { + return (j); + } + } + } else { + if (nodeP == listP->head_ul) { + return (nodeP); + } - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { - if (listP->next_ul[j] == nodeP) { - return (j); - } - } + for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + if (listP->next_ul[j] == nodeP) { + return (j); + } } + } - LOG_E(MAC, - "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n", - nodeP, (ul_flag == 0) ? "DL" : "UL"); - dump_ue_list(listP, ul_flag); + LOG_E(MAC, + "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n", + nodeP, (ul_flag == 0) ? "DL" : "UL"); + dump_ue_list(listP, ul_flag); - return (-1); + return (-1); } void swap_UEs(UE_list_t * listP, int nodeiP, int nodejP, int ul_flag) { - int prev_i, prev_j, next_i, next_j; + int prev_i, prev_j, next_i, next_j; - LOG_T(MAC, "Swapping UE %d,%d\n", nodeiP, nodejP); - dump_ue_list(listP, ul_flag); + LOG_T(MAC, "Swapping UE %d,%d\n", nodeiP, nodejP); + dump_ue_list(listP, ul_flag); - prev_i = prev(listP, nodeiP, ul_flag); - prev_j = prev(listP, nodejP, ul_flag); + prev_i = prev(listP, nodeiP, ul_flag); + prev_j = prev(listP, nodejP, ul_flag); - AssertFatal((prev_i >= 0) && (prev_j >= 0), "swap_UEs: problem"); + AssertFatal((prev_i >= 0) && (prev_j >= 0), "swap_UEs: problem"); - if (ul_flag == 0) { - next_i = listP->next[nodeiP]; - next_j = listP->next[nodejP]; - } else { - next_i = listP->next_ul[nodeiP]; - next_j = listP->next_ul[nodejP]; - } + if (ul_flag == 0) { + next_i = listP->next[nodeiP]; + next_j = listP->next[nodejP]; + } else { + next_i = listP->next_ul[nodeiP]; + next_j = listP->next_ul[nodejP]; + } - LOG_T(MAC, "[%s] next_i %d, next_i, next_j %d, head %d \n", - (ul_flag == 0) ? "DL" : "UL", next_i, next_j, listP->head); - - if (ul_flag == 0) { - - if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... - LOG_T(MAC, - "Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - - listP->next[nodeiP] = next_j; - listP->next[nodejP] = nodeiP; - - if (nodeiP == listP->head) { // case i j n(j) - listP->head = nodejP; - } else { - listP->next[prev_i] = nodejP; - } - } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... - LOG_T(MAC, - "Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); - listP->next[nodejP] = next_i; - listP->next[nodeiP] = nodejP; - - if (nodejP == listP->head) { // case j i n(i) - listP->head = nodeiP; - } else { - listP->next[prev_j] = nodeiP; - } - } else { // case ... p(i) i n(i) ... p(j) j n(j) ... - listP->next[nodejP] = next_i; - listP->next[nodeiP] = next_j; - - if (nodeiP == listP->head) { - LOG_T(MAC, "changing head to %d\n", nodejP); - listP->head = nodejP; - listP->next[prev_j] = nodeiP; - } else if (nodejP == listP->head) { - LOG_D(MAC, "changing head to %d\n", nodeiP); - listP->head = nodeiP; - listP->next[prev_i] = nodejP; - } else { - listP->next[prev_i] = nodejP; - listP->next[prev_j] = nodeiP; - } - } - } else { // ul_flag - - if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... - LOG_T(MAC, - "[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - - listP->next_ul[nodeiP] = next_j; - listP->next_ul[nodejP] = nodeiP; - - if (nodeiP == listP->head_ul) { // case i j n(j) - listP->head_ul = nodejP; - } else { - listP->next_ul[prev_i] = nodejP; - } - } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... - LOG_T(MAC, - "[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); - listP->next_ul[nodejP] = next_i; - listP->next_ul[nodeiP] = nodejP; - - if (nodejP == listP->head_ul) { // case j i n(i) - listP->head_ul = nodeiP; - } else { - listP->next_ul[prev_j] = nodeiP; - } - } else { // case ... p(i) i n(i) ... p(j) j n(j) ... - - listP->next_ul[nodejP] = next_i; - listP->next_ul[nodeiP] = next_j; - - if (nodeiP == listP->head_ul) { - LOG_T(MAC, "[UL]changing head to %d\n", nodejP); - listP->head_ul = nodejP; - listP->next_ul[prev_j] = nodeiP; - } else if (nodejP == listP->head_ul) { - LOG_T(MAC, "[UL]changing head to %d\n", nodeiP); - listP->head_ul = nodeiP; - listP->next_ul[prev_i] = nodejP; - } else { - listP->next_ul[prev_i] = nodejP; - listP->next_ul[prev_j] = nodeiP; - } - } - } + LOG_T(MAC, "[%s] next_i %d, next_i, next_j %d, head %d \n", + (ul_flag == 0) ? "DL" : "UL", next_i, next_j, listP->head); - LOG_T(MAC, "After swap\n"); - dump_ue_list(listP, ul_flag); -} + if (ul_flag == 0) { -/* - #if defined(Rel10) || defined(Rel14) - unsigned char generate_mch_header( unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char msi, - unsigned char short_padding, - unsigned short post_padding) { - - SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header; - uint8_t first_element=0,last_size=0,i; - uint8_t mac_header_control_elements[2*num_sdus],*ce_ptr; - - ce_ptr = &mac_header_control_elements[0]; - - if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element=1; - last_size=1; - } - if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size=1; - } + if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... + LOG_T(MAC, + "Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - // SUBHEADER for MSI CE - if (msi != 0) {// there is MSI MAC Control Element - if (first_element>0) { - mac_header_ptr->E = 1; - mac_header_ptr+=last_size; - } - else { - first_element = 1; - } - if (num_sdus*2 < 128) { - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = MCH_SCHDL_INFO; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = num_sdus*2; - last_size=2; - } - else { - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = MCH_SCHDL_INFO; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L = (num_sdus*2)&0x7fff; - last_size=3; - } - // Create the MSI MAC Control Element here - } + listP->next[nodeiP] = next_j; + listP->next[nodejP] = nodeiP; - // SUBHEADER for MAC SDU (MCCH+MTCHs) - for (i=0;i<num_sdus;i++) { - if (first_element>0) { - mac_header_ptr->E = 1; - mac_header_ptr+=last_size; - } - else { - first_element = 1; - } - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i]; - last_size=2; - } - else { - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L = (unsigned short) sdu_lengths[i]&0x7fff; - last_size=3; - } - } + if (nodeiP == listP->head) { // case i j n(j) + listP->head = nodejP; + } else { + listP->next[prev_i] = nodejP; + } + } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... + LOG_T(MAC, + "Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); + listP->next[nodejP] = next_i; + listP->next[nodeiP] = nodejP; + + if (nodejP == listP->head) { // case j i n(i) + listP->head = nodeiP; + } else { + listP->next[prev_j] = nodeiP; + } + } else { // case ... p(i) i n(i) ... p(j) j n(j) ... + listP->next[nodejP] = next_i; + listP->next[nodeiP] = next_j; + + if (nodeiP == listP->head) { + LOG_T(MAC, "changing head to %d\n", nodejP); + listP->head = nodejP; + listP->next[prev_j] = nodeiP; + } else if (nodejP == listP->head) { + LOG_D(MAC, "changing head to %d\n", nodeiP); + listP->head = nodeiP; + listP->next[prev_i] = nodejP; + } else { + listP->next[prev_i] = nodejP; + listP->next[prev_j] = nodeiP; + } + } + } else { // ul_flag - if (post_padding>0) {// we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr+=last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; - } - else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; - } + if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... + LOG_T(MAC, + "[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - // Copy MSI Control Element to the end of the MAC Header if it presents - if ((ce_ptr-mac_header_control_elements) > 0) { - // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); - memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements); - mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements); - } + listP->next_ul[nodeiP] = next_j; + listP->next_ul[nodejP] = nodeiP; - return((unsigned char*)mac_header_ptr - mac_header); + if (nodeiP == listP->head_ul) { // case i j n(j) + listP->head_ul = nodejP; + } else { + listP->next_ul[prev_i] = nodejP; + } + } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... + LOG_T(MAC, + "[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); + listP->next_ul[nodejP] = next_i; + listP->next_ul[nodeiP] = nodejP; + + if (nodejP == listP->head_ul) { // case j i n(i) + listP->head_ul = nodeiP; + } else { + listP->next_ul[prev_j] = nodeiP; + } + } else { // case ... p(i) i n(i) ... p(j) j n(j) ... + + listP->next_ul[nodejP] = next_i; + listP->next_ul[nodeiP] = next_j; + + if (nodeiP == listP->head_ul) { + LOG_T(MAC, "[UL]changing head to %d\n", nodejP); + listP->head_ul = nodejP; + listP->next_ul[prev_j] = nodeiP; + } else if (nodejP == listP->head_ul) { + LOG_T(MAC, "[UL]changing head to %d\n", nodeiP); + listP->head_ul = nodeiP; + listP->next_ul[prev_i] = nodejP; + } else { + listP->next_ul[prev_i] = nodejP; + listP->next_ul[prev_j] = nodeiP; + } + } } - #endif - */ + + LOG_T(MAC, "After swap\n"); + dump_ue_list(listP, ul_flag); +} // This has to be updated to include BSR information uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id, uint8_t UE_id) { - UE_TEMPLATE *UE_template = - &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; - UE_sched_ctrl *UE_sched_ctl = - &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; - - // do not schedule UE if UL is not working - if (UE_sched_ctl->ul_failure_timer > 0) - return (0); - if (UE_sched_ctl->ul_out_of_sync > 0) - return (0); - - LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n", - module_idP, UE_id, UE_RNTI(module_idP, UE_id)); - - if ((UE_template->bsr_info[LCGID0] > 0) || (UE_template->bsr_info[LCGID1] > 0) || (UE_template->bsr_info[LCGID2] > 0) || (UE_template->bsr_info[LCGID3] > 0) || (UE_template->ul_SR > 0) || // uplink scheduling request - ((UE_sched_ctl->ul_inactivity_timer > 20) && (UE_sched_ctl->ul_scheduled == 0)) || // every 2 frames when RRC_CONNECTED - ((UE_sched_ctl->ul_inactivity_timer > 10) && (UE_sched_ctl->ul_scheduled == 0) && (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED - { - LOG_D(MAC, - "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 %d,SR %d)\n", - module_idP, UE_id, UE_RNTI(module_idP, UE_id), - UE_template->bsr_info[LCGID0], UE_template->ul_SR); - return (1); - } else { - return (0); - } -} + UE_TEMPLATE *UE_template = + &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; + UE_sched_ctrl *UE_sched_ctl = + &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; -uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP) -{ - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + // do not schedule UE if UL is not working + if (UE_sched_ctl->ul_failure_timer > 0) + return (0); + if (UE_sched_ctl->ul_out_of_sync > 0) + return (0); - struct PhysicalConfigDedicated *physicalConfigDedicated = - eNB->UE_list.physicalConfigDedicated[CC_idP][UE_idP]; + LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n", + module_idP, UE_id, UE_RNTI(module_idP, UE_id)); - if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet - AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", - cc->p_eNB); - return (cc->p_eNB); + if ((UE_template->scheduled_ul_bytes < UE_template->estimated_ul_buffer) || + (UE_template->ul_SR > 0) || // uplink scheduling request + ((UE_sched_ctl->ul_inactivity_timer > 20) && (UE_sched_ctl->ul_scheduled == 0)) || // every 2 frames when RRC_CONNECTED + ((UE_sched_ctl->ul_inactivity_timer > 10) && (UE_sched_ctl->ul_scheduled == 0) && (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED + { + LOG_D(MAC, + "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 estimated size %d, SR %d)\n", + module_idP, UE_id, UE_RNTI(module_idP, UE_id), + UE_template->ul_buffer_info[LCGID0], UE_template->ul_SR); + return (1); } else { - AssertFatal(physicalConfigDedicated->antennaInfo != NULL, - "antennaInfo is null for CCId %d, UEid %d\n", CC_idP, - UE_idP); - - AssertFatal(physicalConfigDedicated->antennaInfo->present != - PhysicalConfigDedicated__antennaInfo_PR_NOTHING, - "antennaInfo (mod_id %d, CC_id %d) is set to NOTHING\n", - module_idP, CC_idP); - - if (physicalConfigDedicated->antennaInfo->present == - PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { - return (physicalConfigDedicated->antennaInfo-> - choice.explicitValue.transmissionMode); - } else if (physicalConfigDedicated->antennaInfo->present == - PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { - AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", - cc->p_eNB); - return (cc->p_eNB); - } else - AssertFatal(1 == 0, "Shouldn't be here\n"); - } + return (0); + } +} + +uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP) +{ + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + + struct PhysicalConfigDedicated *physicalConfigDedicated = + eNB->UE_list.physicalConfigDedicated[CC_idP][UE_idP]; + + if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet + AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", + cc->p_eNB); + return (cc->p_eNB); + } else { + AssertFatal(physicalConfigDedicated->antennaInfo != NULL, + "antennaInfo is null for CCId %d, UEid %d\n", CC_idP, + UE_idP); + + AssertFatal(physicalConfigDedicated->antennaInfo->present != + PhysicalConfigDedicated__antennaInfo_PR_NOTHING, + "antennaInfo (mod_id %d, CC_id %d) is set to NOTHING\n", + module_idP, CC_idP); + + if (physicalConfigDedicated->antennaInfo->present == + PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { + return (physicalConfigDedicated->antennaInfo-> + choice.explicitValue.transmissionMode); + } else if (physicalConfigDedicated->antennaInfo->present == + PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { + AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", + cc->p_eNB); + return (cc->p_eNB); + } else + AssertFatal(1 == 0, "Shouldn't be here\n"); + } } int8_t get_ULharq(module_id_t module_idP, int CC_idP, uint16_t frameP, uint8_t subframeP) { - uint8_t ret = -1; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - - if (cc->tdd_Config == NULL) { // FDD - ret = (((frameP << 1) + subframeP) & 7); - } else { - switch (cc->tdd_Config->subframeAssignment) { - case 1: - if ((subframeP == 2) || - (subframeP == 3) || (subframeP == 7) || (subframeP == 8)) - switch (subframeP) { - case 2: - case 3: - ret = (subframeP - 2); - break; - - case 7: - case 8: - ret = (subframeP - 5); - break; - - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - break; - } - - break; + uint8_t ret = -1; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + if (cc->tdd_Config == NULL) { // FDD + ret = (((frameP << 1) + subframeP) & 7); + } else { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + if ((subframeP == 2) || + (subframeP == 3) || (subframeP == 7) || (subframeP == 8)) + switch (subframeP) { case 2: - AssertFatal((subframeP == 2) || (subframeP == 7), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP / 7); - break; - case 3: - AssertFatal((subframeP > 1) && (subframeP < 5), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; - - case 4: - AssertFatal((subframeP > 1) && (subframeP < 4), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; - - case 5: - AssertFatal(subframeP == 2, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; + ret = (subframeP - 2); + break; + + case 7: + case 8: + ret = (subframeP - 5); + break; default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Unsupported TDD mode %d\n", - (int) cc->tdd_Config->subframeAssignment); - break; + AssertFatal(1 == 0, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + break; } + + break; + + case 2: + AssertFatal((subframeP == 2) || (subframeP == 7), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP / 7); + break; + + case 3: + AssertFatal((subframeP > 1) && (subframeP < 5), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + case 4: + AssertFatal((subframeP > 1) && (subframeP < 4), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + case 5: + AssertFatal(subframeP == 2, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + default: + AssertFatal(1 == 0, + "subframe2_harq_pid, Unsupported TDD mode %d\n", + (int) cc->tdd_Config->subframeAssignment); + break; } + } - AssertFatal(ret != -1, - "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t) ret, - frameP, subframeP); - return ret; + AssertFatal(ret != -1, + "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t) ret, + frameP, subframeP); + return ret; } uint16_t getRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs) { - uint16_t RIV; + uint16_t RIV; - if (Lcrbs <= (1 + (N_RB_DL >> 1))) - RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; - else - RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); + if (Lcrbs <= (1 + (N_RB_DL >> 1))) + RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; + else + RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); - return (RIV); + return (RIV); } uint32_t allocate_prbs(int UE_id, unsigned char nb_rb, int N_RB_DL, uint32_t * rballoc) { - int i; - uint32_t rballoc_dci = 0; - unsigned char nb_rb_alloc = 0; - - for (i = 0; i < (N_RB_DL - 2); i += 2) { - if (((*rballoc >> i) & 3) == 0) { - *rballoc |= (3 << i); - rballoc_dci |= (1 << ((12 - i) >> 1)); - nb_rb_alloc += 2; - } + int i; + uint32_t rballoc_dci = 0; + unsigned char nb_rb_alloc = 0; + + for (i = 0; i < (N_RB_DL - 2); i += 2) { + if (((*rballoc >> i) & 3) == 0) { + *rballoc |= (3 << i); + rballoc_dci |= (1 << ((12 - i) >> 1)); + nb_rb_alloc += 2; + } - if (nb_rb_alloc == nb_rb) { - return (rballoc_dci); - } + if (nb_rb_alloc == nb_rb) { + return (rballoc_dci); } + } - if ((N_RB_DL & 1) == 1) { - if ((*rballoc >> (N_RB_DL - 1) & 1) == 0) { - *rballoc |= (1 << (N_RB_DL - 1)); - rballoc_dci |= 1; - } + if ((N_RB_DL & 1) == 1) { + if ((*rballoc >> (N_RB_DL - 1) & 1) == 0) { + *rballoc |= (1 << (N_RB_DL - 1)); + rballoc_dci |= 1; } + } - return (rballoc_dci); + return (rballoc_dci); } int get_bw_index(module_id_t module_id, uint8_t CC_id) { - int bw_index = 0; + int bw_index = 0; - int N_RB_DL = - to_prb(RC.mac[module_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth); + int N_RB_DL = to_prb(RC.mac[module_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - switch (N_RB_DL) { - case 6: // 1.4 MHz - bw_index = 0; - break; + switch (N_RB_DL) { + case 6: // 1.4 MHz + bw_index = 0; + break; - case 25: // 5HMz - bw_index = 1; - break; + case 25: // 5HMz + bw_index = 1; + break; - case 50: // 10HMz - bw_index = 2; - break; + case 50: // 10HMz + bw_index = 2; + break; - case 100: // 20HMz - bw_index = 3; - break; + case 100: // 20HMz + bw_index = 3; + break; - default: - bw_index = 1; - LOG_W(MAC, - "[eNB %d] N_RB_DL %d unknown for CC_id %d, setting bw_index to 1\n", - module_id, N_RB_DL, CC_id); - break; - } + default: + bw_index = 1; + LOG_W(MAC, + "[eNB %d] N_RB_DL %d unknown for CC_id %d, setting bw_index to 1\n", + module_id, N_RB_DL, CC_id); + break; + } - return bw_index; + return bw_index; } int get_min_rb_unit(module_id_t module_id, uint8_t CC_id) { - int min_rb_unit = 0; - int N_RB_DL = - to_prb(RC.mac[module_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth); + int min_rb_unit = 0; + int N_RB_DL = to_prb(RC.mac[module_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - switch (N_RB_DL) { - case 6: // 1.4 MHz - min_rb_unit = 1; - break; + switch (N_RB_DL) { + case 6: // 1.4 MHz + min_rb_unit = 1; + break; - case 25: // 5HMz - min_rb_unit = 2; - break; + case 25: // 5HMz + min_rb_unit = 2; + break; - case 50: // 10HMz - min_rb_unit = 3; - break; + case 50: // 10HMz + min_rb_unit = 3; + break; - case 100: // 20HMz - min_rb_unit = 4; - break; + case 100: // 20HMz + min_rb_unit = 4; + break; - default: - min_rb_unit = 2; - LOG_W(MAC, - "[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", - module_id, N_RB_DL, CC_id); - break; - } + default: + min_rb_unit = 2; + LOG_W(MAC, + "[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", + module_id, N_RB_DL, CC_id); + break; + } - return min_rb_unit; + return min_rb_unit; } uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG, uint8_t * rballoc) { - int check = 0; //check1=0,check2=0; - uint32_t rballoc_dci = 0; - //uint8_t number_of_subbands=13; - - LOG_T(MAC, "*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n", - rballoc[3], rballoc[2], rballoc[1], rballoc[0], nb_rb, N_RBG); - - while ((nb_rb > 0) && (check < N_RBG)) { - //printf("rballoc[%d] %d\n",check,rballoc[check]); - if (rballoc[check] == 1) { - rballoc_dci |= (1 << ((N_RBG - 1) - check)); - - switch (N_RB_DL) { - case 6: - nb_rb--; - break; - - case 25: - if ((check == N_RBG - 1)) { - nb_rb--; - } else { - nb_rb -= 2; - } - - break; - - case 50: - if ((check == N_RBG - 1)) { - nb_rb -= 2; - } else { - nb_rb -= 3; - } - - break; - - case 100: - nb_rb -= 4; - break; - } + int check = 0; //check1=0,check2=0; + uint32_t rballoc_dci = 0; + //uint8_t number_of_subbands=13; + + LOG_T(MAC, "*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n", + rballoc[3], rballoc[2], rballoc[1], rballoc[0], nb_rb, N_RBG); + + while ((nb_rb > 0) && (check < N_RBG)) { + //printf("rballoc[%d] %d\n",check,rballoc[check]); + if (rballoc[check] == 1) { + rballoc_dci |= (1 << ((N_RBG - 1) - check)); + + switch (N_RB_DL) { + case 6: + nb_rb--; + break; + + case 25: + if ((check == N_RBG - 1)) { + nb_rb--; + } else { + nb_rb -= 2; } - // printf("rb_alloc %x\n",rballoc_dci); - check = check + 1; - // check1 = check1+2; + + break; + + case 50: + if ((check == N_RBG - 1)) { + nb_rb -= 2; + } else { + nb_rb -= 3; + } + + break; + + case 100: + nb_rb -= 4; + break; + } } + // printf("rb_alloc %x\n",rballoc_dci); + check = check + 1; + // check1 = check1+2; + } - // rballoc_dci = (rballoc_dci)&(0x1fff); - LOG_T(MAC, "*********RBALLOC : %x\n", rballoc_dci); - // exit(-1); - return (rballoc_dci); + // rballoc_dci = (rballoc_dci)&(0x1fff); + LOG_T(MAC, "*********RBALLOC : %x\n", rballoc_dci); + // exit(-1); + return (rballoc_dci); } int get_subbandsize(uint8_t dl_Bandwidth) { - uint8_t ss[6] = { 6, 4, 4, 6, 8, 8 }; + uint8_t ss[6] = { 6, 4, 4, 6, 8, 8 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth %d is out of bounds\n", - dl_Bandwidth); + AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth %d is out of bounds\n", + dl_Bandwidth); - return (ss[dl_Bandwidth]); + return (ss[dl_Bandwidth]); } int get_nb_subband(int N_RB_DL) { - int nb_sb = 0; + int nb_sb = 0; - switch (N_RB_DL) { - case 6: - nb_sb = 0; - break; + switch (N_RB_DL) { + case 6: + nb_sb = 0; + break; - case 15: - nb_sb = 4; // sb_size =4 + case 15: + nb_sb = 4; // sb_size =4 - case 25: - nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs - break; + case 25: + nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs + break; - case 50: // sb_size =6 - nb_sb = 9; - break; + case 50: // sb_size =6 + nb_sb = 9; + break; - case 75: // sb_size =8 - nb_sb = 10; - break; + case 75: // sb_size =8 + nb_sb = 10; + break; - case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs - nb_sb = 13; - break; + case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs + nb_sb = 13; + break; - default: - nb_sb = 0; - break; - } + default: + nb_sb = 0; + break; + } - return nb_sb; + return nb_sb; } void init_CCE_table(int module_idP, int CC_idP) { - memset(RC.mac[module_idP]->CCE_table[CC_idP], 0, 800 * sizeof(int)); + memset(RC.mac[module_idP]->CCE_table[CC_idP], 0, 800 * sizeof(int)); } @@ -2939,736 +2595,651 @@ get_nCCE_offset(int *CCE_table, const int common_dci, const unsigned short rnti, const unsigned char subframe) { - int search_space_free, m, nb_candidates = 0, l, i; - unsigned int Yk; - /* - printf("CCE Allocation: "); - for (i=0;i<nCCE;i++) - printf("%d.",CCE_table[i]); - printf("\n"); - */ - if (common_dci == 1) { - // check CCE(0 ... L-1) - nb_candidates = (L == 4) ? 4 : 2; - nb_candidates = min(nb_candidates, nCCE / L); - - // printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L); + int search_space_free, m, nb_candidates = 0, l, i; + unsigned int Yk; + /* + printf("CCE Allocation: "); + for (i=0;i<nCCE;i++) + printf("%d.",CCE_table[i]); + printf("\n"); + */ + if (common_dci == 1) { + // check CCE(0 ... L-1) + nb_candidates = (L == 4) ? 4 : 2; + nb_candidates = min(nb_candidates, nCCE / L); + + // printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L); + + for (m = nb_candidates - 1; m >= 0; m--) { + + search_space_free = 1; + for (l = 0; l < L; l++) { + + // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); + if (CCE_table[(m * L) + l] == 1) { + search_space_free = 0; + break; + } + } - for (m = nb_candidates - 1; m >= 0; m--) { + if (search_space_free == 1) { - search_space_free = 1; - for (l = 0; l < L; l++) { + // printf("returning %d\n",m*L); - // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); - if (CCE_table[(m * L) + l] == 1) { - search_space_free = 0; - break; - } - } + for (l = 0; l < L; l++) + CCE_table[(m * L) + l] = 1; + return (m * L); + } + } - if (search_space_free == 1) { + return (-1); - // printf("returning %d\n",m*L); + } else { // Find first available in ue specific search space + // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) + // compute Yk + Yk = (unsigned int) rnti; - for (l = 0; l < L; l++) - CCE_table[(m * L) + l] = 1; - return (m * L); - } - } + for (i = 0; i <= subframe; i++) + Yk = (Yk * 39827) % 65537; - return (-1); + Yk = Yk % (nCCE / L); - } else { // Find first available in ue specific search space - // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) - // compute Yk - Yk = (unsigned int) rnti; + switch (L) { + case 1: + case 2: + nb_candidates = 6; + break; - for (i = 0; i <= subframe; i++) - Yk = (Yk * 39827) % 65537; + case 4: + case 8: + nb_candidates = 2; + break; - Yk = Yk % (nCCE / L); + default: + DevParam(L, nCCE, rnti); + break; + } - switch (L) { - case 1: - case 2: - nb_candidates = 6; - break; + LOG_D(MAC, "rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n", + rnti, Yk, nCCE, nCCE / L, nb_candidates); - case 4: - case 8: - nb_candidates = 2; - break; + for (m = 0; m < nb_candidates; m++) { + search_space_free = 1; - default: - DevParam(L, nCCE, rnti); - break; + for (l = 0; l < L; l++) { + int cce = (((Yk + m) % (nCCE / L)) * L) + l; + if (cce >= nCCE || CCE_table[cce] == 1) { + search_space_free = 0; + break; } + } - LOG_D(MAC, "rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n", - rnti, Yk, nCCE, nCCE / L, nb_candidates); - - for (m = 0; m < nb_candidates; m++) { - search_space_free = 1; - - for (l = 0; l < L; l++) { - int cce = (((Yk + m) % (nCCE / L)) * L) + l; - if (cce >= nCCE || CCE_table[cce] == 1) { - search_space_free = 0; - break; - } - } - - if (search_space_free == 1) { - for (l = 0; l < L; l++) - CCE_table[(((Yk + m) % (nCCE / L)) * L) + l] = 1; - - return (((Yk + m) % (nCCE / L)) * L); - } - } + if (search_space_free == 1) { + for (l = 0; l < L; l++) + CCE_table[(((Yk + m) % (nCCE / L)) * L) + l] = 1; - return (-1); + return (((Yk + m) % (nCCE / L)) * L); + } } + + return (-1); + } } void dump_CCE_table(int *CCE_table, const int nCCE, const unsigned short rnti, const int subframe, int L) { - int nb_candidates = 0, i; - unsigned int Yk; - - printf("CCE 0: "); - for (i = 0; i < nCCE; i++) { - printf("%1d.", CCE_table[i]); - if ((i & 7) == 7) - printf("\n CCE %d: ", i); - } + int nb_candidates = 0, i; + unsigned int Yk; + + printf("CCE 0: "); + for (i = 0; i < nCCE; i++) { + printf("%1d.", CCE_table[i]); + if ((i & 7) == 7) + printf("\n CCE %d: ", i); + } - Yk = (unsigned int) rnti; + Yk = (unsigned int) rnti; - for (i = 0; i <= subframe; i++) - Yk = (Yk * 39827) % 65537; + for (i = 0; i <= subframe; i++) + Yk = (Yk * 39827) % 65537; - Yk = Yk % (nCCE / L); + Yk = Yk % (nCCE / L); - switch (L) { - case 1: - case 2: - nb_candidates = 6; - break; + switch (L) { + case 1: + case 2: + nb_candidates = 6; + break; - case 4: - case 8: - nb_candidates = 2; - break; + case 4: + case 8: + nb_candidates = 2; + break; - default: - DevParam(L, nCCE, rnti); - break; - } + default: + DevParam(L, nCCE, rnti); + break; + } - printf("rnti %x, Yk*L = %d, nCCE %d (nCCE/L %d),nb_cand*L %d\n", rnti, - Yk * L, nCCE, nCCE / L, nb_candidates * L); + printf("rnti %x, Yk*L = %d, nCCE %d (nCCE/L %d),nb_cand*L %d\n", rnti, + Yk * L, nCCE, nCCE / L, nb_candidates * L); } uint16_t getnquad(COMMON_channels_t * cc, uint8_t num_pdcch_symbols, uint8_t mi) { - uint16_t Nreg = 0; + uint16_t Nreg = 0; - AssertFatal(cc != NULL, "cc is null\n"); - AssertFatal(cc->mib != NULL, "cc->mib is null\n"); + AssertFatal(cc != NULL, "cc is null\n"); + AssertFatal(cc->mib != NULL, "cc->mib is null\n"); - int N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - int phich_resource = get_phich_resource_times6(cc); + int N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + int phich_resource = get_phich_resource_times6(cc); - uint8_t Ngroup_PHICH = (phich_resource * N_RB_DL) / 48; + uint8_t Ngroup_PHICH = (phich_resource * N_RB_DL) / 48; - if (((phich_resource * N_RB_DL) % 48) > 0) - Ngroup_PHICH++; + if (((phich_resource * N_RB_DL) % 48) > 0) + Ngroup_PHICH++; - if (cc->Ncp == 1) { - Ngroup_PHICH <<= 1; - } + if (cc->Ncp == 1) { + Ngroup_PHICH <<= 1; + } - Ngroup_PHICH *= mi; + Ngroup_PHICH *= mi; - if ((num_pdcch_symbols > 0) && (num_pdcch_symbols < 4)) - switch (N_RB_DL) { - case 6: - Nreg = 12 + (num_pdcch_symbols - 1) * 18; - break; + if ((num_pdcch_symbols > 0) && (num_pdcch_symbols < 4)) + switch (N_RB_DL) { + case 6: + Nreg = 12 + (num_pdcch_symbols - 1) * 18; + break; - case 25: - Nreg = 50 + (num_pdcch_symbols - 1) * 75; - break; + case 25: + Nreg = 50 + (num_pdcch_symbols - 1) * 75; + break; - case 50: - Nreg = 100 + (num_pdcch_symbols - 1) * 150; - break; + case 50: + Nreg = 100 + (num_pdcch_symbols - 1) * 150; + break; - case 100: - Nreg = 200 + (num_pdcch_symbols - 1) * 300; - break; + case 100: + Nreg = 200 + (num_pdcch_symbols - 1) * 300; + break; - default: - return (0); - } - // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); - return (Nreg - 4 - (3 * Ngroup_PHICH)); + default: + return (0); + } + // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); + return (Nreg - 4 - (3 * Ngroup_PHICH)); } uint16_t getnCCE(COMMON_channels_t * cc, uint8_t num_pdcch_symbols, uint8_t mi) { - AssertFatal(cc != NULL, "cc is null\n"); - return (getnquad(cc, num_pdcch_symbols, mi) / 9); + AssertFatal(cc != NULL, "cc is null\n"); + return (getnquad(cc, num_pdcch_symbols, mi) / 9); } uint8_t getmi(COMMON_channels_t * cc, int subframe) { - AssertFatal(cc != NULL, "cc is null\n"); + AssertFatal(cc != NULL, "cc is null\n"); - // for FDD - if (cc->tdd_Config == NULL) // FDD - return 1; + // for FDD + if (cc->tdd_Config == NULL) // FDD + return 1; - // for TDD - switch (cc->tdd_Config->subframeAssignment) { - case 0: - if ((subframe == 0) || (subframe == 5)) - return (2); - else - return (1); + // for TDD + switch (cc->tdd_Config->subframeAssignment) { + case 0: + if ((subframe == 0) || (subframe == 5)) + return (2); + else + return (1); - break; + break; - case 1: - if ((subframe == 0) || (subframe == 5)) - return (0); - else - return (1); + case 1: + if ((subframe == 0) || (subframe == 5)) + return (0); + else + return (1); - break; + break; - case 2: - if ((subframe == 3) || (subframe == 8)) - return (1); - else - return (0); + case 2: + if ((subframe == 3) || (subframe == 8)) + return (1); + else + return (0); - break; + break; - case 3: - if ((subframe == 0) || (subframe == 8) || (subframe == 9)) - return (1); - else - return (0); + case 3: + if ((subframe == 0) || (subframe == 8) || (subframe == 9)) + return (1); + else + return (0); - break; + break; - case 4: - if ((subframe == 8) || (subframe == 9)) - return (1); - else - return (0); + case 4: + if ((subframe == 8) || (subframe == 9)) + return (1); + else + return (0); - break; + break; - case 5: - if (subframe == 8) - return (1); - else - return (0); + case 5: + if (subframe == 8) + return (1); + else + return (0); - break; + break; - case 6: - return (1); - break; + case 6: + return (1); + break; - default: - return (0); - } + default: + return (0); + } } uint16_t get_nCCE_max(COMMON_channels_t * cc, int num_pdcch_symbols, int subframe) { - AssertFatal(cc != NULL, "cc is null\n"); - return (getnCCE(cc, num_pdcch_symbols, getmi(cc, subframe))); + AssertFatal(cc != NULL, "cc is null\n"); + return (getnCCE(cc, num_pdcch_symbols, getmi(cc, subframe))); } // Allocate the CCEs int allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, int test_onlyP) { - int *CCE_table = RC.mac[module_idP]->CCE_table[CC_idP]; - nfapi_dl_config_request_body_t *DL_req = - &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; - nfapi_hi_dci0_request_body_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body; - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &DL_req->dl_config_pdu_list[0]; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_pdu_list[0]; - int nCCE_max = - get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], 1, - subframeP); - int fCCE; - int i, j, idci; - int nCCE = 0; - int max_symbol; - - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - int ackNAK_absSF = get_pucch1_absSF(cc, (frameP*10+subframeP)); - if (cc->tdd_Config!=NULL && is_S_sf(cc,subframeP) > 0) - max_symbol = 2; - else - max_symbol = 3; - - nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body; - - LOG_D(MAC, - "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", - subframeP, test_onlyP, DL_req->number_pdu, DL_req->number_dci, - HI_DCI0_req->number_of_dci); - DL_req->number_pdcch_ofdm_symbols = 1; - - try_again: - init_CCE_table(module_idP, CC_idP); - nCCE = 0; - - for (i = 0, idci = 0; i < DL_req->number_pdu; i++) { - // allocate DL common DCIs first - if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == - 2)) { - LOG_D(MAC, - "Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - - if (nCCE + - (dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } - // number of CCEs left can potentially hold this allocation - fCCE = get_nCCE_offset(CCE_table, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE_max, 1, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - subframeP); - if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { - LOG_D(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - rnti); - for (j = 0; j <= i; j++) { - if (dl_config_pdu[j].pdu_type == - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + - HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.dci_format, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 - - // the allocation is feasible, rnti rule passes - nCCE += + int *CCE_table = RC.mac[module_idP]->CCE_table[CC_idP]; + nfapi_dl_config_request_body_t *DL_req = + &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; + nfapi_hi_dci0_request_body_t *HI_DCI0_req = + &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &DL_req->dl_config_pdu_list[0]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = + &HI_DCI0_req->hi_dci0_pdu_list[0]; + int nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], 1, + subframeP); + int fCCE; + int i, j, idci; + int nCCE = 0; + int max_symbol; + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + int ackNAK_absSF = get_pucch1_absSF(cc, (frameP*10+subframeP)); + if (cc->tdd_Config!=NULL && is_S_sf(cc,subframeP) > 0) + max_symbol = 2; + else + max_symbol = 3; + + nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body; + + LOG_D(MAC, + "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", + subframeP, test_onlyP, DL_req->number_pdu, DL_req->number_dci, + HI_DCI0_req->number_of_dci); + DL_req->number_pdcch_ofdm_symbols = 1; + + try_again: + init_CCE_table(module_idP, CC_idP); + nCCE = 0; + + for (i = 0, idci = 0; i < DL_req->number_pdu; i++) { + // allocate DL common DCIs first + if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == + 2)) { + LOG_D(MAC, + "Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, HI_DCI0_req->number_of_dci, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + + if (nCCE + + (dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) + goto failed; + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]-> + common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } + // number of CCEs left can potentially hold this allocation + fCCE = get_nCCE_offset(CCE_table, + dl_config_pdu[i]. + dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, nCCE_max, 1, + dl_config_pdu[i]. + dci_dl_pdu.dci_dl_pdu_rel8.rnti, + subframeP); + if (fCCE == -1) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { + LOG_D(MAC, + "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); - if ((test_onlyP%2) == 0) { - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; - LOG_D(MAC, - "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n", - subframeP, test_onlyP, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, fCCE); - } - idci++; + rnti); + for (j = 0; j <= i; j++) { + if (dl_config_pdu[j].pdu_type == + NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + LOG_D(MAC, + "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + dl_config_pdu[j]. + dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[j]. + dci_dl_pdu.dci_dl_pdu_rel8.dci_format, + dl_config_pdu[j]. + dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, nCCE, nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + } + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); + goto failed; } - } // for i = 0 ... num_DL_DCIs - - // no try to allocate UL DCIs - for (i = 0; i < HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi; - i++) { - - // allocate UL DCIs - if (hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { - - LOG_D(MAC, - "Trying to allocate format 0 DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level, - nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols); - - if (nCCE + - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level) > - nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } - // number of CCEs left can potentially hold this allocation - fCCE = get_nCCE_offset(CCE_table, - hi_dci0_pdu[i].dci_pdu. - dci_pdu_rel8.aggregation_level, - nCCE_max, 0, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8. - rnti, subframeP); - if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { - LOG_D(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti); - for (j = 0; j <= i; j++) { - if (hi_dci0_pdu[j].pdu_type == - NFAPI_HI_DCI0_DCI_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + - HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8.rnti, - hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8. - dci_format, - hi_dci0_pdu[j].dci_pdu. - dci_pdu_rel8.aggregation_level, nCCE, - nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(&RC.mac[module_idP]-> common_channels[CC_idP], DL_req->number_pdcch_ofdm_symbols, subframeP); - goto try_again; - } // fCCE==-1 - - // the allocation is feasible, rnti rule passes - nCCE += hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); - if ((test_onlyP%2) == 0) { - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.cce_index = fCCE; - LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", - subframeP, test_onlyP); - } - idci++; + goto try_again; + } // fCCE==-1 + + // the allocation is feasible, rnti rule passes + nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + if ((test_onlyP%2) == 0) { + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; + LOG_D(MAC, + "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n", + subframeP, test_onlyP, + dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, fCCE); + } + idci++; + } + } // for i = 0 ... num_DL_DCIs + + // no try to allocate UL DCIs + for (i = 0; i < HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi; + i++) { + + // allocate UL DCIs + if (hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { + + LOG_D(MAC, + "Trying to allocate format 0 DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, HI_DCI0_req->number_of_dci, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level, + nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols); + + if (nCCE + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) + goto failed; + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } + // number of CCEs left can potentially hold this allocation + fCCE = get_nCCE_offset(CCE_table, + hi_dci0_pdu[i].dci_pdu. + dci_pdu_rel8.aggregation_level, + nCCE_max, 0, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8. + rnti, subframeP); + if (fCCE == -1) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { + LOG_D(MAC, + "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti); + for (j = 0; j <= i; j++) { + if (hi_dci0_pdu[j].pdu_type == + NFAPI_HI_DCI0_DCI_PDU_TYPE) + LOG_D(MAC, + "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8.rnti, + hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8. + dci_format, + hi_dci0_pdu[j].dci_pdu. + dci_pdu_rel8.aggregation_level, nCCE, + nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + } + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); + goto failed; } - } // for i = 0 ... num_UL_DCIs - - for (i = 0; i < DL_req->number_pdu; i++) { - // allocate DL UE specific DCIs - if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == - 1)) { - LOG_D(MAC, - "Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - - if (nCCE + - (dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } - // number of CCEs left can potentially hold this allocation - fCCE = get_nCCE_offset(CCE_table, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE_max, 0, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - subframeP); - if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { - LOG_I(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - rnti); - for (j = 0; j <= i; j++) { - if (dl_config_pdu[j].pdu_type == - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + - HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.dci_format, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 - - // the allocation is feasible, rnti rule passes - nCCE += + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } // fCCE==-1 + + // the allocation is feasible, rnti rule passes + nCCE += hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + if ((test_onlyP%2) == 0) { + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.cce_index = fCCE; + LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", + subframeP, test_onlyP); + } + idci++; + } + } // for i = 0 ... num_UL_DCIs + + for (i = 0; i < DL_req->number_pdu; i++) { + // allocate DL UE specific DCIs + if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == + 1)) { + LOG_D(MAC, + "Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, HI_DCI0_req->number_of_dci, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + + if (nCCE + (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) + goto failed; + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } + // number of CCEs left can potentially hold this allocation + fCCE = get_nCCE_offset(CCE_table, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, nCCE_max, 0, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + subframeP); + if (fCCE == -1) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { + LOG_I(MAC, + "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); - if ((test_onlyP%2) == 0) { - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; - LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", - subframeP, test_onlyP); - } - if ((test_onlyP/2) == 1) { - for(int ack_int = 0;ack_int < ul_req->number_of_pdus; ack_int++){ - if(((ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) || - (ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE)) && - (ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.ue_information.ue_information_rel8.rnti == dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti)){ - if (cc->tdd_Config==NULL) - ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE; - else - ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel10_tdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE + get_Np(to_prb(cc->mib->message.dl_Bandwidth),fCCE,0) ; - } - } - } - idci++; + rnti); + for (j = 0; j <= i; j++) { + if (dl_config_pdu[j].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + LOG_D(MAC, + "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8.dci_format, + dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, + nCCE, + nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + } + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); + goto failed; } - } // for i = 0 ... num_DL_DCIs - - return 0; - - failed: - return -1; -} + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } // fCCE==-1 + + // the allocation is feasible, rnti rule passes + nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + if ((test_onlyP%2) == 0) { + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; + LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", + subframeP, test_onlyP); + } + if ((test_onlyP/2) == 1) { + for(int ack_int = 0;ack_int < ul_req->number_of_pdus; ack_int++){ + if(((ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) || + (ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE)) && + (ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.ue_information.ue_information_rel8.rnti == dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti)){ + if (cc->tdd_Config==NULL) + ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = + cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE; + else + ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel10_tdd.n_pucch_1_0 = + cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE + get_Np(to_prb(cc->mib->message.dl_Bandwidth),fCCE,0) ; + } + } + } + idci++; + } + } // for i = 0 ... num_DL_DCIs -/* -uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP) -{ - if (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config == NULL) - return(0); + return 0; - switch (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment) { - case 0: - case 1: - case 2: - case 6: - return(0); - case 3: - // 1,5,6 -> 2, prog. 8, buffer 0 - // 7,8 -> 3, prog. 9, buffer 1 - // 9,0 -> 4, prog. 0, buffer 0 - if ((subframeP == 7) || (subframeP == 8)) return(1); - else return(0); - case 4: - // 0,1,4,5 -> 2, prog. 8, buffer 0 - // 6,7,8,9 -> 3, prog. 9, buffer 1 - if (subframeP<6) return(0); - else return(1); - return(1); - break; - case 5: - // 9(-1),0,1,3,4,5,6,7,8,9 -> 2, prog 8, buffer 0 - return(0); - break; - default: - AssertFatal(1==0,"Should not get here, why is tdd_Config->subframeAssignment = %d\n",(int)RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment); - break; - } - return(0); + failed: + return -1; } -*/ nfapi_ul_config_request_pdu_t *has_ul_grant(module_id_t module_idP, int CC_idP, uint16_t absSFP, uint16_t rnti) { - nfapi_ul_config_request_body_t *ul_req; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - - ul_req = - &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP % - 10].ul_config_request_body; - ul_config_pdu = &ul_req->ul_config_pdu_list[0]; - LOG_D(MAC, - "Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n", - rnti, absSFP % 10, ul_req->number_of_pdus); - - for (int i = 0; i < ul_req->number_of_pdus; i++) { - LOG_D(MAC, "PDU %d : type %d,rnti %x\n", i, - ul_config_pdu[i].pdu_type, rnti); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) - && (ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_cqi_ri_pdu.ulsch_pdu. - ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8. - rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_cqi_harq_ri_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) - && (ul_config_pdu[i].uci_sr_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_sr_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_sr_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_sr_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_uci_csi_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_uci_harq_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_csi_uci_harq_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - } + nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + + ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP % 10].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[0]; + LOG_D(MAC, + "Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n", + rnti, absSFP % 10, ul_req->number_of_pdus); + + for (int i = 0; i < ul_req->number_of_pdus; i++) { + LOG_D(MAC, "PDU %d : type %d,rnti %x\n", i,ul_config_pdu[i].pdu_type, rnti); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) + && (ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) + && (ul_config_pdu[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) + && (ul_config_pdu[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) + && (ul_config_pdu[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) + && (ul_config_pdu[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE) + && (ul_config_pdu[i].ulsch_uci_csi_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].ulsch_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].ulsch_csi_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + } - return (NULL); // no ul grant at all for this UE + return (NULL); // no ul grant at all for this UE } boolean_t @@ -3677,68 +3248,57 @@ CCE_allocation_infeasible(int module_idP, int format_flag, int subframe, int aggregation, int rnti) { - nfapi_dl_config_request_body_t *DL_req = - &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &DL_req->dl_config_pdu_list[DL_req->number_pdu]; - nfapi_hi_dci0_request_body_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe].hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + - HI_DCI0_req->number_of_hi]; - int ret; - boolean_t res = FALSE; - - if (format_flag != 2) { // DL DCI - if (DL_req->number_pdu == MAX_NUM_DL_PDU) { - LOG_W(MAC, - "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", - subframe, rnti); - } else { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = - (format_flag == 0) ? 2 : 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - aggregation; - DL_req->number_pdu++; - LOG_D(MAC, - "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n", - subframe, format_flag, rnti, aggregation, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type); - ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0); - if (ret == -1) - res = TRUE; - DL_req->number_pdu--; - } - } else { // ue-specific UL DCI - if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == - MAX_NUM_HI_DCI0_PDU) { - LOG_W(MAC, - "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", - subframe, rnti); - } else { - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = - aggregation; - HI_DCI0_req->number_of_dci++; - ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0); - if (ret == -1) - res = TRUE; - HI_DCI0_req->number_of_dci--; - } + nfapi_dl_config_request_body_t *DL_req = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; + nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe].hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi]; + int ret; + boolean_t res = FALSE; + + if (format_flag != 2) { // DL DCI + if (DL_req->number_pdu == MAX_NUM_DL_PDU) { + LOG_W(MAC, + "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", + subframe, rnti); + } else { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0) ? 2 : 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; + DL_req->number_pdu++; + LOG_D(MAC, + "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n", + subframe, format_flag, rnti, aggregation, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type); + ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0); + if (ret == -1) res = TRUE; + DL_req->number_pdu--; + } + } else { // ue-specific UL DCI + if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == MAX_NUM_HI_DCI0_PDU) { + LOG_W(MAC, + "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", + subframe, rnti); + } else { + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + HI_DCI0_req->number_of_dci++; + ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0); + if (ret == -1) res = TRUE; + HI_DCI0_req->number_of_dci--; } + } - return res; + return res; } void get_retransmission_timing(TDD_Config_t *tdd_Config, frame_t *frameP, - sub_frame_t *subframeP) + sub_frame_t *subframeP) { if (tdd_Config == NULL) @@ -3751,6 +3311,7 @@ void get_retransmission_timing(TDD_Config_t *tdd_Config, frame_t *frameP, { switch (tdd_Config->subframeAssignment)//TODO fill in other TDD configs { + default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort(); case 1: if (*subframeP == 0 || *subframeP == 5) { @@ -3814,411 +3375,491 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, frame_t frameP, sub_frame_t subframeP, void *harq_indication, int format) { - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - rnti_t rnti = UE_RNTI(mod_idP, UE_id); - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd; - nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd; - uint16_t num_ack_nak; - int numCC = UE_list->numactiveCCs[UE_id]; - int pCCid = UE_list->pCC_id[UE_id]; - int spatial_bundling = 0; - int tmode[5]; - int i, j, m; - uint8_t *pdu; - LTE_DL_FRAME_PARMS *fp; - sub_frame_t subframe_tx; - int frame_tx; - uint8_t harq_pid; - -#ifdef Rel14 - if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL && - UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL && - (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) - && (UE_list->UE_template[pCCid][UE_id]. - physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13) - && - (((UE_list->UE_template[pCCid][UE_id]. - physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13-> - spatialBundlingPUCCH_r13) - && (format == 0)) - || - ((UE_list->UE_template[pCCid][UE_id]. - physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13-> - spatialBundlingPUSCH_r13) - && (format == 1)))) - spatial_bundling = 1; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti_t rnti = UE_RNTI(mod_idP, UE_id); + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd; + nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd; + uint16_t num_ack_nak; + int numCC = UE_list->numactiveCCs[UE_id]; + int pCCid = UE_list->pCC_id[UE_id]; + int spatial_bundling = 0; + int tmode[5]; + int i, j, m; + uint8_t *pdu; + LTE_DL_FRAME_PARMS *fp; + sub_frame_t subframe_tx; + int frame_tx; + uint8_t harq_pid; + +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL && + UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL && + (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) + && (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13) + && (((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUCCH_r13) && (format == 0)) + || ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUSCH_r13) + && (format == 1)))) + spatial_bundling = 1; #endif - fp=&(RC.eNB[mod_idP][CC_idP]->frame_parms); - for (i = 0; i < numCC; i++) - tmode[i] = get_tmode(mod_idP, i, UE_id); - - if (cc->tdd_Config) { - harq_indication_tdd = (nfapi_harq_indication_tdd_rel13_t *) harq_indication; - // pdu = &harq_indication_tdd->harq_tb_n[0]; - - num_ack_nak = harq_indication_tdd->number_of_ack_nack; - - switch (harq_indication_tdd->mode) { - case 0: // Format 1a/b bundling - AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", numCC); - int M = ul_ACK_subframe2_M(fp,subframeP); - for(m=0;m<M;m++){ - subframe_tx = ul_ACK_subframe2_dl_subframe(fp,subframeP,m); - if(frameP==1023&&subframeP>5) - frame_tx=-1; - else - frame_tx = subframeP < 4 ? frameP -1 : frameP; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame_tx,subframe_tx); - RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; - - if(num_ack_nak==1){ - if(harq_indication_tdd->harq_data[0].bundling.value_0==1){ //ack - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - LOG_D(MAC,"frame %d subframe %d Acking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]); - }else{ //nack - if( sched_ctl->round[CC_idP][harq_pid]<8) - sched_ctl->round[CC_idP][harq_pid]++; - LOG_D(MAC,"frame %d subframe %d Nacking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]); - if(sched_ctl->round[CC_idP][harq_pid] == 8){ - for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){ - //Msg NACK num to MAC ,remove UE - // add UE info to freeList - LOG_I(RRC, "put UE %x into freeList\n", rnti); - put_UE_in_freelist(mod_idP, rnti, 1); - } - } - } - } - } - for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) && (ra[ra_i].crnti_harq_pid == harq_pid)) { - LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",harq_indication_tdd->harq_data[0].bundling.value_0,rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP); - if(num_ack_nak == 1 && harq_indication_tdd->harq_data[0].bundling.value_0 == 1) { - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); - }else{ - if(sched_ctl->round[CC_idP][harq_pid] == 7){ - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); - } - } - break; - } - } - } - break; - case 1: // Channel Selection - break; - case 2: // Format 3 - break; - case 3: // Format 4 - break; - case 4: // Format 5 - break; - } - } else { - harq_indication_fdd = - (nfapi_harq_indication_fdd_rel13_t *) harq_indication; - num_ack_nak = harq_indication_fdd->number_of_ack_nack; - pdu = &harq_indication_fdd->harq_tb_n[0]; - - harq_pid = ((10 * frameP) + subframeP + 10236) & 7; - - LOG_D(MAC,"frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n",frameP,subframeP,harq_pid,harq_indication_fdd->mode,tmode[0],num_ack_nak,sched_ctl->round[CC_idP][harq_pid]); - - switch (harq_indication_fdd->mode) { - case 0: // Format 1a/b (10.1.2.1) - AssertFatal(numCC == 1, - "numCC %d > 1, should not be using Format1a/b\n", - numCC); - if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port - // single ACK/NAK bit - AssertFatal(num_ack_nak == 1, - "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", - num_ack_nak,frameP,subframeP); - AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, - "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", - harq_pid, UE_id, rnti); - AssertFatal(pdu[0] == 1 || pdu[0] == 2 - || pdu[0] == 4, - "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n", - pdu[0], harq_pid, UE_id, rnti); - LOG_D(MAC, "Received %d for harq_pid %d\n", pdu[0], - harq_pid); - + fp=&(RC.eNB[mod_idP][CC_idP]->frame_parms); + for (i = 0; i < numCC; i++) + tmode[i] = get_tmode(mod_idP, i, UE_id); + + if (cc->tdd_Config) { + harq_indication_tdd = (nfapi_harq_indication_tdd_rel13_t *) harq_indication; + // pdu = &harq_indication_tdd->harq_tb_n[0]; + + num_ack_nak = harq_indication_tdd->number_of_ack_nack; + + switch (harq_indication_tdd->mode) { + case 0: // Format 1a/b bundling + AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", numCC); + int M = ul_ACK_subframe2_M(fp,subframeP); + for(m=0;m<M;m++){ + subframe_tx = ul_ACK_subframe2_dl_subframe(fp,subframeP,m); + if(frameP==1023&&subframeP>5) + frame_tx=-1; + else + frame_tx = subframeP < 4 ? frameP -1 : frameP; + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame_tx,subframe_tx); RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; + + if(num_ack_nak==1){ + if(harq_indication_tdd->harq_data[0].bundling.value_0==1){ //ack + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + LOG_D(MAC,"frame %d subframe %d Acking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]); + }else{ //nack + if( sched_ctl->round[CC_idP][harq_pid]<8) + sched_ctl->round[CC_idP][harq_pid]++; + LOG_D(MAC,"frame %d subframe %d Nacking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]); + if(sched_ctl->round[CC_idP][harq_pid] == 8){ + for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { + if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){ + //Msg NACK num to MAC ,remove UE + // add UE info to freeList + LOG_I(RRC, "put UE %x into freeList\n", rnti); + put_UE_in_freelist(mod_idP, rnti, 1); + } + } + } + } + } for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) && - (ra[ra_i].crnti_harq_pid == harq_pid)) { - LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",pdu[0],rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP); - if(pdu[0] == 1){ - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); - }else{ - if(sched_ctl->round[CC_idP][harq_pid] == 7){ - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); - } + if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) && (ra[ra_i].crnti_harq_pid == harq_pid)) { + LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",harq_indication_tdd->harq_data[0].bundling.value_0,rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP); + if(num_ack_nak == 1 && harq_indication_tdd->harq_data[0].bundling.value_0 == 1) { + cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); + }else{ + if(sched_ctl->round[CC_idP][harq_pid] == 7){ + cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); + } + } + break; + } + } + } + break; + case 1: // Channel Selection + break; + case 2: // Format 3 + break; + case 3: // Format 4 + break; + case 4: // Format 5 + break; + } + } else { + harq_indication_fdd = (nfapi_harq_indication_fdd_rel13_t *) harq_indication; + num_ack_nak = harq_indication_fdd->number_of_ack_nack; + pdu = &harq_indication_fdd->harq_tb_n[0]; + + harq_pid = ((10 * frameP) + subframeP + 10236) & 7; + + LOG_D(MAC,"frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n",frameP,subframeP,harq_pid,harq_indication_fdd->mode,tmode[0],num_ack_nak,sched_ctl->round[CC_idP][harq_pid]); + + switch (harq_indication_fdd->mode) { + case 0: // Format 1a/b (10.1.2.1) + AssertFatal(numCC == 1, + "numCC %d > 1, should not be using Format1a/b\n", + numCC); + if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port + // single ACK/NAK bit + AssertFatal(num_ack_nak == 1, + "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", + num_ack_nak,frameP,subframeP); + AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, + "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", + harq_pid, UE_id, rnti); + AssertFatal(pdu[0] == 1 || pdu[0] == 2 + || pdu[0] == 4, + "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n", + pdu[0], harq_pid, UE_id, rnti); + LOG_D(MAC, "Received %d for harq_pid %d\n", pdu[0], + harq_pid); + + RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; + for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { + if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) && + (ra[ra_i].crnti_harq_pid == harq_pid)) { + LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",pdu[0],rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP); + if(pdu[0] == 1){ + cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); + }else{ + if(sched_ctl->round[CC_idP][harq_pid] == 7){ + cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); + } + } + break; + } + } + + if (pdu[0] == 1) { // ACK + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + } else if (pdu[0] == 2 || pdu[0] == 4) { // NAK (treat DTX as NAK) + sched_ctl->round[CC_idP][harq_pid]++; // increment round + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + } + if (sched_ctl->round[CC_idP][harq_pid] == 8){ + for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { + if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){ + //Msg NACK num to MAC ,remove UE + // add UE info to freeList + LOG_I(RRC, "put UE %x into freeList\n", rnti); + put_UE_in_freelist(mod_idP, rnti, 1); } - break; + } + } + } + } else { + // one or two ACK/NAK bits + AssertFatal(num_ack_nak <= 2, + "num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n", + num_ack_nak); + if ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) + && (pdu[0] == 1) && (pdu[1] == 1)) { + sched_ctl->round[CC_idP][harq_pid] = 8; + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + } + if ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) + && (pdu[0] == 2) && (pdu[1] == 2)) { + sched_ctl->round[CC_idP][harq_pid]++; + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + } + } + else if (((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[0][harq_pid] == 2) + && (pdu[0] == 1) && (pdu[1] == 2)) + || ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) + && (pdu[0] == 2) && (pdu[1] == 1))) { + sched_ctl->round[CC_idP][harq_pid]++; + sched_ctl->tbcnt[CC_idP][harq_pid] = 1; + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; /* TODO: do we have to set it to 0? */ + } + } else if ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) + && (pdu[0] == 2) && (pdu[1] == 2)) { + sched_ctl->round[CC_idP][harq_pid]++; + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + } + } + else + AssertFatal(1 == 0, + "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", + num_ack_nak, + sched_ctl->round[CC_idP][harq_pid], + sched_ctl->round[CC_idP][harq_pid], pdu[0], + pdu[1], harq_pid, UE_id, rnti); + } + break; + case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells + AssertFatal(numCC == 2, + "Should not receive harq indication with channel selection with %d active CCs\n", + numCC); + + if ((num_ack_nak == 2) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 1) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + if (pdu[0] == 1) + sched_ctl->round[pCCid][harq_pid] = 8; + else { + sched_ctl->round[pCCid][harq_pid]++; + if (sched_ctl->round[pCCid][harq_pid] == 4) + sched_ctl->round[pCCid][harq_pid] = 8; + } + if (pdu[1] == 1) + sched_ctl->round[1 - pCCid][harq_pid] = 8; + else { + sched_ctl->round[1 - pCCid][harq_pid]++; + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) + sched_ctl->round[1 - pCCid][harq_pid] = 8; + } + } // A=2 + else if ((num_ack_nak == 3) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 2) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2, + "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", + pCCid, harq_pid, UE_id, rnti); + AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1, + "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", + 1 - pCCid, harq_pid, UE_id, rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[pCCid][harq_pid] = 8; + sched_ctl->tbcnt[pCCid][harq_pid] = 0; + } else if (((pdu[0] == 2) && (pdu[1] == 1)) || + ((pdu[0] == 1) && (pdu[1] == 2))) { + sched_ctl->round[pCCid][harq_pid]++; + sched_ctl->tbcnt[pCCid][harq_pid] = 1; + if (sched_ctl->round[pCCid][harq_pid] == 4) { + sched_ctl->round[pCCid][harq_pid] = 8; + sched_ctl->tbcnt[pCCid][harq_pid] = 0; /* TODO: do we have to set it to 0? */ + } + } else { + sched_ctl->round[pCCid][harq_pid]++; + if (sched_ctl->round[pCCid][harq_pid] == 4) { + sched_ctl->round[pCCid][harq_pid] = 8; + sched_ctl->tbcnt[pCCid][harq_pid] = 0; } } - if (pdu[0] == 1) { // ACK - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - } else if (pdu[0] == 2 || pdu[0] == 4){ // NAK (treat DTX as NAK) - sched_ctl->round[CC_idP][harq_pid]++; // increment round - if(sched_ctl->round[CC_idP][harq_pid] == 8){ - for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){ - //Msg NACK num to MAC ,remove UE - // add UE info to freeList - LOG_I(RRC, "put UE %x into freeList\n", rnti); - put_UE_in_freelist(mod_idP, rnti, 1); - } - } - } - } - } else { - // one or two ACK/NAK bits - AssertFatal(num_ack_nak > 2, - "num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n", - num_ack_nak); - if ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) - && (pdu[0] == 1) && (pdu[1] == 1)) { - sched_ctl->round[CC_idP][harq_pid] = 8; - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - } - if ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) - && (pdu[0] == 2) && (pdu[1] == 2)) - sched_ctl->round[CC_idP][harq_pid]++; - else if (((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[0][harq_pid] == 2) - && (pdu[0] == 1) && (pdu[1] == 2)) - || ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) - && (pdu[0] == 2) && (pdu[1] == 1))) { - sched_ctl->round[CC_idP][harq_pid]++; - sched_ctl->tbcnt[CC_idP][harq_pid] = 1; - } else if ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) - && (pdu[0] == 2) && (pdu[1] == 2)) - sched_ctl->round[CC_idP][harq_pid]++; - else - AssertFatal(1 == 0, - "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", - num_ack_nak, - sched_ctl->round[CC_idP][harq_pid], - sched_ctl->round[CC_idP][harq_pid], pdu[0], - pdu[1], harq_pid, UE_id, rnti); - } - break; - case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells - AssertFatal(numCC == 2, - "Should not receive harq indication with channel selection with %d active CCs\n", - numCC); - - if ((num_ack_nak == 2) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 1) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - if (pdu[0] == 1) - sched_ctl->round[pCCid][harq_pid] = 8; - else - sched_ctl->round[pCCid][harq_pid]++; - if (pdu[1] == 1) - sched_ctl->round[1 - pCCid][harq_pid] = 8; - else - sched_ctl->round[1 - pCCid][harq_pid]++; - } // A=2 - else if ((num_ack_nak == 3) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 2) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2, - "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", - pCCid, harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1, - "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", - 1 - pCCid, harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[pCCid][harq_pid] = 8; - sched_ctl->tbcnt[pCCid][harq_pid] = 0; - } else if (((pdu[0] == 2) && (pdu[1] == 1)) || - ((pdu[0] == 1) && (pdu[1] == 2))) { - sched_ctl->round[pCCid][harq_pid]++; - sched_ctl->tbcnt[pCCid][harq_pid] = 1; - } else - sched_ctl->round[pCCid][harq_pid]++; - - if (pdu[2] == 1) - sched_ctl->round[1 - pCCid][harq_pid] = 8; - else - sched_ctl->round[1 - pCCid][harq_pid]++; - } // A=3 primary cell has 2 TBs - else if ((num_ack_nak == 3) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2, - "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", - 1 - pCCid, harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1, - "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", - pCCid, harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[1 - pCCid][harq_pid] = 8; - sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; - } else if (((pdu[0] >= 2) && (pdu[1] == 1)) - || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK - sched_ctl->round[1 - pCCid][harq_pid]++; - sched_ctl->tbcnt[1 - pCCid][harq_pid] = 1; - } else // both NAK/DTX - sched_ctl->round[1 - pCCid][harq_pid]++; - - if (pdu[2] == 1) - sched_ctl->round[pCCid][harq_pid] = 8; - else - sched_ctl->round[pCCid][harq_pid]++; - } // A=3 secondary cell has 2 TBs + if (pdu[2] == 1) + sched_ctl->round[1 - pCCid][harq_pid] = 8; + else { + sched_ctl->round[1 - pCCid][harq_pid]++; + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { + sched_ctl->round[1 - pCCid][harq_pid] = 8; + } + } + } // A=3 primary cell has 2 TBs + else if ((num_ack_nak == 3) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2, + "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", + 1 - pCCid, harq_pid, UE_id, rnti); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1, + "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", + pCCid, harq_pid, UE_id, rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[1 - pCCid][harq_pid] = 8; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } else if (((pdu[0] >= 2) && (pdu[1] == 1)) + || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK + sched_ctl->round[1 - pCCid][harq_pid]++; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 1; + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { + sched_ctl->round[1 - pCCid][harq_pid] = 8; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } + } else { // both NAK/DTX + sched_ctl->round[1 - pCCid][harq_pid]++; + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { + sched_ctl->round[1 - pCCid][harq_pid] = 8; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } + } + + if (pdu[2] == 1) + sched_ctl->round[pCCid][harq_pid] = 8; + else { + sched_ctl->round[pCCid][harq_pid]++; + if (sched_ctl->round[pCCid][harq_pid] == 4) { + sched_ctl->round[pCCid][harq_pid] = 8; + } + } + } // A=3 secondary cell has 2 TBs #if MAX_NUM_CCs>1 - else if ((num_ack_nak == 4) - && (sched_ctl->round[0][harq_pid] < 8) - && (sched_ctl->round[1][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 2)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(pdu[3] <= 3, "pdu[3] %d is not ACK/NAK/DTX\n", - pdu[3]); - AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2, - "sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n", - harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2, - "sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n", - harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[0][harq_pid] = 8; - sched_ctl->tbcnt[0][harq_pid] = 0; - } else if (((pdu[0] >= 2) && (pdu[1] == 1)) - || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK - sched_ctl->round[0][harq_pid]++; - sched_ctl->tbcnt[0][harq_pid] = 1; - } else // both NAK/DTX - sched_ctl->round[0][harq_pid]++; - - if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK - sched_ctl->round[1][harq_pid] = 8; - sched_ctl->tbcnt[1][harq_pid] = 0; - } else if (((pdu[2] >= 2) && (pdu[3] == 1)) - || ((pdu[2] == 1) && (pdu[3] >= 2))) { // one ACK - sched_ctl->round[1][harq_pid]++; - sched_ctl->tbcnt[1][harq_pid] = 1; - } else // both NAK/DTX - sched_ctl->round[1][harq_pid]++; - } // A=4 both serving cells have 2 TBs + else if ((num_ack_nak == 4) + && (sched_ctl->round[0][harq_pid] < 8) + && (sched_ctl->round[1][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 2)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(pdu[3] <= 3, "pdu[3] %d is not ACK/NAK/DTX\n", + pdu[3]); + AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2, + "sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n", + harq_pid, UE_id, rnti); + AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2, + "sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n", + harq_pid, UE_id, rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[0][harq_pid] = 8; + sched_ctl->tbcnt[0][harq_pid] = 0; + } else if (((pdu[0] >= 2) && (pdu[1] == 1)) + || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK + sched_ctl->round[0][harq_pid]++; + sched_ctl->tbcnt[0][harq_pid] = 1; + if (sched_ctl->round[0][harq_pid] == 4) { + sched_ctl->round[0][harq_pid] = 8; + sched_ctl->tbcnt[0][harq_pid] = 0; + } + } else { // both NAK/DTX + sched_ctl->round[0][harq_pid]++; + if (sched_ctl->round[0][harq_pid] == 4) { + sched_ctl->round[0][harq_pid] = 8; + sched_ctl->tbcnt[0][harq_pid] = 0; + } + } + + if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK + sched_ctl->round[1][harq_pid] = 8; + sched_ctl->tbcnt[1][harq_pid] = 0; + } else if (((pdu[2] >= 2) && (pdu[3] == 1)) + || ((pdu[2] == 1) && (pdu[3] >= 2))) { // one ACK + sched_ctl->round[1][harq_pid]++; + sched_ctl->tbcnt[1][harq_pid] = 1; + if (sched_ctl->round[1][harq_pid] == 4) { + sched_ctl->round[1][harq_pid] = 8; + sched_ctl->tbcnt[1][harq_pid] = 0; + } + } else { // both NAK/DTX + sched_ctl->round[1][harq_pid]++; + if (sched_ctl->round[1][harq_pid] == 4) { + sched_ctl->round[1][harq_pid] = 8; + sched_ctl->tbcnt[1][harq_pid] = 0; + } + } + } // A=4 both serving cells have 2 TBs #endif - break; - case 2: // Format 3 - AssertFatal(numCC > 2, - "Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n", - numCC); - for (i = 0, j = 0; i < numCC; i++) { - if ((sched_ctl->round[i][harq_pid] < 8)) { - if (tmode[i] == 1 || tmode[i] == 2 || tmode[0] == 5 - || tmode[0] == 6 || tmode[0] == 7) { - if (pdu[j] == 1) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if (pdu[j] == 2) - sched_ctl->round[i][harq_pid]++; - else - AssertFatal(1 == 0, - "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", - i, harq_pid, pdu[j], UE_id, rnti); - j++; - } else if (spatial_bundling == 0) { - if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 1) && (pdu[j + 1] == 1)) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 1) && (pdu[j + 1] == 2)) { - sched_ctl->round[i][harq_pid]++; - sched_ctl->tbcnt[i][harq_pid] = 1; - } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 2) && (pdu[j + 1] == 1)) { - sched_ctl->round[i][harq_pid]++; - sched_ctl->tbcnt[i][harq_pid] = 1; - } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 2) && (pdu[j + 1] == 2)) { - sched_ctl->round[i][harq_pid]++; - } else - AssertFatal(1 == 0, - "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", - i, harq_pid, - sched_ctl->tbcnt[i][harq_pid], - pdu[j], pdu[j + 1], UE_id, rnti); - j += 2; - } else if (spatial_bundling == 1) { - if (pdu[j] == 1) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if (pdu[j] == 2) { - sched_ctl->round[i][harq_pid]++; - } else - AssertFatal(1 == 0, - "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", - pdu[j], i, harq_pid, UE_id, rnti); - j++; - } else - AssertFatal(1 == 0, - "Illegal value for spatial_bundling %d\n", - spatial_bundling); - } - } - break; - case 3: // Format 4 - AssertFatal(1 == 0, - "Should not receive harq indication with Format 4\n"); - break; - case 4: // Format 5 + break; + case 2: // Format 3 + AssertFatal(numCC > 2, + "Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n", + numCC); + for (i = 0, j = 0; i < numCC; i++) { + if ((sched_ctl->round[i][harq_pid] < 8)) { + if (tmode[i] == 1 || tmode[i] == 2 || tmode[0] == 5 + || tmode[0] == 6 || tmode[0] == 7) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if (pdu[j] == 2) { + sched_ctl->round[i][harq_pid]++; + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } + else + AssertFatal(1 == 0, + "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", + i, harq_pid, pdu[j], UE_id, rnti); + j++; + } else if (spatial_bundling == 0) { + if ((sched_ctl->tbcnt[i][harq_pid] == 2) + && (pdu[j] == 1) && (pdu[j + 1] == 1)) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) + && (pdu[j] == 1) && (pdu[j + 1] == 2)) { + sched_ctl->round[i][harq_pid]++; + sched_ctl->tbcnt[i][harq_pid] = 1; + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) + && (pdu[j] == 2) && (pdu[j + 1] == 1)) { + sched_ctl->round[i][harq_pid]++; + sched_ctl->tbcnt[i][harq_pid] = 1; + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) + && (pdu[j] == 2) && (pdu[j + 1] == 2)) { + sched_ctl->round[i][harq_pid]++; + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else + AssertFatal(1 == 0, + "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", + i, harq_pid, + sched_ctl->tbcnt[i][harq_pid], + pdu[j], pdu[j + 1], UE_id, rnti); + j += 2; + } else if (spatial_bundling == 1) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if (pdu[j] == 2) { + sched_ctl->round[i][harq_pid]++; + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else + AssertFatal(1 == 0, + "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", + pdu[j], i, harq_pid, UE_id, rnti); + j++; + } else AssertFatal(1 == 0, - "Should not receive harq indication with Format 5\n"); - break; + "Illegal value for spatial_bundling %d\n", + spatial_bundling); } + } + break; + case 3: // Format 4 + AssertFatal(1 == 0, + "Should not receive harq indication with Format 4\n"); + break; + case 4: // Format 5 + AssertFatal(1 == 0, + "Should not receive harq indication with Format 5\n"); + break; } + } } void @@ -4226,129 +3867,106 @@ extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, frame_t frameP, sub_frame_t subframeP, uint8_t * pdu, uint8_t length) { - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - struct CQI_ReportPeriodic *cqi_ReportPeriodic; - int no_pmi; - uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 }; - uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; - int feedback_cnt; - - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", UE_id); - AssertFatal(UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig != NULL, - "cqi_ReportConfig is null for UE %d\n", UE_id); - AssertFatal((cqi_ReportPeriodic = - UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportPeriodic) != NULL, - "cqi_ReportPeriodic is null for UE %d\n", UE_id); - - // determine feedback mode - AssertFatal(cqi_ReportPeriodic->present != - CQI_ReportPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); - AssertFatal(cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present != - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); - - uint16_t Npd, N_OFFSET_CQI; - int H, K, bandwidth_part, L, Lmask; - int ri = sched_ctl->periodic_ri_received[CC_idP]; - - get_csi_params(cc, cqi_ReportPeriodic, &Npd, &N_OFFSET_CQI, &H); - K = (H - 1) / Jtab[cc->mib->message.dl_Bandwidth]; - L = Ltab[cc->mib->message.dl_Bandwidth]; - Lmask = L - 1; - feedback_cnt = (((frameP * 10) + subframeP) / Npd) % H; - - if (feedback_cnt > 0) - bandwidth_part = (feedback_cnt - 1) % K; - else - bandwidth_part = 0; - - switch (get_tmode(mod_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 3: - case 7: - no_pmi = 1; - break; - case 4: - case 5: - case 6: - no_pmi = 0; - break; - default: - // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213) - no_pmi = 0; - } + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + struct CQI_ReportPeriodic *cqi_ReportPeriodic; + int no_pmi; + uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 }; + uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; + int feedback_cnt; + + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", UE_id); + AssertFatal(UE_list-> + UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, + "cqi_ReportConfig is null for UE %d\n", UE_id); + AssertFatal((cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL, + "cqi_ReportPeriodic is null for UE %d\n", UE_id); + + // determine feedback mode + AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + + uint16_t Npd, N_OFFSET_CQI; + int H, K, bandwidth_part, L, Lmask; + int ri = sched_ctl->periodic_ri_received[CC_idP]; + + get_csi_params(cc, cqi_ReportPeriodic, &Npd, &N_OFFSET_CQI, &H); + K = (H - 1) / Jtab[cc->mib->message.dl_Bandwidth]; + L = Ltab[cc->mib->message.dl_Bandwidth]; + Lmask = L - 1; + feedback_cnt = (((frameP * 10) + subframeP) / Npd) % H; + + if (feedback_cnt > 0) + bandwidth_part = (feedback_cnt - 1) % K; + else + bandwidth_part = 0; + + switch (get_tmode(mod_idP, CC_idP, UE_id)) { + case 1: + case 2: + case 3: + case 7: + no_pmi = 1; + break; + case 4: + case 5: + case 6: + no_pmi = 0; + break; + default: + // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213) + no_pmi = 0; + } - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. - present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) - || (feedback_cnt == 0)) { - // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI) - - if (no_pmi == 1) { // get spatial_diffcqi if needed - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; - } else if ((cc->p_eNB == 2) && (ri == 1)) { - // p=2 Rank 1 wideband CQI/PMI 6 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 4) & 3; - } else if ((cc->p_eNB == 2) && (ri > 1)) { - // p=2 Rank 2 wideband CQI/PMI 8 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; - sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 1; - } else if ((cc->p_eNB == 4) && (ri == 1)) { - // p=4 Rank 1 wideband CQI/PMI 8 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_pmi[CC_idP] = - (pdu[0] >> 4) & 0x0F; - - } else if ((cc->p_eNB == 4) && (ri > 1)) { - // p=4 Rank 2 wideband CQI/PMI 11 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; - sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 0xF; - } else - AssertFatal(1 == 0, - "illegal combination p %d, ri %d, no_pmi %d\n", - cc->p_eNB, ri, no_pmi); - } else if (cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) + || (feedback_cnt == 0)) { + // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI) + + if (no_pmi == 1) { // get spatial_diffcqi if needed + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = + (pdu[0] >> 4) & 7; + } else if ((cc->p_eNB == 2) && (ri == 1)) { + // p=2 Rank 1 wideband CQI/PMI 6 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 4) & 3; + } else if ((cc->p_eNB == 2) && (ri > 1)) { + // p=2 Rank 2 wideband CQI/PMI 8 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = + (pdu[0] >> 4) & 7; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 1; + } else if ((cc->p_eNB == 4) && (ri == 1)) { + // p=4 Rank 1 wideband CQI/PMI 8 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_pmi[CC_idP] = + (pdu[0] >> 4) & 0x0F; + } else if ((cc->p_eNB == 4) && (ri > 1)) { + // p=4 Rank 2 wideband CQI/PMI 11 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = + (pdu[0] >> 4) & 7; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 0xF; + } else + AssertFatal(1 == 0, + "illegal combination p %d, ri %d, no_pmi %d\n", + cc->p_eNB, ri, no_pmi); + } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { - // This is Table 5.2.3.3.2-2 for 36.213 - if (ri == 1) { - //4+Ltab[cc->mib->message.dl_Bandwidth] bits - sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + - ((pdu[0] >> 4) & - Lmask)] = - pdu[0] & 0xF; - } else if (ri > 1) { - //7+Ltab[cc->mib->message.dl_Bandwidth] bits; - sched_ctl-> - periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part * - L) + - ((pdu[0] >> 7) & - Lmask)] = - (pdu[0] >> 4) & 7; - sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + - ((pdu[0] >> 7) & - Lmask)] = - pdu[0] & 0xF; - } + // This is Table 5.2.3.3.2-2 for 36.213 + if (ri == 1) { + //4+Ltab[cc->mib->message.dl_Bandwidth] bits + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) +((pdu[0] >> 4) & Lmask)] = pdu[0] & 0xF; + } else if (ri > 1) { + //7+Ltab[cc->mib->message.dl_Bandwidth] bits; + sched_ctl->periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = (pdu[0] >> 4) & 7; + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = + pdu[0] & 0xF; + } } } @@ -4357,278 +3975,265 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, frame_t frameP, sub_frame_t subframeP, uint8_t * pdu, uint8_t length) { - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; - int Ntab_uesel[6] = { 0, 8, 13, 17, 19, 25 }; - int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; - int Mtab_uesel[6] = { 0, 1, 3, 5, 6, 6 }; - int v[6]; - int i; - uint64_t p = *(uint64_t *) pdu; - int curbyte, curbit; - CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; - - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", UE_id); - AssertFatal(UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig != NULL, - "cqi_ReportConfig is null for UE %d\n", UE_id); - AssertFatal((cqi_ReportModeAperiodic = - UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportModeAperiodic) != NULL, - "cqi_ReportModeAperiodic is null for UE %d\n", UE_id); - - int N = Ntab[cc->mib->message.dl_Bandwidth]; - int tmode = get_tmode(mod_idP, CC_idP, UE_id); - int ri = sched_ctl->aperiodic_ri_received[CC_idP]; - int r, diffcqi0 = 0, diffcqi1 = 0, pmi_uesel = 0; - int bw = cc->mib->message.dl_Bandwidth; - int m; - - switch (*cqi_ReportModeAperiodic) { - case CQI_ReportModeAperiodic_rm12: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n", - tmode); - if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 - if ((ri == 1) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; - } - } - if ((ri == 2) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - } - if ((ri == 1) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 4; - } - } - if ((ri == 2) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 4; - } - } - } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 - else { - AssertFatal(1 == 0, "support for TM 8-10 to be done\n"); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; + int Ntab_uesel[6] = { 0, 8, 13, 17, 19, 25 }; + int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; + int Mtab_uesel[6] = { 0, 1, 3, 5, 6, 6 }; + int v[6]; + int i; + uint64_t p = *(uint64_t *) pdu; + int curbyte, curbit; + CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; + + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, + "cqi_ReportConfig is null for UE %d\n", UE_id); + AssertFatal((cqi_ReportModeAperiodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) != NULL, + "cqi_ReportModeAperiodic is null for UE %d\n", UE_id); + + int N = Ntab[cc->mib->message.dl_Bandwidth]; + int tmode = get_tmode(mod_idP, CC_idP, UE_id); + int ri = sched_ctl->aperiodic_ri_received[CC_idP]; + int r, diffcqi0 = 0, diffcqi1 = 0, pmi_uesel = 0; + int bw = cc->mib->message.dl_Bandwidth; + int m; + + switch (*cqi_ReportModeAperiodic) { + case CQI_ReportModeAperiodic_rm12: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n", + tmode); + if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + if ((ri == 1) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 2; } - - break; - case CQI_ReportModeAperiodic_rm20: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n", - tmode); - - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + } + if ((ri == 2) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); p >>= 4; - diffcqi0 = (uint8_t) (p & 0x03); - p >>= 2; - r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); - reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); - for (m = 0; m < Mtab_uesel[bw]; m++) - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; - break; - case CQI_ReportModeAperiodic_rm22: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 - - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n", - tmode); - - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); p >>= 4; - diffcqi0 = (uint8_t) (p & 0x03); - p >>= 2; - - if (ri > 1) { - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - diffcqi1 = (uint8_t) (p & 0x03); - p >>= 2; - } - r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); - p >>= Ltab_uesel[bw]; - reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); - if ((ri == 1) && (cc->p_eNB == 2)) { - pmi_uesel = p & 0x3; - p >>= 2; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x3; - } else if ((ri == 2) && (cc->p_eNB == 2)) { - pmi_uesel = p & 0x1; - p >>= 1; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x1; - } else if (cc->p_eNB == 4) { - pmi_uesel = p & 0x0F; - p >>= 4; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; - } - for (m = 0; m < Mtab_uesel[bw]; m++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; - if (ri > 1) - sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = - diffcqi1; - sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; - } - break; - case CQI_ReportModeAperiodic_rm30: - //subband CQI no PMI (TM1/2/3/7) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n", - tmode); - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = pdu[0] >> 4; - curbyte = 0; - curbit = 3; for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (pdu[curbyte] >> (curbit - 1)) & 0x03; - curbit -= 2; - if (curbit < 0) { - curbit = 7; - curbyte++; - } + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 1; } - sched_ctl->dl_cqi[CC_idP] = - sched_ctl->aperiodic_wideband_cqi0[CC_idP]; - break; - case CQI_ReportModeAperiodic_rm31: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - //subband CQI single PMI (TM4/5/6) - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n", - tmode); - - if ((ri == 1) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x03; - } - if ((ri == 2) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x01; - } - if ((ri == 1) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + if ((ri == 1) && (cc->p_eNB == 4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 4; } - if ((ri > 1) && (cc->p_eNB == 4)) { // Note : 64 bits for 20 MHz - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 2; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + if ((ri == 2) && (cc->p_eNB == 4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 4; } + } + } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + else { + AssertFatal(1 == 0, "support for TM 8-10 to be done\n"); + } - break; - case CQI_ReportModeAperiodic_rm32_v1250: - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32 to be done\n"); - break; - case CQI_ReportModeAperiodic_rm10_v1310: - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm10 to be done\n"); - break; - case CQI_ReportModeAperiodic_rm11_v1310: - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); - break; + break; + case CQI_ReportModeAperiodic_rm20: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 + || tmode == 7, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n", + tmode); + + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + diffcqi0 = (uint8_t) (p & 0x03); + p >>= 2; + r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); + reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); + for (m = 0; m < Mtab_uesel[bw]; m++) + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; + break; + case CQI_ReportModeAperiodic_rm22: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 + + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n", + tmode); + + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + diffcqi0 = (uint8_t) (p & 0x03); + p >>= 2; + + if (ri > 1) { + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + diffcqi1 = (uint8_t) (p & 0x03); + p >>= 2; + } + r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); + p >>= Ltab_uesel[bw]; + reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); + if ((ri == 1) && (cc->p_eNB == 2)) { + pmi_uesel = p & 0x3; + p >>= 2; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x3; + } else if ((ri == 2) && (cc->p_eNB == 2)) { + pmi_uesel = p & 0x1; + p >>= 1; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x1; + } else if (cc->p_eNB == 4) { + pmi_uesel = p & 0x0F; + p >>= 4; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + for (m = 0; m < Mtab_uesel[bw]; m++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; + if (ri > 1) + sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = + diffcqi1; + sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; + } + break; + case CQI_ReportModeAperiodic_rm30: + //subband CQI no PMI (TM1/2/3/7) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 + || tmode == 7, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n", + tmode); + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = pdu[0] >> 4; + curbyte = 0; + curbit = 3; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = + (pdu[curbyte] >> (curbit - 1)) & 0x03; + curbit -= 2; + if (curbit < 0) { + curbit = 7; + curbyte++; + } } + sched_ctl->dl_cqi[CC_idP] = + sched_ctl->aperiodic_wideband_cqi0[CC_idP]; + break; + case CQI_ReportModeAperiodic_rm31: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + //subband CQI single PMI (TM4/5/6) + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 + || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n", + tmode); + + if ((ri == 1) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = + (uint8_t) (p & 0x03); + p >>= 2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x03; + } + if ((ri == 2) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 1; + } + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 1; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x01; + } + if ((ri == 1) && (cc->p_eNB == 4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = + (uint8_t) (p & 0x03); + p >>= 2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + if ((ri > 1) && (cc->p_eNB == 4)) { // Note : 64 bits for 20 MHz + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 1; + } + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + + break; +#if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) + case CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 + || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32 to be done\n"); + break; +#endif +#if (RRC_VERSION >= MAKE_VERSION(13, 1, 0)) + case CQI_ReportModeAperiodic_rm10_v1310: + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 + || tmode == 7, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm10 to be done\n"); + break; + case CQI_ReportModeAperiodic_rm11_v1310: + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 + || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); + break; +#endif /* #if (RRC_VERSION >= MAKE_VERSION(13, 1, 0)) */ + } } void @@ -4637,106 +4242,124 @@ cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, nfapi_cqi_indication_rel9_t * rel9, uint8_t * pdu, nfapi_ul_cqi_information_t * ul_cqi_information) { - int UE_id = find_UE_id(mod_idP, rntiP); - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - if (UE_id == -1) { - LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP); - return; - } - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - if (UE_id >= 0) { + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + if (UE_id == -1) { + LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP); + return; + } + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", __FUNCTION__, UE_id, ul_cqi_information->channel, ul_cqi_information->ul_cqi); + if (UE_id >= 0) { - if (ul_cqi_information->channel == 0) { // PUCCH + LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", __FUNCTION__, UE_id, ul_cqi_information->channel, ul_cqi_information->ul_cqi); - // extract pucch csi information before changing RI information - extract_pucch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, - pdu, rel9->length); + if (ul_cqi_information->channel == 0) { // PUCCH - memcpy((void *) sched_ctl->periodic_ri_received, - (void *) rel9->ri, rel9->number_of_cc_reported); + // extract pucch csi information before changing RI information + extract_pucch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, + pdu, rel9->length); - // SNR for PUCCH2 - sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi; - } else { //PUSCH - memcpy((void *) sched_ctl->aperiodic_ri_received, - (void *) rel9->ri, rel9->number_of_cc_reported); + memcpy((void *) sched_ctl->periodic_ri_received, + (void *) rel9->ri, rel9->number_of_cc_reported); - extract_pusch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, - pdu, rel9->length); + // SNR for PUCCH2 + sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi; + } else { //PUSCH + memcpy((void *) sched_ctl->aperiodic_ri_received, + (void *) rel9->ri, rel9->number_of_cc_reported); - LOG_D(MAC,"Frame %d Subframe %d update CQI:%d\n",frameP,subframeP,sched_ctl->dl_cqi[CC_idP]); - } + extract_pusch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, + pdu, rel9->length); - // timing advance - sched_ctl->timing_advance = rel9->timing_advance; - sched_ctl->timing_advance_r9 = rel9->timing_advance_r9; + LOG_D(MAC,"Frame %d Subframe %d update CQI:%d\n",frameP,subframeP,sched_ctl->dl_cqi[CC_idP]); } + + // timing advance + sched_ctl->timing_advance = rel9->timing_advance; + sched_ctl->timing_advance_r9 = rel9->timing_advance_r9; + } } void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, uint8_t ul_cqi) { - T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), - T_INT(frameP), T_INT(subframeP), T_INT(rntiP)); + T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), + T_INT(frameP), T_INT(subframeP), T_INT(rntiP)); - int UE_id = find_UE_id(mod_idP, rntiP); - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - if (UE_id != -1) { - if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < - RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + if (UE_id != -1) { + if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < + RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", + mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); #if 0 - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - /* for the moment don't use ul_cqi from SR, value is too different from harq */ - sched_ctl->pucch1_snr[cc_idP] = ul_cqi; - sched_ctl->pucch1_cqi_update[cc_idP] = 1; + /* for the moment don't use ul_cqi from SR, value is too different from harq */ + sched_ctl->pucch1_snr[cc_idP] = ul_cqi; + sched_ctl->pucch1_cqi_update[cc_idP] = 1; #endif - UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; - UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); - } else { - // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); - // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_D(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); - } + UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; + UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); + } else { + // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); + // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); + LOG_D(MAC, + "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n", + mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + } } void UL_failure_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) { - int UE_id = find_UE_id(mod_idP, rntiP); - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n", - mod_idP, UE_id, rntiP, frameP, subframeP, UE_id, cc_idP, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; - } else { - // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); - // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_W(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); - } + if (UE_id != -1) { + LOG_D(MAC, + "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n", + mod_idP, UE_id, rntiP, frameP, subframeP, UE_id, cc_idP, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0) + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + } else { + // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); + // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); + LOG_W(MAC, + "[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n", + mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + } +} + +static int nack_or_dtx_reported( + COMMON_channels_t *cc, + nfapi_harq_indication_pdu_t *harq_pdu) +{ + int i; + + if (cc->tdd_Config) { + AssertFatal(0==1, "TDD to be done. FAPI structures (see nfapi_harq_indication_tdd_rel13_t) are not clean. To be cleaned as well?\n"); + abort(); + } else { + nfapi_harq_indication_fdd_rel13_t *hi = &harq_pdu->harq_indication_fdd_rel13; + for (i = 0; i < hi->number_of_ack_nack; hi++) + if (hi->harq_tb_n[i] != 1) + return 1; + return 0; + } } void @@ -4744,31 +4367,51 @@ harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, nfapi_harq_indication_pdu_t * harq_pdu) { - rnti_t rnti = harq_pdu->rx_ue_information.rnti; - uint8_t ul_cqi = harq_pdu->ul_cqi_information.ul_cqi; - uint8_t channel = harq_pdu->ul_cqi_information.channel; - int UE_id = find_UE_id(mod_idP, rnti); - if (UE_id == -1) { - LOG_W(MAC, "harq_indication: UE %x not found\n", rnti); - return; - } - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - // extract HARQ Information - LOG_D(MAC, - "Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n", - frameP, subframeP, channel, UE_id, rnti, ul_cqi); - if (cc->tdd_Config) - extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, - (void *) &harq_pdu->harq_indication_tdd_rel13, - channel); - else - extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, - (void *) &harq_pdu->harq_indication_fdd_rel13, - channel); - if (channel == 0) { - sched_ctl->pucch1_snr[CC_idP] = ul_cqi; - sched_ctl->pucch1_cqi_update[CC_idP] = 1; - } + rnti_t rnti = harq_pdu->rx_ue_information.rnti; + uint8_t ul_cqi = harq_pdu->ul_cqi_information.ul_cqi; + uint8_t channel = harq_pdu->ul_cqi_information.channel; + int UE_id = find_UE_id(mod_idP, rnti); + if (UE_id == -1) { + LOG_W(MAC, "harq_indication: UE %x not found\n", rnti); + return; + } + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + // extract HARQ Information + LOG_D(MAC, + "Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n", + frameP, subframeP, channel, UE_id, rnti, ul_cqi); + if (cc->tdd_Config) + extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, + (void *) &harq_pdu->harq_indication_tdd_rel13, + channel); + else + extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, + (void *) &harq_pdu->harq_indication_fdd_rel13, + channel); + /* don't care about cqi reporting if NACK/DTX is there */ + if (channel == 0 && !nack_or_dtx_reported(cc, harq_pdu)) { + sched_ctl->pucch1_snr[CC_idP] = ul_cqi; + sched_ctl->pucch1_cqi_update[CC_idP] = 1; + } +} + +// Flexran Slicing functions + +uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) +{ + return (uint16_t) floor(rb_percentage * total_rbs); +} + +int ue_slice_membership(int UE_id, int slice_id) +{ + if ((slice_id < 0) || (slice_id > n_active_slices)) + LOG_W(MAC, "out of range slice id %d\n", slice_id); + + + if ((UE_id % n_active_slices) == slice_id) { + return 1; // this ue is a member of this slice + } + return 0; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index dd6810d075a275127d5251589fd8e5f627c932e6..4b8d4188b45c9cf8ebc25a368ac817a698fbcb1c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -31,25 +31,22 @@ /* indented with: indent -kr eNB_scheduler_RA.c */ -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "assertions.h" //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" @@ -57,6 +54,13 @@ #include "intertask_interface.h" #endif +#include "ENB_APP/flexran_agent_defs.h" +#include "flexran_agent_ran_api.h" +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "flexran_agent_mac.h" +#include <dlfcn.h> + #include "T.h" #define ENABLE_MAC_PAYLOAD_DEBUG @@ -72,11 +76,42 @@ extern uint8_t nfapi_mode; // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[34] = - { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, - 36, 40, 45, 48, 50, 54, 60, 72, 75, 80, 81, 90, 96, 100, 100 + { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, + 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 + }; + +/* number of active slices for past and current time*/ +int n_active_slices_uplink = 1; +int n_active_slices_current_uplink = 1; + +/* RB share for each slice for past and current time*/ +float avg_slice_percentage_uplink=0.25; +float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float total_slice_percentage_uplink = 0; +float total_slice_percentage_current_uplink = 0; + +// MAX MCS for each slice for past and current time +int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20}; +int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20}; + +/*resource blocks allowed*/ +uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; +/*Slice Update */ +int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; +int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; + +/* name of available scheduler*/ +char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti", + "schedule_ulsch_rnti", + "schedule_ulsch_rnti", + "schedule_ulsch_rnti" }; extern mui_t rrc_eNB_mui; +/* Slice Function Pointer */ +slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; + void rx_sdu(const module_id_t enb_mod_idP, const int CC_idP, @@ -87,97 +122,101 @@ rx_sdu(const module_id_t enb_mod_idP, const uint16_t sdu_lenP, const uint16_t timing_advance, const uint8_t ul_cqi) { - int current_rnti = rntiP; - unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - unsigned short rx_lengths[NB_RB_MAX]; - int UE_id = find_UE_id(enb_mod_idP, current_rnti); - int RA_id; - int ii, j; - eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; - int harq_pid = - subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); - - UE_list_t *UE_list = &mac->UE_list; - int crnti_rx = 0; - int old_buffer_info; - RA_t *ra = - (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; - int first_rb = 0; - - start_meas(&mac->rx_ulsch_sdu); - - if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1)) - for (ii = 0; ii < NB_RB_MAX; ii++) { - rx_lengths[ii] = 0; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); - if (opt_enabled == 1) { - trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP, - 0, 0); - LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", - enb_mod_idP, frameP, current_rnti, sdu_lenP); + int current_rnti = rntiP; + unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; + int UE_id = find_UE_id(enb_mod_idP, current_rnti); + int RA_id; + int ii, j; + eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; + int harq_pid = + subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + int lcgid_updated[4] = {0, 0, 0, 0}; + + UE_list_t *UE_list = &mac->UE_list; + int crnti_rx = 0; + RA_t *ra = + (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; + int first_rb = 0; + + start_meas(&mac->rx_ulsch_sdu); + + if ((UE_id > MAX_MOBILES_PER_ENB) || (UE_id == -1)) + for (ii = 0; ii < NB_RB_MAX; ii++) { + rx_lengths[ii] = 0; } - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - current_rnti, UE_id, ul_cqi); - - AssertFatal(UE_list->UE_sched_ctrl[UE_id]. - round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); - if (sduP != NULL) { - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) { - LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d clear to 0\n", UE_id, rntiP, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - } - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= - (~(1 << harq_pid)); - /* Update with smoothing: 3/4 of old value and 1/4 of new. - * This is the logic that was done in the function - * lte_est_timing_advance_pusch, maybe it's not necessary? - * maybe it's even not correct at all? - */ - UE_list->UE_sched_ctrl[UE_id].ta_update = - (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + - timing_advance) / 4; - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; - UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; - first_rb = - UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; - - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, UE_RNTI(enb_mod_idP, - UE_id)); - } - } else { // we've got an error - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - ul_cqi); - - if(ul_cqi>200){ // too high energy pattern - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; - } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); + if (opt_enabled == 1) { + trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP, + 0, 0); + LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", + enb_mod_idP, frameP, current_rnti, sdu_lenP); + } + + if (UE_id != -1) { + LOG_D(MAC, + "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + current_rnti, UE_id, ul_cqi); + + AssertFatal(UE_list->UE_sched_ctrl[UE_id]. + round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + if (sduP != NULL) { + UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + /* Update with smoothing: 3/4 of old value and 1/4 of new. + * This is the logic that was done in the function + * lte_est_timing_advance_pusch, maybe it's not necessary? + * maybe it's even not correct at all? + */ + UE_list->UE_sched_ctrl[UE_id].ta_update = (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance) / 4; + UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; + UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; + first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, + subframeP, UE_RNTI(enb_mod_idP, + UE_id)); + } + + /* update scheduled bytes */ + UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) + UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; + } else { // we've got an error + LOG_D(MAC, + "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + ul_cqi); + + if(ul_cqi>200){ // too high energy pattern + UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; + } + // AssertFatal(1==0,"ulsch in error\n"); if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; - if(find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1) + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + + /* update scheduled bytes */ + UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) + UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; + + if (find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1) cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } else - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; @@ -189,7 +228,6 @@ rx_sdu(const module_id_t enb_mod_idP, uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP] , subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); @@ -202,712 +240,606 @@ rx_sdu(const module_id_t enb_mod_idP, hi_dci0_req_body->number_of_hi++; hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP,sf_ahead_dl); + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - return; - } - } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti - AssertFatal(mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx > 1, - "maxHARQ %d should be greater than 1\n", - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); + return; - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, - current_rnti, RA_id, ul_cqi); + } + } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti + AssertFatal(mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx > 1, + "maxHARQ %d should be greater than 1\n", + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); - first_rb = ra->msg3_first_rb; + LOG_D(MAC, + "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, + current_rnti, RA_id, ul_cqi); - if (sduP == NULL) { // we've got an error on Msg3 - LOG_D(MAC, - "[eNB %d] CC_id %d, RA %d ULSCH in error in round(Msg3) %d/%d\n", - enb_mod_idP, CC_idP, RA_id, - ra[RA_id].msg3_round, - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - if (ra[RA_id].msg3_round >= - mac->common_channels[CC_idP].radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { - cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); - } + first_rb = ra->msg3_first_rb; + + if (sduP == NULL) { // we've got an error on Msg3 + LOG_D(MAC, + "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", + enb_mod_idP, CC_idP, RA_id, + ra[RA_id].msg3_round, + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); + if (ra[RA_id].msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); + } + + else { + first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + ra[RA_id].msg3_round++; + // prepare handling of retransmission + get_Msg3allocret(&mac->common_channels[CC_idP], + ra[RA_id].Msg3_subframe, ra[RA_id].Msg3_frame, + &ra[RA_id].Msg3_frame, &ra[RA_id].Msg3_subframe); + add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP); + } + + /* TODO: program NACK for PHICH? */ - else { - first_rb = - UE_list->UE_template[CC_idP][UE_id]. - first_rb_ul[harq_pid]; - ra[RA_id].msg3_round++; - // prepare handling of retransmission - get_Msg3allocret(&mac->common_channels[CC_idP], - ra[RA_id].Msg3_subframe, ra[RA_id].Msg3_frame, - &ra[RA_id].Msg3_frame, &ra[RA_id].Msg3_subframe); - add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, - subframeP); - } - return; - } - } else { - LOG_W(MAC, - "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", - current_rnti); - return; - } - payload_ptr = - parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, - rx_lengths, sdu_lenP); - if(payload_ptr == NULL){ - LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", - enb_mod_idP, harq_pid, CC_idP,current_rnti, UE_id); return; } + } else { + LOG_W(MAC, + "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", + current_rnti); + return; + } + payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); - T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); - T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), + if(payload_ptr == NULL){ + LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", + enb_mod_idP, harq_pid, CC_idP,current_rnti, UE_id); + return; + } + + T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); + T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), + T_BUFFER(sduP, sdu_lenP)); + + mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; + mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; + mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; + + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + + // control element + for (i = 0; i < num_ce; i++) { + + T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), - T_BUFFER(sduP, sdu_lenP)); - - mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; - mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; - mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; - - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; - - // control element - for (i = 0; i < num_ce; i++) { - - T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_ces[i])); - - switch (rx_ces[i]) { // implement and process BSR + CRNTI + - case POWER_HEADROOM: - if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].phr_info = - (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].phr_info); - UE_list->UE_template[CC_idP][UE_id].phr_info_configured = - 1; - UE_list->UE_sched_ctrl[UE_id].phr_received = 1; - } - payload_ptr += sizeof(POWER_HEADROOM_CMD); - break; + T_INT(rx_ces[i])); - case CRNTI: - { - int old_rnti = - (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; - int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); - LOG_I(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", - enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, - num_ce, old_rnti, old_UE_id); - /* receiving CRNTI means that the current rnti has to go away */ - //cancel_ra_proc(enb_mod_idP, CC_idP, frameP, - // current_rnti); - if (old_UE_id != -1) { - /* TODO: if the UE did random access (followed by a MAC uplink with - * CRNTI) because none of its scheduling request was granted, then - * according to 36.321 5.4.4 the UE's MAC will notify RRC to release - * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply - * default configuration for CQI reporting and scheduling requests, - * which basically means that the CQI requests won't work anymore and - * that the UE won't do any scheduling request anymore as long as the - * eNB doesn't reconfigure the UE. - * We have to take care of this. As the code is, nothing is done and - * the UE state in the eNB is wrong. - */ + switch (rx_ces[i]) { // implement and process BSR + CRNTI + + case POWER_HEADROOM: + if (UE_id != -1) { + UE_list->UE_template[CC_idP][UE_id].phr_info = + (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].phr_info); + UE_list->UE_template[CC_idP][UE_id].phr_info_configured = + 1; + UE_list->UE_sched_ctrl[UE_id].phr_received = 1; + } + payload_ptr += sizeof(POWER_HEADROOM_CMD); + break; + + case CRNTI: + { + int old_rnti = + (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; + int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); + LOG_D(MAC, + "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", + enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, + num_ce, old_rnti, old_UE_id); + /* receiving CRNTI means that the current rnti has to go away */ + //cancel_ra_proc(enb_mod_idP, CC_idP, frameP, + // current_rnti); + if (old_UE_id != -1) { + /* TODO: if the UE did random access (followed by a MAC uplink with + * CRNTI) because none of its scheduling request was granted, then + * according to 36.321 5.4.4 the UE's MAC will notify RRC to release + * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply + * default configuration for CQI reporting and scheduling requests, + * which basically means that the CQI requests won't work anymore and + * that the UE won't do any scheduling request anymore as long as the + * eNB doesn't reconfigure the UE. + * We have to take care of this. As the code is, nothing is done and + * the UE state in the eNB is wrong. + */ for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { ra = &mac->common_channels[CC_idP].ra[ii]; if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { - mac_rrc_data_ind(enb_mod_idP, - CC_idP, - frameP, subframeP, - old_rnti, - DCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], - ENB_FLAG_YES, enb_mod_idP, 0); - // prepare transmission of Msg4(RRCConnectionReconfiguration) - ra->state = MSGCRNTI; - LOG_I(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) RRCConnectionReconfiguration(Msg4)\n", - enb_mod_idP, frameP, subframeP, CC_idP, old_rnti, old_UE_id); - // - UE_id = old_UE_id; - current_rnti = old_rnti; - ra->rnti = old_rnti; - ra->crnti_rrc_mui = rrc_eNB_mui-1; - ra->crnti_harq_pid = -1; - //clear timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, old_rnti); - } - UE_list->UE_template[CC_idP][UE_id].ul_SR = 1; - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1; - break; + mac_rrc_data_ind(enb_mod_idP, + CC_idP, + frameP, subframeP, + old_rnti, + DCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], + 0); + // prepare transmission of Msg4(RRCConnectionReconfiguration) + ra->state = MSGCRNTI; + LOG_I(MAC, + "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) RRCConnectionReconfiguration(Msg4)\n", + enb_mod_idP, frameP, subframeP, CC_idP, old_rnti, old_UE_id); + + UE_id = old_UE_id; + current_rnti = old_rnti; + ra->rnti = old_rnti; + ra->crnti_rrc_mui = rrc_eNB_mui-1; + ra->crnti_harq_pid = -1; + //clear timer + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, + subframeP, old_rnti); } + UE_list->UE_template[CC_idP][UE_id].ul_SR = 1; + UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1; + break; + } } - }else{ + } else { cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); } - crnti_rx = 1; - payload_ptr += 2; - break; - } + crnti_rx = 1; + payload_ptr += 2; + break; + } - case TRUNCATED_BSR: - case SHORT_BSR: - { - uint8_t lcgid; - lcgid = (payload_ptr[0] >> 6); - - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - if (UE_id != -1) { - - UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = - (payload_ptr[0] & 0x3f); - - // update buffer info - - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[lcgid]]; - - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]; - - RC.eNB[enb_mod_idP][CC_idP]-> - pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] - = (payload_ptr[0] & 0x3f); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr - [UE_id][(frameP * 10) + subframeP]); - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[lcgid] - == 0) { - UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[lcgid] = - frameP; - } - if (mac_eNB_get_rrc_status - (enb_mod_idP, - UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - ul_total_buffer, - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]); - } else { - - } - payload_ptr += 1; //sizeof(SHORT_BSR); // fixme - } - break; - - case LONG_BSR: - if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = - ((payload_ptr[0] & 0xFC) >> 2); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = - ((payload_ptr[0] & 0x03) << 4) | - ((payload_ptr[1] & 0xF0) >> 4); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = - ((payload_ptr[1] & 0x0F) << 2) | - ((payload_ptr[2] & 0xC0) >> 6); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = - (payload_ptr[2] & 0x3F); - - // update buffer info - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0]]; - - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, - rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, - CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID0] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID0] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID0] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID1] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID1] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID1] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID2] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID2] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID2] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID3] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID3] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID3] = frameP; - - } - } + case TRUNCATED_BSR: + case SHORT_BSR: + { + uint8_t lcgid; + lcgid = (payload_ptr[0] >> 6); - payload_ptr += 3; ////sizeof(LONG_BSR); - break; + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); + + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); + if (UE_id != -1) { + int bsr = payload_ptr[0] & 0x3f; + + lcgid_updated[lcgid] = 1; + + // update buffer info + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[bsr]; + + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr + [UE_id][(frameP * 10) + subframeP]); + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; + } + if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer, + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); + } else { - default: - LOG_E(MAC, - "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", - enb_mod_idP, CC_idP, rx_ces[i]); - break; } + payload_ptr += 1; //sizeof(SHORT_BSR); // fixme + } + break; + + case LONG_BSR: + if (UE_id != -1) { + int bsr0 = (payload_ptr[0] & 0xFC) >> 2; + int bsr1 = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); + int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); + int bsr3 = payload_ptr[2] & 0x3F; + + lcgid_updated[0] = 1; + lcgid_updated[1] = 1; + lcgid_updated[2] = 1; + lcgid_updated[3] = 1; + + // update buffer info + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; + + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, + rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, + CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); + + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = frameP; + + } + } + + payload_ptr += 3; ////sizeof(LONG_BSR); + break; + + default: + LOG_E(MAC, + "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", + enb_mod_idP, CC_idP, rx_ces[i]); + break; } + } - for (i = 0; i < num_sdu; i++) { - LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", - i, rx_lcids[i], rx_lengths[i]); - - T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); - T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, - rx_lengths - [i])); - - switch (rx_lcids[i]) { - case CCCH: - if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { - LOG_E(MAC, - "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); - break; - } + for (i = 0; i < num_sdu; i++) { + LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", + i, rx_lcids[i], rx_lengths[i]); + + T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); + T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, + rx_lengths + [i])); + + switch (rx_lcids[i]) { + case CCCH: + if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { + LOG_E(MAC, + "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); + break; + } + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + enb_mod_idP, CC_idP, frameP, payload_ptr[0], + payload_ptr[1], payload_ptr[2], payload_ptr[3], + payload_ptr[4], payload_ptr[5], current_rnti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); + for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { + RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; + + LOG_D(MAC, + "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", + enb_mod_idP, CC_idP, ii, ra->rnti, + current_rnti, ra->state); + + if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { + + //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); + + if (UE_id < 0) { + memcpy(&ra->cont_res_id[0], payload_ptr, 6); LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - enb_mod_idP, CC_idP, frameP, payload_ptr[0], - payload_ptr[1], payload_ptr[2], payload_ptr[3], - payload_ptr[4], payload_ptr[5], current_rnti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); - for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { - RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; - - LOG_D(MAC, - "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", - enb_mod_idP, CC_idP, ii, ra->rnti, - current_rnti, ra->state); - - if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { - - //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - - if (UE_id < 0) { - memcpy(&ra->cont_res_id[0], payload_ptr, 6); - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - payload_ptr - sduP); - - if ((UE_id = - add_new_ue(enb_mod_idP, CC_idP, - mac->common_channels[CC_idP]. - ra[ii].rnti, harq_pid -#ifdef Rel14 - , - mac->common_channels[CC_idP]. - ra[ii].rach_resource_type + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + payload_ptr - sduP); + + if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, + mac->common_channels[CC_idP]. + ra[ii].rnti, harq_pid +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + mac->common_channels[CC_idP]. + ra[ii].rach_resource_type #endif - )) == -1) { - LOG_E(MAC,"[MAC][eNB] Max user count reached\n"); - cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); - break; - // kill RA procedure - } else - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", - enb_mod_idP, CC_idP, frameP, ra->rnti, - UE_id); - } else { - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, UE_id, - rx_lengths[i], payload_ptr - sduP); - // kill RA procedure - } - - mac_rrc_data_ind(enb_mod_idP, - CC_idP, - frameP, subframeP, - current_rnti, - CCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], - ENB_FLAG_YES, enb_mod_idP, 0); - - - if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest - // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - } - // prepare transmission of Msg4 - ra->state = MSG4; - - - - if(mac->common_channels[CC_idP].tdd_Config!=NULL){ - switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment){ - case 1: - ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 7) % 10; - break; - // TODO need to be complete for other tdd configs. - } - }else{ - // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different - ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 4) % 10; - } - - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; - } // if process is active - } // loop on RA processes - - break; - - case DCCH: - case DCCH1: - // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ + )) == -1) { + LOG_E(MAC,"[MAC][eNB] Max user count reached\n"); + cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); + break; + // kill RA procedure + } else + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", + enb_mod_idP, CC_idP, frameP, ra->rnti, + UE_id); + } else { + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, UE_id, + rx_lengths[i], payload_ptr - sduP); + // kill RA procedure + } + + mac_rrc_data_ind(enb_mod_idP, + CC_idP, + frameP, subframeP, + current_rnti, + CCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], + 0); + + + if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest + // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + } + // prepare transmission of Msg4 + ra->state = MSG4; + + + + if(mac->common_channels[CC_idP].tdd_Config!=NULL){ + switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment){ + case 1: + ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 7) % 10; + break; + default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort(); + // TODO need to be complete for other tdd configs. + } + }else{ + // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different + ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 4) % 10; + } + + UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; + } // if process is active + } // loop on RA processes + + break; + + case DCCH: + case DCCH1: + // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - LOG_T(MAC, "\n"); + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + LOG_T(MAC, "\n"); #endif - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] >= - rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] -= - rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] = 0; - - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); - - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_bytes_rx[rx_lcids[i]] - += rx_lengths[i]; + if (UE_id != -1) { + if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { + // adjust buffer occupancy of the correponding logical channel group + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + } + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + rx_lcids[i]); - } + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + + + } - /* UE_id != -1 */ - // } - break; + /* UE_id != -1 */ + // } + break; - // all the DRBS - case DTCH: - default: + // all the DRBS + case DTCH: + default: #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - LOG_T(MAC, "\n"); + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + LOG_T(MAC, "\n"); #endif - if (rx_lcids[i] < NB_RB_MAX) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); - - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - UE_id, rx_lcids[i], - UE_list->UE_template[CC_idP][UE_id]. - lcgidmap[rx_lcids[i]], - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]]); - - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - -= rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info - [UE_list->UE_template[CC_idP][UE_id].lcgidmap - [rx_lcids[i]]] = 0; - if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) - && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; - //clear uplane_inactivity_timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } else { /* rx_length[i] */ - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_errors_rx += 1; - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], - UE_id); - } - } else { /*(UE_id != -1 */ - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); - } - } + if (rx_lcids[i] < NB_RB_MAX) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + rx_lcids[i]); + + if (UE_id != -1) { + // adjust buffer occupancy of the correponding logical channel group + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + UE_id, rx_lcids[i], + UE_list->UE_template[CC_idP][UE_id]. + lcgidmap[rx_lcids[i]], + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[UE_list->UE_template[CC_idP] + [UE_id].lcgidmap[rx_lcids[i]]]); + + if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + } + + if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - break; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + //clear uplane_inactivity_timer + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } else { /* rx_length[i] */ + UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + LOG_E(MAC, + "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + enb_mod_idP, CC_idP, frameP, rx_lcids[i], + UE_id); + } + } else { /*(UE_id != -1 */ + LOG_E(MAC, + "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); } + } - payload_ptr += rx_lengths[i]; + break; } - // Program ACK for PHICH - LOG_D(MAC, - "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", - current_rnti, harq_pid, first_rb); - nfapi_hi_dci0_request_t *hi_dci0_req; - uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP] , subframeP); - hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; - - nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; - hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP,sf_ahead_dl); - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - - /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ - if ((num_sdu == 0) && (num_ce == 0)) { - if (UE_id != -1) - UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; - /* - if (msg3_flagP != NULL) { - if( *msg3_flagP == 1 ) { - LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); - *msg3_flagP=0; - } - } */ - } else { - if (UE_id != -1) { - UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; - UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += - sdu_lenP; - UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; - } + payload_ptr += rx_lengths[i]; + } + + // Program ACK for PHICH + LOG_D(MAC, + "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", + current_rnti, harq_pid, first_rb); + nfapi_hi_dci0_request_t *hi_dci0_req; + uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP] , subframeP); + hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; + + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = + &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + + /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ + if ((num_sdu == 0) && (num_ce == 0)) { + if (UE_id != -1) + UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; + /* + if (msg3_flagP != NULL) { + if( *msg3_flagP == 1 ) { + LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); + *msg3_flagP=0; + } + } */ + } else { + if (UE_id != -1) { + UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; + UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP; + UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; } + } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); - stop_meas(&mac->rx_ulsch_sdu); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); + stop_meas(&mac->rx_ulsch_sdu); } uint32_t bytes_to_bsr_index(int32_t nbytes) { - uint32_t i = 0; + uint32_t i = 0; - if (nbytes < 0) { - return (0); - } + if (nbytes < 0) { + return (0); + } - while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { - i++; - } + while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { + i++; + } - return (i - 1); + return (i - 1); } void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status) { - eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); - eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; + eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); + eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; + eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; - eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; + eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; } unsigned char *parse_ulsch_header(unsigned char *mac_header, @@ -918,78 +850,77 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, unsigned short *rx_lengths, unsigned short tb_length) { - unsigned char not_done = 1, num_ces = 0, num_sdus = - 0, lcid, num_sdu_cnt; - unsigned char *mac_header_ptr = mac_header; - unsigned short length, ce_len = 0; + unsigned char not_done = 1, num_ces = 0, num_sdus = + 0, lcid, num_sdu_cnt; + unsigned char *mac_header_ptr = mac_header; + unsigned short length, ce_len = 0; - while (not_done == 1) { + while (not_done == 1) { - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { - not_done = 0; - } + if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { + not_done = 0; + } - lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; + lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - if (lcid < EXTENDED_POWER_HEADROOM) { - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = - tb_length - (mac_header_ptr - mac_header) - ce_len; + if (lcid < EXTENDED_POWER_HEADROOM) { + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = tb_length - (mac_header_ptr - mac_header) - ce_len; - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; - num_sdu_cnt++) { - length -= rx_lengths[num_sdu_cnt]; - } - } else { - if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); - } else { // F = 1 - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & - 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) - mac_header_ptr)->L_LSB & 0xff); - mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); - } - } + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; + num_sdu_cnt++) { + length -= rx_lengths[num_sdu_cnt]; + } + } else { + if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); + } else { // F = 1 + length = + ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & + 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) + mac_header_ptr)->L_LSB & 0xff); + mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); + } + } - LOG_D(MAC, - "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", - num_sdus, lcid, tb_length, length, - mac_header_ptr - mac_header); - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; - } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI - if (lcid == SHORT_PADDING) { - mac_header_ptr++; - } else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; - - if (lcid == LONG_BSR) { - ce_len += 3; - } else if (lcid == CRNTI) { - ce_len += 2; - } else if ((lcid == POWER_HEADROOM) - || (lcid == TRUNCATED_BSR) - || (lcid == SHORT_BSR)) { - ce_len++; - } else { - LOG_E(MAC, "unknown CE %d \n", lcid); - //AssertFatal(1 == 0, "unknown CE"); - return NULL; - } - } + LOG_D(MAC, + "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", + num_sdus, lcid, tb_length, length, + mac_header_ptr - mac_header); + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI + if (lcid == SHORT_PADDING) { + mac_header_ptr++; + } else { + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; + + if (lcid == LONG_BSR) { + ce_len += 3; + } else if (lcid == CRNTI) { + ce_len += 2; + } else if ((lcid == POWER_HEADROOM) + || (lcid == TRUNCATED_BSR) + || (lcid == SHORT_BSR)) { + ce_len++; + } else { + LOG_E(MAC, "unknown CE %d \n", lcid); + //AssertFatal(1 == 0, "unknown CE"); + return NULL; } + } } + } - *num_ce = num_ces; - *num_sdu = num_sdus; + *num_ce = num_ces; + *num_sdu = num_sdus; - return (mac_header_ptr); + return (mac_header_ptr); } /* This function is called by PHY layer when it schedules some @@ -998,39 +929,37 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, * (done below in schedule_ulsch). */ void -set_msg3_subframe(module_id_t Mod_id, +set_msg3_subframe(module_id_t mod_id, int CC_id, int frame, int subframe, int rnti, int Msg3_frame, int Msg3_subframe) { - eNB_MAC_INST *mac = RC.mac[Mod_id]; - int i; - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if (mac->common_channels[CC_id].ra[i].state != IDLE && - mac->common_channels[CC_id].ra[i].rnti == rnti) { - mac->common_channels[CC_id].ra[i].Msg3_subframe = - Msg3_subframe; - break; - } + eNB_MAC_INST *mac = RC.mac[mod_id]; + int i; + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if (mac->common_channels[CC_id].ra[i].state != IDLE && + mac->common_channels[CC_id].ra[i].rnti == rnti) { + mac->common_channels[CC_id].ra[i].Msg3_subframe = + Msg3_subframe; + break; } + } } - void schedule_ulsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - uint16_t first_rb[MAX_NUM_CCs]; - uint16_t i; + uint16_t first_rb[MAX_NUM_CCs], i; int CC_id; eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc; - int sched_frame=frameP; start_meas(&mac->schedule_ulsch); - int sched_subframe = (subframeP+4)%10; + int sched_frame=frameP; + int sched_subframe = (subframeP + 4) % 10; cc = &mac->common_channels[0]; int tdd_sfa; @@ -1039,621 +968,737 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, tdd_sfa = cc->tdd_Config->subframeAssignment; switch (subframeP) { case 0: - if ((tdd_sfa == 0)|| - (tdd_sfa == 3)) sched_subframe = 4; - else if (tdd_sfa==6) sched_subframe = 7; - else return; + if ((tdd_sfa == 0) || (tdd_sfa == 3)) + sched_subframe = 4; + else if (tdd_sfa == 6) + sched_subframe = 7; + else + return; break; case 1: - if ((tdd_sfa==0)|| - (tdd_sfa==1)) sched_subframe = 7; - else if (tdd_sfa==6) sched_subframe = 8; - else return; + if ((tdd_sfa == 0) || (tdd_sfa == 1)) + sched_subframe = 7; + else if (tdd_sfa == 6) + sched_subframe = 8; + else + return; break; - case 2: // Don't schedule UL in subframe 2 for TDD + default: + return; + + case 2: // Don't schedule UL in subframe 2 for TDD return; case 3: - if (tdd_sfa==2) sched_subframe = 7; - else return; + if (tdd_sfa == 2) + sched_subframe = 7; + else + return; break; case 4: - if (tdd_sfa==1) sched_subframe = 8; - else return; + if (tdd_sfa == 1) + sched_subframe = 8; + else + return; break; case 5: - if (tdd_sfa==0) sched_subframe = 9; - else if (tdd_sfa==6) sched_subframe = 2; - else return; + if (tdd_sfa == 0) + sched_subframe = 9; + else if (tdd_sfa == 6) + sched_subframe = 2; + else + return; break; case 6: - if (tdd_sfa==0 || tdd_sfa==1) sched_subframe = 2; - else if (tdd_sfa==6) sched_subframe = 3; - else return; + if (tdd_sfa == 0 || tdd_sfa == 1) + sched_subframe = 2; + else if (tdd_sfa == 6) + sched_subframe = 3; + else + return; break; case 7: return; case 8: - if ((tdd_sfa>=2) && (tdd_sfa<=5)) sched_subframe=2; - else return; + if ((tdd_sfa >= 2) && (tdd_sfa <= 5)) + sched_subframe = 2; + else + return; break; case 9: - if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3; - else if (tdd_sfa==6) sched_subframe=4; - else return; + if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) + sched_subframe = 3; + else if (tdd_sfa == 6) + sched_subframe = 4; + else + return; break; } } if (sched_subframe < subframeP) sched_frame++; - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + //leave out first RB for PUCCH + first_rb[CC_id] = 1; - //leave out first RB for PUCCH - first_rb[CC_id] = 1; + // UE data info; + // check which UE has data to transmit + // function to decide the scheduling + // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) - // UE data info; - // check which UE has data to transmit - // function to decide the scheduling - // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) + // default function for default scheduling + // - // default function for default scheduling - // + // output of scheduling, the UE numbers in RBs, where it is in the code??? + // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 + // Msg3 is using 1 PRB so we need to increase first_rb accordingly + // not sure about the break (can there be more than 1 active RA procedure?) - // output of scheduling, the UE numbers in RBs, where it is in the code??? - // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 - // Msg3 is using 1 PRB so we need to increase first_rb accordingly - // not sure about the break (can there be more than 1 active RA procedure?) + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if ((cc->ra[i].state == WAITMSG3) && + (cc->ra[i].Msg3_subframe == sched_subframe)) { + first_rb[CC_id]++; + // cc->ray[i].Msg3_subframe = -1; + break; + } + } + } - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if ((cc->ra[i].state == WAITMSG3) && - (cc->ra[i].Msg3_subframe == sched_subframe)) { - first_rb[CC_id]++; - // cc->ray[i].Msg3_subframe = -1; - break; - } - } + // perform slice-specifc operations + + total_slice_percentage_uplink=0; + avg_slice_percentage_uplink=1.0/n_active_slices_uplink; + + // reset the slice percentage for inactive slices + for (i = n_active_slices_uplink; i< MAX_NUM_SLICES; i++) { + slice_percentage_uplink[i]=0; + } + for (i = 0; i < n_active_slices_uplink; i++) { + if (slice_percentage_uplink[i] < 0 ){ + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", + module_idP, frameP, subframeP, i, slice_percentage_uplink[i]); + slice_percentage_uplink[i]=0; + } + total_slice_percentage_uplink+=slice_percentage_uplink[i]; + } + + for (i = 0; i < n_active_slices_uplink; i++) { + + // Load any updated functions + if (update_ul_scheduler[i] > 0 ) { + slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); + update_ul_scheduler[i] = 0; + update_ul_scheduler_current[i] = 0; + //slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; + //total_slice_percentage_current_uplink+=slice_percentage_uplink[i]; + //if (total_slice_percentage_current_uplink> 1) + //total_slice_percentage_current_uplink=1; + LOG_N(MAC,"update ul scheduler slice %d\n", i); + } + // the new total RB share is within the range + if (total_slice_percentage_uplink <= 1.0){ + + // check if the number of slices has changed, and log + if (n_active_slices_current_uplink != n_active_slices_uplink ){ + if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { + LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", + module_idP, frameP, subframeP, n_active_slices_current_uplink, n_active_slices_uplink); + n_active_slices_current_uplink = n_active_slices_uplink; + } else { + LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n", + n_active_slices_uplink, n_active_slices_current_uplink); + n_active_slices_uplink = n_active_slices_current_uplink; + } + } + + // check if the slice rb share has changed, and log the console + if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + module_idP, i, frameP, subframeP, total_slice_percentage_current_uplink, + total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); + total_slice_percentage_current_uplink = total_slice_percentage_uplink; + slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; + } + + // check if the slice max MCS, and log the console + if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ + if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + module_idP, i, frameP, subframeP, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); + slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n", + module_idP, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); + slice_maxmcs_uplink[i] = slice_maxmcs_current_uplink[i]; + } + } + + // check if a new scheduler, and log the console + if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", + module_idP, i, frameP, subframeP, ul_scheduler_type[i]); + update_ul_scheduler_current[i] = update_ul_scheduler[i]; + } + } else { + if (n_active_slices_uplink == n_active_slices_current_uplink) { + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", + module_idP, i, total_slice_percentage_current_uplink, total_slice_percentage_uplink); + if (slice_percentage_uplink[i] > avg_slice_percentage_uplink) { + slice_percentage_uplink[i] -= 0.1; + total_slice_percentage_uplink -= 0.1; + } + } else { + // here we can correct the values, e.g. reduce proportionally + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", + module_idP, i, total_slice_percentage_current_uplink, + total_slice_percentage_uplink, n_active_slices_uplink, + n_active_slices_current_uplink); + n_active_slices_uplink = n_active_slices_current_uplink; + slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; + } } - schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb); + // Run each enabled slice-specific schedulers one by one + slice_sched_ul[i](module_idP, i, frameP, subframeP, sched_subframe, first_rb); + } + stop_meas(&mac->schedule_ulsch); } + void schedule_ulsch_rnti(module_id_t module_idP, + slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb) { - int UE_id; - uint8_t aggregation = 2; - rnti_t rnti = -1; - uint8_t round = 0; - uint8_t harq_pid = 0; - uint8_t status = 0; - uint8_t rb_table_index = -1; - uint32_t cqi_req, cshift, ndi, tpc; - int32_t normalized_rx_power; - int32_t target_rx_power = -90; - static int32_t tpc_accumulated = 0; - int n; - int CC_id = 0; - int drop_ue = 0; - int N_RB_UL; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - UE_list_t *UE_list = &mac->UE_list; - UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; - int sched_frame = frameP; - int rvidx_tab[4] = { 0, 2, 3, 1 }; - uint16_t ul_req_index; - uint8_t dlsch_flag; - if (sched_subframeP < subframeP) - sched_frame++; - - nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id][subframeP]; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; - nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; - nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; - //LOG_D(MAC, "entering ulsch preprocesor\n"); - ulsch_scheduler_pre_processor(module_idP, frameP, subframeP,sched_subframeP, first_rb); - - //LOG_D(MAC, "exiting ulsch preprocesor\n"); - - hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; - - // loop over all active UEs - for (UE_id = UE_list->head_ul; UE_id >= 0; - UE_id = UE_list->next_ul[UE_id]) { - - // don't schedule if Msg4 is not received yet - if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. - configured == FALSE) { - LOG_D(MAC, - "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", - module_idP, frameP, subframeP, UE_id); - continue; - } + int UE_id; + uint8_t aggregation = 2; + rnti_t rnti = -1; + uint8_t round = 0; + uint8_t harq_pid = 0; + uint8_t status = 0; + uint8_t rb_table_index = -1; + uint32_t cqi_req, cshift, ndi, tpc; + int32_t normalized_rx_power; + int32_t target_rx_power = -90; + static int32_t tpc_accumulated = 0; + int n; + int CC_id = 0; + int drop_ue = 0; + int N_RB_UL; + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc = mac->common_channels; + UE_list_t *UE_list = &mac->UE_list; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *UE_sched_ctrl; + int sched_frame = frameP; + int rvidx_tab[4] = { 0, 2, 3, 1 }; + uint16_t ul_req_index; + uint8_t dlsch_flag; + + if (sched_subframeP < subframeP) + sched_frame++; + + nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id][subframeP]; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + + nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; + nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; + //LOG_D(MAC, "entering ulsch preprocesor\n"); + ulsch_scheduler_pre_processor(module_idP, slice_id, frameP, subframeP, sched_subframeP, first_rb); + + //LOG_D(MAC, "exiting ulsch preprocesor\n"); + + hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; + + // loop over all active UEs + for (UE_id = UE_list->head_ul; UE_id >= 0; + UE_id = UE_list->next_ul[UE_id]) { + + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + // don't schedule if Msg4 is not received yet + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. + configured == FALSE) { + LOG_D(MAC, + "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", + module_idP, frameP, subframeP, UE_id); + continue; + } - rnti = UE_RNTI(module_idP, UE_id); + rnti = UE_RNTI(module_idP, UE_id); - if (rnti == NOT_A_RNTI) { - LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", - module_idP, frameP, subframeP, UE_id); - continue; - } + if (rnti == NOT_A_RNTI) { + LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", + module_idP, frameP, subframeP, UE_id); + continue; + } - drop_ue = 0; - /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ - /* TODO: refine? - - for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - - if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - drop_ue = 1; - break; - } - } */ - if (drop_ue == 1) { -/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ - abort(); - /* TODO: this is a hack. Sometimes the UE has no PHY context but - * is still present in the MAC with 'ul_failure_timer' = 0 and - * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's - * start an UL out of sync procedure in this case. - * The root cause of this problem has to be found and corrected. - * In the meantime, this hack... - */ - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - // inform RRC of failure and clear timer - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, - subframeP, rnti); - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) { - LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d clear to 0\n", UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - } - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + drop_ue = 0; + /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ + /* TODO: refine? + + for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + + if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); + drop_ue = 1; + break; + } + } */ + if (drop_ue == 1) { + /* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ + abort(); + /* TODO: this is a hack. Sometimes the UE has no PHY context but + * is still present in the MAC with 'ul_failure_timer' = 0 and + * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's + * start an UL out of sync procedure in this case. + * The root cause of this problem has to be found and corrected. + * In the meantime, this hack... + */ + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + // inform RRC of failure and clear timer + mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, + subframeP, rnti); + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + } + continue; + } + // loop over all active UL CC_ids for this UE + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); + + /* + aggregation=get_aggregation(get_bw_index(module_idP,CC_id), + eNB_UE_stats->dl_cqi, + format0); + */ + + if (CCE_allocation_infeasible + (module_idP, CC_id, 1, 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; + } + + /* be sure that there are some free RBs */ + if (first_rb[CC_id] >= N_RB_UL - 1) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + continue; + } + // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel + + UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; + harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); + round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; + AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, + UE_id, rnti); + LOG_D(MAC, + "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", + module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, + CC_id, aggregation, N_RB_UL); + + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template->estimated_ul_buffer; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * + 10) + + subframeP]); + if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) + // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + { + LOG_D(MAC, + "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP, harq_pid, frameP, subframeP, UE_id, rnti, + round, UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer, + UE_sched_ctrl->cqi_req_timer); + // reset the scheduling request + UE_template->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP, rnti); + if (status < RRC_CONNECTED) + cqi_req = 0; + else if (UE_sched_ctrl->cqi_req_timer > 30) { + if (nfapi_mode) { + cqi_req = 0; + } else { + cqi_req = 1; + UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; } - continue; - } - // loop over all active UL CC_ids for this UE - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); - - /* - aggregation=get_aggregation(get_bw_index(module_idP,CC_id), - eNB_UE_stats->dl_cqi, - format0); - */ - - if (CCE_allocation_infeasible - (module_idP, CC_id, 1, 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; + UE_sched_ctrl->cqi_req_timer = 0; + } else + cqi_req = 0; + + //power control + //compute the expected ULSCH RX power (for the stats) + + // this is the normalized RX power and this should be constant (regardless of mcs + normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; + target_rx_power = 178; + + // 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_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around + { + UE_template->pusch_tpc_tx_frame = frameP; + UE_template->pusch_tpc_tx_subframe = subframeP; + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } + } else { + tpc = 1; //0 + } + //tpc = 1; + if (tpc != 1) { + LOG_D(MAC, + "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, + tpc_accumulated, normalized_rx_power, + target_rx_power); + } + // new transmission + if (round == 0) { + + ndi = 1 - UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid] = ndi; + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; + UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, slice_maxmcs_uplink[slice_id]); + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; + //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + if (UE_template->pre_allocated_rb_table_index_ul >= 0) { + rb_table_index = UE_template->pre_allocated_rb_table_index_ul; + } else { + UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); + rb_table_index = 5; // for PHR } - /* be sure that there are some free RBs */ - if (first_rb[CC_id] >= N_RB_UL - 1) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; + // buffer_occupancy = UE_template->ul_total_buffer; + + + while (((rb_table[rb_table_index] > (N_RB_UL - 1 - first_rb[CC_id])) + || (rb_table[rb_table_index] > 45)) + && (rb_table_index > 0)) { + rb_table_index--; } - // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel - - UE_template = &UE_list->UE_template[CC_id][UE_id]; - UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; - harq_pid = - subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); - round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; - AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, - UE_id, rnti); + + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], + rb_table[rb_table_index]); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template->TBS_UL[harq_pid]; + // buffer_occupancy -= TBS; + + T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb[CC_id]), + T_INT(rb_table[rb_table_index]), + T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); + + if (mac_eNB_get_rrc_status(module_idP, rnti) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP, harq_pid, rnti, CC_id, frameP, + subframeP, UE_id, + UE_template->mcs_UL[harq_pid], + first_rb[CC_id], rb_table[rb_table_index], + rb_table_index, + UE_template->TBS_UL[harq_pid], harq_pid); + + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + + UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, + UE_sched_ctrl->ul_scheduled); + + // adjust scheduled UL bytes by TBS, wait for UL sdus to do final update LOG_D(MAC, - "[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", - module_idP, frameP, subframeP, harq_pid, UE_id, rnti, - CC_id, aggregation, N_RB_UL); - - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP] = - UE_template->ul_total_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP]); - if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames - { - LOG_D(MAC, - "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP, harq_pid, frameP, subframeP, UE_id, rnti, - round, UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer, - UE_sched_ctrl->cqi_req_timer); - // reset the scheduling request - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP, rnti); - if (status < RRC_CONNECTED) - cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer > 30) { - if (nfapi_mode) { - cqi_req = 0; - } else { - cqi_req = 1; - UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; - } - UE_sched_ctrl->cqi_req_timer = 0; - } else - cqi_req = 0; - - //power control - //compute the expected ULSCH RX power (for the stats) - - // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; - target_rx_power = 178; - - // 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_template->pusch_tpc_tx_frame * 10 + - UE_template->pusch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame = frameP; - UE_template->pusch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < (target_rx_power - 4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - } else { - tpc = 1; //0 - } - //tpc = 1; - if (tpc != 1) { - LOG_D(MAC, - "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, tpc, - tpc_accumulated, normalized_rx_power, - target_rx_power); - } - // new transmission - if (round == 0) { - - ndi = 1 - UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid] = ndi; - UE_list->eNB_UE_stats[CC_id][UE_id]. - normalized_rx_power = normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = - target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = - UE_template->pre_assigned_mcs_ul; - UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >= 0) { - rb_table_index = - UE_template->pre_allocated_rb_table_index_ul; - } else { - UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index = 5; // for PHR - } - - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = - UE_template->mcs_UL[harq_pid]; - // buffer_occupancy = UE_template->ul_total_buffer; - - - while (((rb_table[rb_table_index] > - (N_RB_UL - 1 - first_rb[CC_id])) - || (rb_table[rb_table_index] > 45)) - && (rb_table_index > 0)) { - rb_table_index--; - } - - UE_template->TBS_UL[harq_pid] = - get_TBS_UL(UE_template->mcs_UL[harq_pid], - rb_table[rb_table_index]); - UE_list->eNB_UE_stats[CC_id][UE_id]. - total_rbs_used_rx += rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = - UE_template->TBS_UL[harq_pid]; - // buffer_occupancy -= TBS; - - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), - T_INT(rb_table[rb_table_index]), - T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - - if (mac_eNB_get_rrc_status(module_idP, rnti) < - RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP, harq_pid, rnti, CC_id, frameP, - subframeP, UE_id, - UE_template->mcs_UL[harq_pid], - first_rb[CC_id], rb_table[rb_table_index], - rb_table_index, - UE_template->TBS_UL[harq_pid], harq_pid); - - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = - rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; - - UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, - UE_sched_ctrl->ul_scheduled); - - // adjust total UL buffer status by TBS, wait for UL sdus to do final update - LOG_D(MAC, - "[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", - module_idP, CC_id, UE_id, rnti, - UE_template->ul_total_buffer, - UE_template->TBS_UL[harq_pid]); - if (UE_template->ul_total_buffer > - UE_template->TBS_UL[harq_pid]) - UE_template->ul_total_buffer -= - UE_template->TBS_UL[harq_pid]; - else - UE_template->ul_total_buffer = 0; - LOG_D(MAC, "ul_total_buffer, new %d\n", - UE_template->ul_total_buffer); - // Cyclic shift for DM RS - cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - // save it for a potential retransmission - UE_template->cshift[harq_pid] = cshift; - - hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0, - sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = - 2 + sizeof(nfapi_hi_dci0_dci_pdu); - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = - NFAPI_UL_DCI_FORMAT_0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = - aggregation; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = - 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - resource_block_start = first_rb[CC_id]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - number_of_resource_block = - rb_table[rb_table_index]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = - UE_template->mcs_UL[harq_pid]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - cyclic_shift_2_for_drms = cshift; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - frequency_hopping_enabled_flag = 0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - new_data_indication_1 = ndi; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = - cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = - UE_template->DAI_ul[sched_subframeP]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; - - hi_dci0_req_body->number_of_dci++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4) - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - - hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - - - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); + "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", + module_idP, CC_id, UE_id, rnti, + UE_template->scheduled_ul_bytes, + UE_template->TBS_UL[harq_pid]); + + UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; + + LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); + + // Cyclic shift for DM RS + cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + // save it for a potential retransmission + UE_template->cshift[harq_pid] = cshift; + + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; + + hi_dci0_req_body->number_of_dci++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + + hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + + + LOG_D(MAC, + "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); + ul_req_index = 0; dlsch_flag = 0; for(ul_req_index = 0;ul_req_index < ul_req_tmp_body->number_of_pdus;ul_req_index++){ - if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE){ - dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); - break; - } + if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE){ + dlsch_flag = 1; + LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); + break; + } } - // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start - rb_table[rb_table_index], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - 0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - get_TBS_UL - (UE_template-> - mcs_UL[harq_pid], - rb_table - [rb_table_index])); -#ifdef Rel14 - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } + + // Add UL_config PDUs + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start + rb_table[rb_table_index], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL + (UE_template-> + mcs_UL[harq_pid], + rb_table + [rb_table_index])); +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } #endif if(dlsch_flag == 1){ - if(cqi_req == 1){ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; - - }else{ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; - } - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + if(cqi_req == 1){ + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; + + }else{ + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; + } + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); }else{ - ul_req_tmp_body->number_of_pdus++; + ul_req_tmp_body->number_of_pdus++; } - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - mac->ul_handle++; - - uint16_t ul_sched_frame = sched_frame; - uint16_t ul_sched_subframeP = sched_subframeP; - - // add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); - ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; - - add_ue_ulsch_info(module_idP, - CC_id, UE_id, subframeP, - S_UL_SCHEDULED); - - //LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); - LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); - - // increment first rb for next UE allocation - first_rb[CC_id] += rb_table[rb_table_index]; - } else { // round > 0 => retransmission - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, - T_INT(module_idP), T_INT(CC_id), T_INT(rnti), - T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), - T_INT(rb_table[rb_table_index]), T_INT(round)); - // Add UL_config PDUs - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); + + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + mac->ul_handle++; + + uint16_t ul_sched_frame = sched_frame; + uint16_t ul_sched_subframeP = sched_subframeP; + + //add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); + ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; + + add_ue_ulsch_info(module_idP, + CC_id, UE_id, subframeP, + S_UL_SCHEDULED); + + //LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); + LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); + + // increment first rb for next UE allocation + first_rb[CC_id] += rb_table[rb_table_index]; + } else { // round > 0 => retransmission + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, + T_INT(module_idP), T_INT(CC_id), T_INT(rnti), + T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb[CC_id]), + T_INT(rb_table[rb_table_index]), T_INT(round)); + +#if 0 + /* This is done in rx_sdu, as it has to. + * Since the code is a bit different, let's keep this version here for review, in case of problem. + */ + // fill in NAK information + + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0, + sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = UE_template->cshift[harq_pid]; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); + hi_dci0_req->sfn_sf = frameP<<4|subframeP; + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + + LOG_D(MAC, + "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n", + module_idP, harq_pid, rnti, CC_id, frameP, + subframeP, UE_id, UE_template->mcs_UL[harq_pid], + UE_template->first_rb_ul[harq_pid], + UE_template->nb_rb_ul[harq_pid], + UE_template->TBS_UL[harq_pid], round); +#endif + // Add UL_config PDUs + LOG_D(MAC, + "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); ul_req_index = 0; dlsch_flag = 0; for(ul_req_index = 0;ul_req_index < ul_req_tmp_body->number_of_pdus;ul_req_index++){ - if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE){ - dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); - break; - } + if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE){ + dlsch_flag = 1; + LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); + break; + } } - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round & 3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template-> - TBS_UL[harq_pid]); -#ifdef Rel14 - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round & 3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template-> + TBS_UL[harq_pid]); +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } #endif if(dlsch_flag == 1){ - if(cqi_req == 1){ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid]; - - }else{ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid]; - } - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + if(cqi_req == 1){ + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid]; + + }else{ + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid]; + } + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); }else{ - ul_req_tmp_body->number_of_pdus++; + ul_req_tmp_body->number_of_pdus++; } - mac->ul_handle++; + mac->ul_handle++; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); - } /* - else if (round > 0) { //we schedule a retransmission + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); + } /* + else if (round > 0) { //we schedule a retransmission - ndi = UE_template->oldNDI_UL[harq_pid]; + ndi = UE_template->oldNDI_UL[harq_pid]; - if ((round&3)==0) { - mcs = openair_daq_vars.target_ue_ul_mcs; - } else { - mcs = rvidx_tab[round&3] + 28; //not correct for round==4! + if ((round&3)==0) { + mcs = openair_daq_vars.target_ue_ul_mcs; + } else { + mcs = rvidx_tab[round&3] + 28; //not correct for round==4! - } + } - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", - module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, - first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], - harq_pid, round); + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", + module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, + first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], + harq_pid, round); - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, - first_rb[CC_id], - UE_template->nb_rb_ul[harq_pid]); - first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation + rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, + first_rb[CC_id], + UE_template->nb_rb_ul[harq_pid]); + first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; - } - */ + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; + } + */ - } // UE_is_to_be_scheduled - } // loop over UE_id - } // loop of CC_id + } // UE_is_to_be_scheduled + } // loop over UE_id + } // loop of CC_id } diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h deleted file mode 100644 index d3170aaf919e2a24e4599399729b4078e9d6c254..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ /dev/null @@ -1,216 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 flexran_agent_mac_proto.h - * \brief MAC functions for FlexRAN agent - * \author Xenofon Foukas and Navid Nikaein - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#ifndef __LAYER2_MAC_FLEXRAN_AGENT_MAC_PROTO_H__ -#define __LAYER2_MAC_FLEXRAN_AGENT_MAC_PROTO_H__ - -#include "flexran_agent_defs.h" -#include "header.pb-c.h" -#include "flexran.pb-c.h" - -/* - * slice specific scheduler - */ -typedef void (*slice_scheduler) (module_id_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - - - -/* - * top level flexran scheduler used by the eNB scheduler - */ -void flexran_schedule_ue_spec_default(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); -/* - * slice specific scheduler for embb - */ -void -flexran_schedule_ue_spec_embb(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); -/* - * slice specific scheduler for urllc - */ -void -flexran_schedule_ue_spec_urllc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - -/* - * slice specific scheduler for mmtc - */ -void -flexran_schedule_ue_spec_mmtc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); -/* - * slice specific scheduler for best effort traffic - */ -void -flexran_schedule_ue_spec_be(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - -/* - * common flexran scheduler function - */ -void -flexran_schedule_ue_spec_common(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); - -int flexran_slice_member(int UE_id, int slice_id); - -int flexran_slice_maxmcs(int slice_id); - -void _store_dlsch_buffer(module_id_t Mod_id, - int slice_id, - frame_t frameP, sub_frame_t subframeP); - - -void _assign_rbs_required(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t - nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs]); - -void _dlsch_scheduler_pre_processor(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], - int *mbsfn_flag); - -void _dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], - unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] - [N_RBG_MAX]); - -void _dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator - [MAX_NUM_CCs][N_RBG_MAX]); - -/* - * Default scheduler used by the eNB agent - */ -void flexran_schedule_ue_spec_default(mid_t mod_id, uint32_t frame, - uint32_t subframe, int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - -/* - * Data plane function for applying the DL decisions of the scheduler - */ -void flexran_apply_dl_scheduling_decisions(mid_t mod_id, uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage * - dl_scheduling_info); - -/* - * Data plane function for applying the UE specific DL decisions of the scheduler - */ -void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - uint32_t n_dl_ue_data, - Protocol__FlexDlData ** - dl_ue_data); - -/* - * Data plane function for filling the DCI structure - */ -void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, - Protocol__FlexDlDci * dl_dci); - -#endif diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c deleted file mode 100644 index 44052a8749191780e5c6c62c39935bfa91081792..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c +++ /dev/null @@ -1,588 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 flexran_agent_scheduler_dataplane.c - * \brief data plane procedures related to eNB scheduling - * \author Xenofon Foukas - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "LAYER2/MAC/flexran_agent_mac_proto.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/flexran_dci_conversions.h" - -#include "UTIL/LOG/log.h" -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" - -#include "RRC/LITE/extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - -#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 - -void -flexran_apply_dl_scheduling_decisions(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage * - dl_scheduling_info) -{ - - Protocol__FlexDlMacConfig *mac_config = - dl_scheduling_info->dl_mac_config_msg; - - // Check if there is anything to schedule for random access - if (mac_config->n_dl_rar > 0) { - /*TODO: call the random access data plane function */ - } - // Check if there is anything to schedule for paging/broadcast - if (mac_config->n_dl_broadcast > 0) { - /*TODO: call the broadcast/paging data plane function */ - } - // Check if there is anything to schedule for the UEs - if (mac_config->n_dl_ue_data > 0) { - flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, - mbsfn_flag, - mac_config-> - n_dl_ue_data, - mac_config->dl_ue_data); - } - -} - - -void -flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - uint32_t n_dl_ue_data, - Protocol__FlexDlData ** - dl_ue_data) -{ - - uint8_t CC_id; - int UE_id; - mac_rlc_status_resp_t rlc_status; - unsigned char ta_len = 0; - 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, sdu_lengths[11], rnti, padding = 0, post_padding = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - 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; - short ta_update = 0; - eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; - UE_list_t *UE_list = &eNB->UE_list; - // static int32_t tpc_accumulated=0; - UE_sched_ctrl *ue_sched_ctl; - - int last_sdu_header_len = 0; - - 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; - - CC_id = dl_data->serv_cell_index; - // frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id); - - rnti = dl_data->rnti; - UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]); - - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - - 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 - rlc_status.bytes_in_buffer = 0; - - TBS = dl_dci->tbs_size[0]; - - 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) ? 2 - : 0; - } - - num_sdus = 0; - sdu_length_total = 0; - - n_lc = dl_data->n_rlc_pdu; - // Go through each one of the channel commands and create SDUs - 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, - rnti, - mod_id, - frame, - subframe, - ENB_FLAG_YES, - MBMS_FLAG_NO, lcid, 0); - - if (rlc_status.bytes_in_buffer > 0) { - - 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, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, rlc_size); // transport block set size - - 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[j] = mac_rlc_data_req(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, rlc_size, //not used - (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[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[j]; - - if (sdu_lengths[j] < 128) { - header_len += 2; - last_sdu_header_len = 2; - } else { - header_len += 3; - last_sdu_header_len = 3; - } - num_sdus++; - } - } - } - } // SDU creation end - - - 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) == 1) { - //if (header_len == 2 || header_len == 3) { - header_len = 1; - } else { - header_len = (header_len - last_sdu_header_len) + 1; - } - - // 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; - } - - // If there is nothing to schedule, just leave - if ((sdu_length_total) <= 0) { - 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 - sdu_lengths, // - sdu_lcids, 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); - - - - - -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } - - LOG_T(MAC, "\n"); -#endif - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0][offset], dlsch_buffer, sdu_length_total); - // memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - - // 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) { - trace_pdu(1, - (uint8_t *) - UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS, mod_id, 3, UE_RNTI(mod_id, - UE_id), - eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - mod_id, CC_id, frame, UE_RNTI(mod_id, UE_id), - TBS); - } - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi = - eNB_UE_stats->DL_cqi[0]; - - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = - mac_eNB_get_rrc_status(mod_id, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - - //nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - //Find the number of resource blocks and set them to the template for retransmissions - nb_rb = get_min_rb_unit(mod_id, CC_id); - uint16_t stats_tbs = - mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb); - - while (stats_tbs < TBS) { - 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; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - dl_dci->mcs[0]; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = - dl_dci->mcs[0]; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = - TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; - - //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; - //UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb; - //UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb; - //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]; - - //Fill the proper DCI of OAI - flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci); - } -} - -void -flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, - Protocol__FlexDlDci * dl_dci) -{ - - void *DLSCH_dci = NULL; - DCI_PDU *DCI_pdu; - - unsigned char harq_pid = 0; - // unsigned char round = 0; - LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; - int size_bits = 0, size_bytes = 0; - eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; - UE_list_t *UE_list = &eNB->UE_list; - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - - int UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]); - - uint32_t format; - - harq_pid = dl_dci->harq_process; - // round = dl_dci->rv[0]; - - // Note this code is for a specific DCI format - DLSCH_dci = - (void *) UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid]; - DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; - - frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id); - - if (dl_dci->has_tpc == 1) { - // Check if tpc has been set and reset measurement */ - if ((dl_dci->tpc == 0) || (dl_dci->tpc == 2)) { - eNB_UE_stats = - mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - eNB_UE_stats->Po_PUCCH_update = 0; - } - } - - - switch (frame_parms[CC_id]->N_RB_DL) { - case 6: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_1_5MHz_TDD_t); - size_bits = sizeof_DCI1_1_5MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_1_5MHz_FDD_t); - size_bits = sizeof_DCI1_1_5MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - case 25: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_5MHz_TDD_t); - size_bits = sizeof_DCI1_5MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_5MHz_FDD_t); - size_bits = sizeof_DCI1_5MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - case 50: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_10MHz_TDD_t); - size_bits = sizeof_DCI1_10MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_10MHz_FDD_t); - size_bits = sizeof_DCI1_10MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - case 100: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_20MHz_TDD_t); - size_bits = sizeof_DCI1_20MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_20MHz_FDD_t); - size_bits = sizeof_DCI1_20MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - } - - //Set format to the proper type - switch (dl_dci->format) { - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1: - format = format1; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1A: - format = format1A; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1B: - format = format1B; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1C: - format = format1C; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D: - format = format1E_2A_M10PRB; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2: - format = format2; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A: - format = format2A; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2B: - format = format2B; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_3: - format = 3; - break; - default: - /*TODO: Need to deal with unsupported DCI type */ - return; - } - - add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - size_bytes, dl_dci->aggr_level, size_bits, format, 0); -} diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c deleted file mode 100644 index bf1db6c613a32b768fe96fdf382945c7df6aabb8..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ /dev/null @@ -1,2005 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 flexran_agent_scheduler_dlsch_ue.c - * \brief procedures related to eNB for the DLSCH transport channel - * \author Xenofon Foukas, Navid Nikaein and Raymond Knopp - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "LAYER2/MAC/flexran_agent_mac_proto.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" -#include "UTIL/LOG/log.h" -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" - -#include "RRC/LITE/extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - -#include "ENB_APP/flexran_agent_defs.h" - -#include "pdcp.h" - -#include "header.pb-c.h" -#include "flexran.pb-c.h" -#include "flexran_agent_mac.h" -#include <dlfcn.h> - -#include "SIMULATION/TOOLS/defs.h" // for taus - -#if defined(ENABLE_ITTI) -#include "intertask_interface.h" -#endif - -#define ENABLE_MAC_PAYLOAD_DEBUG - -/** - * Local variables to support slicing - * - */ - - -/*!\brief UE ULSCH scheduling states*/ -typedef enum { - MIN_SLICE_STRATEGY = 0, - SLICE_MASK, - UEID_TO_SLICEID, - MAX_SLICE_STRATEGY -} SLICING_STRATEGY; - -// this assumes a max of of 16 UE per eNB/CC -#define SLICE0_MASK 0x000f -#define SLICE1_MASK 0x00f0 -#define SLICE2_MASK 0x0f00 -#define SLICE3_MASK 0xf000 - - -// number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; - -// ue to slice mapping -int slicing_strategy = UEID_TO_SLICEID; -int slicing_strategy_current = UEID_TO_SLICEID; - -// RB share for each slice for past and current time -float slice_percentage[MAX_NUM_SLICES] = { 1.0, 0.0, 0.0, 0.0 }; -float slice_percentage_current[MAX_NUM_SLICES] = { 1.0, 0.0, 0.0, 0.0 }; - -float total_slice_percentage = 0; - -// MAX MCS for each slice for past and current time -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, 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", - "flexran_schedule_ue_spec_urllc", - "flexran_schedule_ue_spec_mmtc", - "flexran_schedule_ue_spec_be" // best effort -}; - -// pointer to the slice specific scheduler -slice_scheduler slice_sched[MAX_NUM_SLICES] = { 0 }; - - -/** - * preprocessor functions for scheduling - * - */ - - -// This function stores the downlink buffer for all the logical channels -void -_store_dlsch_buffer(module_id_t Mod_id, - int slice_id, frame_t frameP, sub_frame_t subframeP) -{ - - int UE_id, i; - rnti_t rnti; - mac_rlc_status_resp_t rlc_status; - UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - UE_TEMPLATE *UE_template; - - 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; - - UE_template = - &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; - - // clear logical channel interface variables - UE_template->dl_buffer_total = 0; - UE_template->dl_pdus_total = 0; - - for (i = 0; i < MAX_NUM_LCID; i++) { - UE_template->dl_buffer_info[i] = 0; - UE_template->dl_pdus_in_buffer[i] = 0; - UE_template->dl_buffer_head_sdu_creation_time[i] = 0; - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0; - } - - rnti = UE_RNTI(Mod_id, UE_id); - - for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels - - rlc_status = - mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, - ENB_FLAG_YES, MBMS_FLAG_NO, i, 0); - UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel - UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; - UE_template->dl_buffer_head_sdu_creation_time[i] = - rlc_status.head_sdu_creation_time; - UE_template->dl_buffer_head_sdu_creation_time_max = - cmax(UE_template->dl_buffer_head_sdu_creation_time_max, - rlc_status.head_sdu_creation_time); - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = - rlc_status.head_sdu_remaining_size_to_send; - UE_template->dl_buffer_head_sdu_is_segmented[i] = - rlc_status.head_sdu_is_segmented; - UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer - UE_template->dl_pdus_total += - UE_template->dl_pdus_in_buffer[i]; - -#ifdef DEBUG_eNB_SCHEDULER - - /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : - * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent - */ - if (UE_template->dl_buffer_info[i] > 0) - LOG_D(MAC, - "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, slice_id, frameP, subframeP, UE_id, - i, UE_template->dl_pdus_in_buffer[i], - UE_template->dl_buffer_info[i], - UE_template->dl_buffer_head_sdu_creation_time[i], - UE_template-> - dl_buffer_head_sdu_remaining_size_to_send[i], - UE_template->dl_buffer_head_sdu_is_segmented[i]); - -#endif - - } - - //#ifdef DEBUG_eNB_SCHEDULER - if (UE_template->dl_buffer_total > 0) - LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", - Mod_id, frameP, subframeP, UE_id, - UE_template->dl_buffer_total, - UE_template->dl_pdus_total); - - //#endif - } -} - - -// This function returns the estimated number of RBs required by each UE for downlink scheduling -void -_assign_rbs_required(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t - nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs]) -{ - - - rnti_t rnti; - uint16_t TBS = 0; - LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs]; - int UE_id, n, i, j, CC_id, pCCid, tmp; - UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - // UE_TEMPLATE *UE_template; - - // clear rb allocations across all CC_ids - 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; - - 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)]; - } - - // provide the list of CCs sorted according to MCS - for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { - for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { - DevAssert(j < MAX_NUM_CCs); - - if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]-> - dlsch_mcs1 > - eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]-> - dlsch_mcs1) { - tmp = UE_list->ordered_CCids[i][UE_id]; - UE_list->ordered_CCids[i][UE_id] = - UE_list->ordered_CCids[j][UE_id]; - UE_list->ordered_CCids[j][UE_id] = tmp; - } - } - } - - /* NN --> RK - * check the index of UE_template" - */ - if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) { - LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id); - - for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { - 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 (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(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], - 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(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(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, cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)]); - } - } - } -} - -void -_dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], unsigned char - MIMO_mode_indicator - [MAX_NUM_CCs][N_RBG_MAX]) -{ - int i; - 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]; - - for (i = 0; i < N_RBG; i++) { - - if ((rballoc_sub[CC_id][i] == 0) && - (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && - (nb_rbs_required_remaining[CC_id][UE_id] > 0) && - (ue_sched_ctl->pre_nb_available_rbs[CC_id] < - nb_rbs_required[CC_id][UE_id])) { - - // if this UE is not scheduled for TM5 - if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { - - if ((i == N_RBG - 1) - && ((N_RB_DL == 25) || (N_RB_DL == 50))) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit + 1; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit - 1; - } else { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit; - } - } - } // dl_pow_off[CC_id][UE_id] ! = 0 - } - } -} - -void -_dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] - [N_RBG_MAX]) -{ - int i, j; - UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - uint8_t *vrb_map = - eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map; - int RBGsize = - PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL / N_RBG; -#ifdef SF05_LIMIT - //int subframe05_limit=0; - int sf05_upper = -1, sf05_lower = -1; -#endif - // LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); - - flexran_update_TA(module_idP, UE_id, CC_id); - - if (UE_id == 0) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE, - ue_sched_ctl->ta_update); - } - nb_rbs_required[CC_id][UE_id] = 0; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; - ue_sched_ctl->dl_pow_off[CC_id] = 2; - nb_rbs_required_remaining[CC_id][UE_id] = 0; - for (i = 0; i < n_active_slices; i++) - nb_rbs_allowed_slice[CC_id][i] = 0; -#ifdef SF05_LIMIT - switch (N_RBG) { - case 6: - sf05_lower = 0; - sf05_upper = 5; - break; - case 8: - sf05_lower = 2; - sf05_upper = 5; - break; - case 13: - sf05_lower = 4; - sf05_upper = 7; - break; - case 17: - sf05_lower = 7; - sf05_upper = 9; - break; - case 25: - sf05_lower = 11; - sf05_upper = 13; - break; - } -#endif - // Initialize Subbands according to VRB map - for (i = 0; i < N_RBG; i++) { - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; -#ifdef SF05_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors) - - if ((subframeP == 0 || subframeP == 5) && - (i >= sf05_lower && i <= sf05_upper)) - rballoc_sub[CC_id][i] = 1; -#endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < RBGsize; j++) { - if (vrb_map[j + (i * RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", - frameP, subframeP, j + (i * RBGsize)); - break; - } - } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; - } -} - -// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done -void -_dlsch_scheduler_pre_processor(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], int *mbsfn_flag) -{ - - 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; - 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]; - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t average_rbs_per_user[MAX_NUM_CCs] = { 0 }; - rnti_t rnti; - int min_rb_unit[MAX_NUM_CCs]; - uint16_t r1 = 0; - uint8_t CC_id; - UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs] = { 0 }; - - int transmission_mode = 0; - UE_sched_ctrl *ue_sched_ctl; - - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; - - frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id, CC_id); - - - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - - 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 - - //if (flexran_slice_member(UE_id, slice_id) == 0) - //continue; - _dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, - frameP, - subframeP, - N_RBG[CC_id], - nb_rbs_required, - nb_rbs_required_remaining, - nb_rbs_allowed_slice, - rballoc_sub, - MIMO_mode_indicator); - - } - } - - // Store the DLSCH buffer for each logical channel - _store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); - - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - _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); - - total_ue_count = 0; - - // loop over all active UEs - 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 (!phy_stats_exist(Mod_id, rnti)) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_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); - - // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); - - if (round > 0) { - nb_rbs_required[CC_id][UE_id] = - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - } - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count = total_ue_count + 1; - } - // hypotetical assignement - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ - - if (total_ue_count == 0) { - average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count) <= - nb_rbs_allowed_slice[CC_id][slice_id]) { - average_rbs_per_user[CC_id] = - (uint16_t) floor(nb_rbs_allowed_slice[CC_id][slice_id] - / total_ue_count); - } else { - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE - } - } - } - - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required - 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; - - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - - // control channel - if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED) { - nb_rbs_required_remaining_1[CC_id][i] = - nb_rbs_required[CC_id][i]; - } else { - nb_rbs_required_remaining_1[CC_id][i] = - cmin(average_rbs_per_user[CC_id], - nb_rbs_required[CC_id][i]); - - } - } - } - - //Allocation to UEs is done in 2 rounds, - // 1st stage: average number of RBs allocated to each UE - // 2nd stage: remaining RBs are allocated to high priority UEs - for (r1 = 0; r1 < 2; r1++) { - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - - if (flexran_slice_member(i, slice_id) == 0) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - - if (r1 == 0) { - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required_remaining_1[CC_id][i]; - } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required[CC_id][i] - - nb_rbs_required_remaining_1[CC_id][i] + - nb_rbs_required_remaining[CC_id][i]; - } - - if (nb_rbs_required[CC_id][i] > 0) - LOG_D(MAC, - "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", - r1, CC_id, i, - nb_rbs_required_remaining[CC_id][i], - nb_rbs_required_remaining_1[CC_id][i], - nb_rbs_required[CC_id][i], - UE_list->UE_sched_ctrl[i]. - pre_nb_available_rbs[CC_id], N_RBG[CC_id], - min_rb_unit[CC_id]); - - } - } - - if (total_ue_count > 0) { - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - flexran_get_harq(Mod_id, CC_id, UE_id, frameP, - subframeP, &harq_pid, &round); - rnti = UE_RNTI(Mod_id, UE_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 */ - - // retransmission in data channels - // control channel in the 1st transmission - // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - _dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, - CC_id, - N_RBG[CC_id], - transmission_mode, - min_rb_unit - [CC_id], - frame_parms - [CC_id]-> - N_RB_DL, - nb_rbs_required, - nb_rbs_required_remaining, - rballoc_sub, - MIMO_mode_indicator); - } - } - } // total_ue_count - } // end of for for r1 and r2 - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; - - if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { - LOG_D(MAC, - "******************DL Scheduling Information for UE%d ************************\n", - UE_id); - LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, - ue_sched_ctl->dl_pow_off[CC_id]); - LOG_D(MAC, - "***********RB Alloc for every subband for UE%d ***********\n", - UE_id); - - for (j = 0; j < N_RBG[CC_id]; j++) { - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; - LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", - UE_id, j, - ue_sched_ctl->rballoc_sub_UE[CC_id][j]); - } - - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; - LOG_D(MAC, - "[eNB %d][SLICE %d] Total RBs allocated for UE%d = %d\n", - Mod_id, slice_id, UE_id, - ue_sched_ctl->pre_nb_available_rbs[CC_id]); - } - } - } -} - -#define SF05_LIMIT 1 - -/* - * Main scheduling functions to support slicing - * - */ - -void -flexran_schedule_ue_spec_default(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -//------------------------------------------------------------------------------ -{ - int i = 0; - - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); - - for (i = 0; i < n_active_slices; i++) { - - // Load any updated functions - if (update_dl_scheduler[i] > 0) { - slice_sched[i] = dlsym(NULL, dl_scheduler_type[i]); - update_dl_scheduler[i] = 0; - update_dl_scheduler_current[i] = 0; - slice_percentage_current[i] = slice_percentage[i]; - total_slice_percentage += slice_percentage[i]; - LOG_N(MAC, "update dl scheduler slice %d\n", i); - } - // check if the number of slices has changed, and log - if (n_active_slices_current != n_active_slices) { - if ((n_active_slices > 0) - && (n_active_slices <= MAX_NUM_SLICES)) { - LOG_N(MAC, - "[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_current, - n_active_slices); - n_active_slices_current = n_active_slices; - } else { - LOG_W(MAC, - "invalid number of slices %d, revert to the previous value %d\n", - n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; - } - } - // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]) { - if ((slice_percentage[i] >= 0.0) - && (slice_percentage[i] <= 1.0)) { - if ((total_slice_percentage - slice_percentage_current[i] + - slice_percentage[i]) <= 1.0) { - total_slice_percentage = - total_slice_percentage - - slice_percentage_current[i] + slice_percentage[i]; - LOG_N(MAC, - "[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, - total_slice_percentage, - slice_percentage_current[i], - slice_percentage[i]); - slice_percentage_current[i] = slice_percentage[i]; - } else { - LOG_W(MAC, - "[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", - mod_id, i, total_slice_percentage, - total_slice_percentage - - slice_percentage_current[i] + - slice_percentage[i], slice_percentage[i], - slice_percentage_current[i]); - slice_percentage[i] = slice_percentage_current[i]; - - } - } else { - LOG_W(MAC, - "[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n", - mod_id, i, slice_percentage[i], - slice_percentage_current[i]); - slice_percentage[i] = slice_percentage_current[i]; - - } - } - // check if the slice max MCS, and log the console - if (slice_maxmcs_current[i] != slice_maxmcs[i]) { - if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)) { - LOG_N(MAC, - "[eNB %d][SLICE %d] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - mod_id, i, frame, subframe, slice_maxmcs_current[i], - slice_maxmcs[i]); - slice_maxmcs_current[i] = slice_maxmcs[i]; - } else { - LOG_W(MAC, - "[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n", - mod_id, i, slice_percentage[i], slice_percentage[i]); - slice_maxmcs[i] = slice_maxmcs_current[i]; - } - } - // check if a new scheduler, and log the console - if (update_dl_scheduler_current[i] != update_dl_scheduler[i]) { - LOG_N(MAC, - "[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, dl_scheduler_type[i]); - update_dl_scheduler_current[i] = update_dl_scheduler[i]; - } - // Run each enabled slice-specific schedulers one by one - //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); - slice_sched[i] (mod_id, i, frame, subframe, mbsfn_flag, dl_info); - - } - -} - -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) -{ - return (uint16_t) floor(rb_percentage * total_rbs); -} - -int flexran_slice_maxmcs(int slice_id) -{ - return slice_maxmcs[slice_id]; -} - -int flexran_slice_member(int UE_id, int slice_id) -{ - // group membership definition - int slice_member = 0; - - if ((slice_id < 0) || (slice_id > n_active_slices)) - LOG_W(MAC, "out of range slice id %d\n", slice_id); - - switch (slicing_strategy) { - case SLICE_MASK: - switch (slice_id) { - case 0: - if (SLICE0_MASK & UE_id) { - slice_member = 1; - } - break; - case 1: - if (SLICE1_MASK & UE_id) { - slice_member = 1; - } - break; - case 2: - if (SLICE2_MASK & UE_id) { - slice_member = 1; - } - break; - case 3: - if (SLICE3_MASK & UE_id) { - slice_member = 1; - } - break; - default: - LOG_W(MAC, "unknown slice_id %d\n", slice_id); - break; - - } - break; - case UEID_TO_SLICEID: - default: - if ((UE_id % n_active_slices) == slice_id) { - slice_member = 1; // this ue is a member of this slice - } - break; - } - - return slice_member; -} - -/* more aggressive rb and mcs allocation with medium priority and the traffic qci */ -void -flexran_schedule_ue_spec_embb(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - flexran_schedule_ue_spec_common(mod_id, - slice_id, - frame, subframe, mbsfn_flag, dl_info); - -} - -/* more conservative mcs allocation with high priority and the traffic qci */ -void -flexran_schedule_ue_spec_urllc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - flexran_schedule_ue_spec_common(mod_id, - slice_id, - frame, subframe, mbsfn_flag, dl_info); - -} - -/* constant rb allocation with low mcs with low priority and given the UE capabilities */ -void -flexran_schedule_ue_spec_mmtc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - - flexran_schedule_ue_spec_common(mod_id, - slice_id, - frame, subframe, mbsfn_flag, dl_info); - -} - -/* regular rb and mcs allocation with low priority */ -void -flexran_schedule_ue_spec_be(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - - flexran_schedule_ue_spec_common(mod_id, - slice_id, - frame, subframe, mbsfn_flag, dl_info); - -} - -//------------------------------------------------------------------------------ -void -flexran_schedule_ue_spec_common(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -//------------------------------------------------------------------------------ -{ - uint8_t CC_id; - int UE_id; - int N_RBG[MAX_NUM_CCs]; - unsigned char aggregation; - mac_rlc_status_resp_t rlc_status; - 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; - 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]; - eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; - /* TODO: Must move the helper structs to scheduler implementation */ - UE_list_t *UE_list = &eNB->UE_list; - int32_t normalized_rx_power, target_rx_power; - 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; - - Protocol__FlexDlDci *dl_dci; - Protocol__FlexRlcPdu *rlc_pdus[11]; - uint32_t ce_flags = 0; - - uint8_t rballoc_sub[25]; - int i; - uint32_t data_to_request; - uint32_t dci_tbs; - uint8_t ue_has_transmission = 0; - uint32_t ndi; - -#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 = 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); - // get number of PRBs less those used by common channels - total_nb_available_rb[CC_id] = flexran_get_N_RB_DL(mod_id, CC_id); - for (i = 0; i < flexran_get_N_RB_DL(mod_id, CC_id); i++) - if (eNB->common_channels[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; - - N_RBG[CC_id] = flexran_get_N_RBG(mod_id, CC_id); - - // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); - - start_meas(&eNB->schedule_dlsch_preprocessor); - _dlsch_scheduler_pre_processor(mod_id, - slice_id, - frame, subframe, N_RBG, mbsfn_flag); - stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_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; - - if (rnti == NOT_A_RNTI) { - LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", - UE_id, UE_list->num_UEs); - // mac_xface->macphy_exit("Cannot find rnti for UE_id"); - 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", - mod_id, frame, UE_id, CC_id); - //if(mac_xface->get_transmission_mode(module_idP,rnti)==5) - continue; //to next user (there might be rbs availiable for other UEs in TM5 - // else - // break; - } - - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - set_ue_dai(subframe, - flexran_get_subframe_assignment(mod_id, CC_id), - UE_id, CC_id, UE_list); - //TODO: update UL DAI after DLSCH scheduling - //set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe,frame_parms); - } - - channels_added = 0; - - // After this point all the UEs will be scheduled - dl_data[num_ues_added] = - (Protocol__FlexDlData *) - malloc(sizeof(Protocol__FlexDlData)); - protocol__flex_dl_data__init(dl_data[num_ues_added]); - dl_data[num_ues_added]->has_rnti = 1; - dl_data[num_ues_added]->rnti = rnti; - dl_data[num_ues_added]->n_rlc_pdu = 0; - dl_data[num_ues_added]->has_serv_cell_index = 1; - dl_data[num_ues_added]->serv_cell_index = CC_id; - - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_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 - - if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) { - mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; - mcs = cmin(mcs, 16); - } -#endif - - // initializing the rb allocation indicator for each UE - for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] - = 0; - rballoc_sub[j] = 0; - } - - /* LOG_D(MAC,"[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", */ - /* mod_id, frame, UE_id, CC_id, rnti, harq_pid, round, nb_available_rb, */ - /* eNB_UE_stats->DL_cqi[0], mcs, */ - /* UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); */ - - dl_dci = - (Protocol__FlexDlDci *) - malloc(sizeof(Protocol__FlexDlDci)); - protocol__flex_dl_dci__init(dl_dci); - dl_data[num_ues_added]->dl_dci = dl_dci; - - - dl_dci->has_rnti = 1; - dl_dci->rnti = rnti; - dl_dci->has_harq_process = 1; - 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,subframe); - LOG_D(MAC, - "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframe, UE_id, - UE_list->UE_template[CC_id][UE_id].DAI); - } - - mcs = UE_list->UE_template[CC_id][UE_id].mcs[harq_pid]; - - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - - /*TODO: Must add this to FlexRAN agent API */ - dci_tbs = mac_xface->get_TBS_DL(mcs, nb_rb); - - if (nb_rb <= nb_available_rb) { - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) - && (j < flexran_get_N_RBG(mod_id, CC_id))) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == - flexran_get_N_RBG(mod_id, CC_id) - 1) - && - ((flexran_get_N_RB_DL(mod_id, CC_id) == - 25) - || (flexran_get_N_RB_DL(mod_id, CC_id) - == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - j = j + 1; - } - } - - nb_available_rb -= nb_rb; - 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]; - - for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - PHY_vars_eNB_g[mod_id][CC_id]-> - mu_mimo_mode[UE_id].rballoc_sub[j] = - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband - [harq_pid][j]; - rballoc_sub[j] = - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband - [harq_pid][j]; - } - - // Keep the old NDI, do not toggle - ndi = - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - tpc = - UE_list->UE_template[CC_id][UE_id]. - oldTPC[harq_pid]; - UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; - - ue_has_transmission = 1; - num_ues_added++; - } else { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - mod_id, frame, CC_id, UE_id); - ue_has_transmission = 0; - } - //End of retransmission - } else { /* This is a potentially new SDU opportunity */ - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - //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; - - dl_data[num_ues_added]->n_ce_bitmap = 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; - } - - /*TODO: Add other flags if DRX and other CE are required */ - - // Add the control element flags to the flexran message - dl_data[num_ues_added]->ce_bitmap[0] = ce_flags; - dl_data[num_ues_added]->ce_bitmap[1] = ce_flags; - - // 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; - // 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); - //If we have space, we need to see how much data we can request at most (if any available) - rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, j, (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 - - 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; - } */ - LOG_D(MAC, - "[TEST]Will request %d from channel %d\n", - data_to_request, j); - rlc_pdus[channels_added] = - (Protocol__FlexRlcPdu *) - malloc(sizeof(Protocol__FlexRlcPdu)); - protocol__flex_rlc_pdu__init(rlc_pdus - [channels_added]); - rlc_pdus[channels_added]->n_rlc_pdu_tb = 2; - rlc_pdus[channels_added]->rlc_pdu_tb = - (Protocol__FlexRlcPduTb **) - malloc(sizeof(Protocol__FlexRlcPduTb *) * - 2); - rlc_pdus[channels_added]->rlc_pdu_tb[0] = - (Protocol__FlexRlcPduTb *) - malloc(sizeof(Protocol__FlexRlcPduTb)); - protocol__flex_rlc_pdu_tb__init(rlc_pdus - [channels_added]->rlc_pdu_tb - [0]); - rlc_pdus[channels_added]-> - rlc_pdu_tb[0]->has_logical_channel_id = 1; - rlc_pdus[channels_added]-> - rlc_pdu_tb[0]->logical_channel_id = j; - rlc_pdus[channels_added]->rlc_pdu_tb[0]-> - has_size = 1; - rlc_pdus[channels_added]->rlc_pdu_tb[0]->size = - data_to_request; - rlc_pdus[channels_added]->rlc_pdu_tb[1] = - (Protocol__FlexRlcPduTb *) - malloc(sizeof(Protocol__FlexRlcPduTb)); - protocol__flex_rlc_pdu_tb__init(rlc_pdus - [channels_added]->rlc_pdu_tb - [1]); - rlc_pdus[channels_added]-> - rlc_pdu_tb[1]->has_logical_channel_id = 1; - rlc_pdus[channels_added]-> - rlc_pdu_tb[1]->logical_channel_id = j; - rlc_pdus[channels_added]->rlc_pdu_tb[1]-> - has_size = 1; - rlc_pdus[channels_added]->rlc_pdu_tb[1]->size = - data_to_request; - dl_data[num_ues_added]->n_rlc_pdu++; - channels_added++; - //Set this to the max value that we might request - sdu_length_total += data_to_request; - } else { - //Take back the assumption of a header for this channel - header_len -= 3; - } //End rlc_status.bytes_in_buffer <= 0 - } //end of if dci_tbs - ta_len - header_len > 0 - } // End of iterating the logical channels - - // Add rlc_pdus to the dl_data message - dl_data[num_ues_added]->rlc_pdu = (Protocol__FlexRlcPdu **) - malloc(sizeof(Protocol__FlexRlcPdu *) * - dl_data[num_ues_added]->n_rlc_pdu); - for (i = 0; i < dl_data[num_ues_added]->n_rlc_pdu; i++) { - 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)) { - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - 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) { - nb_rb = 4; // don't let the TBS get too small - } else { - nb_rb = min_rb_unit[CC_id]; - } - - LOG_D(MAC, - "[TEST]The initial number of resource blocks was %d\n", - nb_rb); - LOG_D(MAC, "[TEST] The initial mcs was %d\n", mcs_tmp); - - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - LOG_D(MAC, - "[TEST]The TBS during rate matching was %d\n", - TBS); - - while (TBS < (sdu_length_total + header_len + ta_len)) { - nb_rb += min_rb_unit[CC_id]; // - LOG_D(MAC, - "[TEST]Had to increase the number of RBs\n"); - if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = - mac_xface->get_TBS_DL(mcs_tmp, - nb_available_rb); - nb_rb = nb_available_rb; - break; - } - - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - LOG_D(MAC, - "[TEST]We had the exact number of rbs. Time to fill the rballoc subband\n"); - for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - LOG_D(MAC, - "[TEST]Will only partially fill the bitmap\n"); - while ((nb_rb_temp > 0) - && (j < flexran_get_N_RBG(mod_id, CC_id))) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - if ((j == - flexran_get_N_RBG(mod_id, CC_id) - 1) - && - ((flexran_get_N_RB_DL(mod_id, CC_id) == - 25) - || (flexran_get_N_RB_DL(mod_id, CC_id) - == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - j = j + 1; - } - } - - 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]; - - for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - PHY_vars_eNB_g[mod_id][CC_id]-> - mu_mimo_mode[UE_id].rballoc_sub[j] = - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband - [harq_pid][j]; - } - - // decrease mcs until TBS falls below required length - while ((TBS > (sdu_length_total + header_len + ta_len)) - && (mcs_tmp > 0)) { - mcs_tmp--; - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - } - - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < (sdu_length_total + header_len + ta_len)) - && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) - && (mcs_tmp < 28)) - || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) - && (mcs_tmp <= 15)))) { - mcs_tmp++; - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - } - - dci_tbs = TBS; - mcs = mcs_tmp; - LOG_D(FLEXRAN_AGENT, "Final mcs was %d\n", mcs); - - dl_dci->has_aggr_level = 1; - dl_dci->aggr_level = aggregation; - - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = - nb_rb; - - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - UE_list->UE_template[CC_id][UE_id].DAI++; - // printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); - //#warning only for 5MHz channel - update_ul_dci(mod_id, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI,frame); - } - // 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) + 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; - - 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); - - 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)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < - (target_rx_power - 1)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - LOG_D(MAC, - "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - mod_id, frame, subframe, harq_pid, tpc, - tpc_accumulated, normalized_rx_power, - target_rx_power); - } // Po_PUCCH has been updated - else { - tpc = 1; //0 - } // time to do TPC update - else { - tpc = 1; //0 - } - - for (i = 0; - i < - PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RBG; - i++) { - rballoc_sub[i] = - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband - [harq_pid][i]; - } - - // Toggle NDI - LOG_D(MAC, - "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frame, subframe, UE_id, - UE_list->UE_template[CC_id][UE_id].rnti, - harq_pid, - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]); - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = - 1 - - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - ndi = - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - - UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid] = - tpc; - - // Increase the pointer for the number of scheduled UEs - num_ues_added++; - ue_has_transmission = 1; - } else { // There is no data from RLC or MAC header, so don't schedule - ue_has_transmission = 0; - } - } // End of new scheduling - - // If we has transmission or retransmission - if (ue_has_transmission) { - switch (mac_xface-> - get_transmission_mode(mod_id, CC_id, rnti)) { - case 1: - case 2: - default: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = - PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = - allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->n_tbs_size = 1; - dl_dci->tbs_size = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - } - break; - case 3: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = - PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = - allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 2; - dl_dci->ndi = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->ndi[1] = ndi; - dl_dci->n_rv = 2; - dl_dci->rv = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->rv[1] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 2; - dl_dci->mcs = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = mcs; - dl_dci->n_tbs_size = 2; - dl_dci->tbs_size = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - dl_dci->tbs_size[1] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - } - break; - case 4: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = - PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = - allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 2; - dl_dci->ndi = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->ndi[1] = ndi; - dl_dci->n_rv = 2; - dl_dci->rv = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->rv[1] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 2; - dl_dci->mcs = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = mcs; - dl_dci->n_tbs_size = 2; - dl_dci->tbs_size = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - dl_dci->tbs_size[1] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - } - break; - case 5: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = - PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = - allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->n_tbs_size = 1; - dl_dci->tbs_size = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - } - - if (ue_sched_ctl->dl_pow_off[CC_id] == 2) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - - dl_dci->has_dl_power_offset = 1; - dl_dci->dl_power_offset = - ue_sched_ctl->dl_pow_off[CC_id]; - dl_dci->has_precoding_info = 1; - dl_dci->precoding_info = 5; // Is this right?? - - break; - case 6: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = - PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = - allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = - (uint32_t *) malloc(sizeof(uint32_t) * - dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - } - - dl_dci->has_dl_power_offset = 1; - dl_dci->dl_power_offset = - ue_sched_ctl->dl_pow_off[CC_id]; - dl_dci->has_precoding_info = 1; - dl_dci->precoding_info = 5; // Is this right?? - break; - } - } - - if (flexran_get_duplex_mode(mod_id, CC_id) == - PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - - /* TODO */ - //set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe, frame_parms); - } - } // UE_id loop - } // CC_id loop - - // Add all the dl_data elements to the flexran message - int offset = (*dl_info)->dl_mac_config_msg->n_dl_ue_data; - (*dl_info)->dl_mac_config_msg->n_dl_ue_data += num_ues_added; - if (num_ues_added > 0) { - (*dl_info)->dl_mac_config_msg->dl_ue_data = - (Protocol__FlexDlData **) - realloc((*dl_info)->dl_mac_config_msg->dl_ue_data, - sizeof(Protocol__FlexDlData *) * - ((*dl_info)->dl_mac_config_msg->n_dl_ue_data)); - if ((*dl_info)->dl_mac_config_msg->dl_ue_data == NULL) { - LOG_E(MAC, "Request for memory reallocation failed\n"); - return; - } - for (i = 0; i < num_ues_added; i++) { - (*dl_info)->dl_mac_config_msg->dl_ue_data[offset + i] = - dl_data[i]; - } - } - - stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); -} diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c deleted file mode 100644 index 68c86f1da54671e4110c5bb6bb8a610be210725a..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c +++ /dev/null @@ -1,202 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 flexran_agent_scheduler_dlsch_ue_remote.c - * \brief procedures related to remote scheduling in the DLSCH transport channel - * \author Xenofon Foukas - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#include "flexran_agent_common_internal.h" - -#include "flexran_agent_scheduler_dlsch_ue_remote.h" - -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" - -struct DlMacConfigHead queue_head; - -int queue_initialized = 0; - -//uint32_t skip_subframe = 1; -//uint32_t period = 10; -//uint32_t sched [] = {1, 2, 3}; - -void -flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, - uint32_t subframe, int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - - - //if ((subframe == skip_subframe) && (frame % period == 0)) { - // LOG_I(MAC, "Will skip subframe %d %d\n", subframe, frame); - // for (int i = 0; i < 3; i++) { - // LOG_I(MAC, "%d\n", sched[i]); - // } - //} - - /* if (frame == 500 && subframe == 1) { */ - /* char policy[] = "rrc: \n - ul_scheduler: \n behavior : tester_function\n parameters:\n period: !!int 3\nmac: \n - dl_scheduler: \n parameters: \n period : !!int 40\n skip_subframe : !!int 3\n sched : [!!int 4, !!int 5, !!int 6]"; */ - /* apply_reconfiguration_policy(mod_id, policy, strlen(policy)); */ - /* } */ - - eNB_MAC_INST *eNB; - - if (!queue_initialized) { - TAILQ_INIT(&queue_head); - queue_initialized = 1; - } - - eNB = &eNB_mac_inst[mod_id]; - - dl_mac_config_element_t *dl_config_elem; - - int diff; - LOG_D(MAC, "[TEST] Current frame and subframe %d, %d\n", frame, - subframe); - // First we check to see if we have a scheduling decision for this sfn_sf already in our queue - while (queue_head.tqh_first != NULL) { - dl_config_elem = queue_head.tqh_first; - - diff = - get_sf_difference(mod_id, - dl_config_elem->dl_info-> - dl_mac_config_msg->sfn_sf); - // Check if this decision is for now, for a later or a previous subframe - if (diff == 0) { // Now - LOG_D(MAC, - "Found a decision for this subframe in the queue. Let's use it!\n"); - TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs); - *dl_info = dl_config_elem->dl_info; - free(dl_config_elem); - eNB->eNB_stats[mod_id].sched_decisions++; - return; - } else if (diff < 0) { //previous subframe , delete message and free memory - LOG_D(MAC, - "Found a decision for a previous subframe in the queue. Let's get rid of it\n"); - TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs); - flexran_agent_mac_destroy_dl_config(dl_config_elem->dl_info); - free(dl_config_elem); - eNB->eNB_stats[mod_id].sched_decisions++; - eNB->eNB_stats[mod_id].missed_deadlines++; - } else { // next subframe, nothing to do now - LOG_D(MAC, - "Found a decision for a future subframe in the queue. Nothing to do now\n"); - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); - return; - } - } - - //Done with the local cache. Now we need to check if something new arrived - flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); - while (*dl_info != NULL) { - - diff = - get_sf_difference(mod_id, - (*dl_info)->dl_mac_config_msg->sfn_sf); - if (diff == 0) { // Got a command for this sfn_sf - LOG_D(MAC, - "Found a decision for this subframe pending. Let's use it\n"); - eNB->eNB_stats[mod_id].sched_decisions++; - return; - } else if (diff < 0) { - LOG_D(MAC, - "Found a decision for a previous subframe. Let's get rid of it\n"); - flexran_agent_mac_destroy_dl_config(*dl_info); - *dl_info = NULL; - flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); - eNB->eNB_stats[mod_id].sched_decisions++; - eNB->eNB_stats[mod_id].missed_deadlines++; - } else { // Intended for future subframe. Store it in local cache - LOG_D(MAC, - "Found a decision for a future subframe in the queue. Let's store it in the cache\n"); - dl_mac_config_element_t *e = - malloc(sizeof(dl_mac_config_element_t)); - e->dl_info = *dl_info; - TAILQ_INSERT_TAIL(&queue_head, e, configs); - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); - // No need to look for another. Messages arrive ordered - return; - } - } - - // We found no pending command, so we will simply pass an empty one - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); -} - -int get_sf_difference(mid_t mod_id, uint32_t sfn_sf) -{ - int diff_in_subframes; - - uint16_t current_frame = flexran_get_current_system_frame_num(mod_id); - uint16_t current_subframe = flexran_get_current_subframe(mod_id); - uint32_t current_sfn_sf = flexran_get_sfn_sf(mod_id); - - if (sfn_sf == current_sfn_sf) { - return 0; - } - - uint16_t frame_mask = ((1 << 12) - 1); - uint16_t frame = (sfn_sf & (frame_mask << 4)) >> 4; - - uint16_t sf_mask = ((1 << 4) - 1); - uint16_t subframe = (sfn_sf & sf_mask); - - LOG_D(MAC, "[TEST] Target frame and subframe %d, %d\n", frame, - subframe); - - if (frame == current_frame) { - return subframe - current_subframe; - } else if (frame > current_frame) { - diff_in_subframes = - ((frame * 10) + subframe) - ((current_frame * 10) + - current_subframe); - - // diff_in_subframes = 9 - current_subframe; - //diff_in_subframes += (subframe + 1); - //diff_in_subframes += (frame-2) * 10; - if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) { - return -1; - } else { - return 1; - } - } else { //frame < current_frame - //diff_in_subframes = 9 - current_subframe; - //diff_in_subframes += (subframe + 1); - //if (frame > 0) { - // diff_in_subframes += (frame - 1) * 10; - //} - //diff_in_subframes += (1023 - current_frame) * 10; - diff_in_subframes = - 10240 - ((current_frame * 10) + current_subframe) + - ((frame * 10) + subframe); - if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) { - return -1; - } else { - return 1; - } - } -} diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h deleted file mode 100644 index 449ba1e8cde85e8c6001178f9e68534590b9952f..0000000000000000000000000000000000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h +++ /dev/null @@ -1,70 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 flexran_agent_scheduler_dlsch_ue_remote.h - * \brief Local stub for remote scheduler used by the controller - * \author Xenofon Foukas - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#ifndef __LAYER2_MAC_FLEXRAN_AGENT_SCHEDULER_DLSCH_UE_REMOTE_H__ -#define __LAYER2_MAC_FLEXRAN_AGENT_SCHEDULER_DLSCH_UE_REMOTE_H___ - -#include "flexran.pb-c.h" -#include "header.pb-c.h" - -#include "ENB_APP/flexran_agent_defs.h" -#include "flexran_agent_mac.h" -#include "LAYER2/MAC/flexran_agent_mac_proto.h" - -#include <sys/queue.h> - -// Maximum value of schedule ahead of time -// Required to identify if a dl_command is for the future or not -#define SCHED_AHEAD_SUBFRAMES 20 - -typedef struct dl_mac_config_element_s { - Protocol__FlexranMessage *dl_info; - TAILQ_ENTRY(dl_mac_config_element_s) configs; -} dl_mac_config_element_t; - -TAILQ_HEAD(DlMacConfigHead, dl_mac_config_element_s); - -/* - * Default scheduler used by the eNB agent - */ -void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, - uint32_t subframe, int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - - -// Find the difference in subframes from the given subframe -// negative for older value -// 0 for equal -// positive for future value -// Based on -int get_sf_difference(mid_t mod_id, uint32_t sfn_sf); - -#endif diff --git a/openair2/LAYER2/MAC/l1_helpers.c b/openair2/LAYER2/MAC/l1_helpers.c index 6e71f66ec5f56d32a52863db3fde89d6594b9b20..0cb5c17f0f6984f22c1ac3cbb77c74b1770aa394 100644 --- a/openair2/LAYER2/MAC/l1_helpers.c +++ b/openair2/LAYER2/MAC/l1_helpers.c @@ -29,10 +29,10 @@ */ -#include "defs.h" -#include "extern.h" +#include "mac.h" +#include "mac_extern.h" #include "UTIL/LOG/log.h" -#include "proto.h" +#include "mac_proto.h" int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id) { @@ -54,6 +54,52 @@ int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id) 1) + get_DELTA_PREAMBLE(module_idP, CC_id)); } +int8_t get_DELTA_PREAMBLE(module_id_t module_idP, int CC_id) +{ + + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + uint8_t prachConfigIndex = + UE_mac_inst[module_idP].radioResourceConfigCommon-> + prach_Config.prach_ConfigInfo.prach_ConfigIndex; + uint8_t preambleformat; + + if (UE_mac_inst[module_idP].tdd_Config) { // TDD + if (prachConfigIndex < 20) { + preambleformat = 0; + } else if (prachConfigIndex < 30) { + preambleformat = 1; + } else if (prachConfigIndex < 40) { + preambleformat = 2; + } else if (prachConfigIndex < 48) { + preambleformat = 3; + } else { + preambleformat = 4; + } + } else { // FDD + preambleformat = prachConfigIndex >> 2; + } + + switch (preambleformat) { + case 0: + case 1: + return (0); + + case 2: + case 3: + return (-3); + + case 4: + return (8); + + default: + AssertFatal(1 == 0, + "[UE %d] ue_procedures.c: FATAL, Illegal preambleformat %d, prachConfigIndex %d\n", + module_idP, preambleformat, prachConfigIndex); + } + +} + int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id) { diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/mac.h similarity index 74% rename from openair2/LAYER2/MAC/defs.h rename to openair2/LAYER2/MAC/mac.h index 2315d59b8fe5fdec1b8d0f4e27e7203eb2c1ffbd..8bef29101be6b63b3b09746a0f261cbd9e15a3e5 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/mac.h @@ -43,11 +43,10 @@ #include <stdlib.h> #include <string.h> -#include "PHY/defs.h" -#include "PHY/LTE_TRANSPORT/defs.h" #include "COMMON/platform_constants.h" #include "BCCH-BCH-Message.h" #include "RadioResourceConfigCommon.h" +#include "RadioResourceConfigCommonSIB.h" #include "RadioResourceConfigDedicated.h" #include "MeasGapConfig.h" #include "SchedulingInfoList.h" @@ -55,19 +54,29 @@ #include "RACH-ConfigCommon.h" #include "MeasObjectToAddModList.h" #include "MobilityControlInfo.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-SubframeConfigList.h" #include "PMCH-InfoList-r9.h" +#endif +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "SCellToAddMod-r10.h" #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) #include "SystemInformationBlockType1-v1310-IEs.h" +#include "SystemInformationBlockType18-r12.h" #endif - +#include "RadioResourceConfigCommonSIB.h" #include "nfapi_interface.h" #include "PHY_INTERFACE/IF_Module.h" +#include "PHY/TOOLS/time_meas.h" + +#include "PHY/defs_common.h" // for PRACH_RESOURCES_t +#include "PHY/LTE_TRANSPORT/transport_common.h" + +#include "targets/ARCH/COMMON/common_lib.h" + /** @defgroup _mac MAC * @ingroup _oai2 * @{ @@ -79,9 +88,10 @@ #define RAR_PAYLOAD_SIZE_MAX 128 #define SCH_PAYLOAD_SIZE_MAX 8192 +#define DCH_PAYLOAD_SIZE_MAX 4096 /// Logical channel ids from 36-311 (Note BCCH is not specified in 36-311, uses the same as first DRB) -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Mask for identifying subframe for MBMS #define MBSFN_TDD_SF3 0x80 // for TDD @@ -155,15 +165,16 @@ /*!\brief maximum number of slices / groups */ #define MAX_NUM_SLICES 4 + #define U_PLANE_INACTIVITY_VALUE 6000 -/* - * eNB part +/* + * eNB part */ -/* - * UE/ENB common part +/* + * UE/ENB common part */ /*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */ typedef struct { @@ -233,6 +244,75 @@ typedef struct { uint8_t R:2; } __attribute__ ((__packed__)) SCH_SUBHEADER_FIXED; + + +/*!\brief MAC subheader long with 24bit DST field */ +typedef struct { + uint8_t R0:4; + uint8_t V:4;//Version number: Possible values "0001", "0010", "0011" based on TS36.321 section 6.2.3. + uint8_t SRC07; //Prose UE source ID. Size 24 bits. + uint8_t SRC815; //Prose UE source ID. Size 24 bits. + uint8_t SRC1623; //Prose UE source ID. Size 24 bits. + uint8_t DST07; //Prose UE destination ID. Size 24 bits. + uint8_t DST815; //Prose UE destination ID. Size 24 bits. + uint8_t DST1623; //Prose UE destination ID. Size 24 bits. + uint8_t LCID:5; + uint8_t E:1; + uint8_t R1:2; + uint8_t L:7; // Length field indicating the size of the corresponding SDU in bytes. + uint8_t F:1; +}__attribute__((__packed__))SLSCH_SUBHEADER_24_Bit_DST_SHORT; + +/*!\brief MAC subheader long with 24bit DST field */ +typedef struct { + uint8_t R0:4; + uint8_t V:4;//Version number: Possible values "0001", "0010", "0011" based on TS36.321 section 6.2.3. + uint8_t SRC07; //Prose UE source ID. Size 24 bits. + uint8_t SRC815; //Prose UE source ID. Size 24 bits. + uint8_t SRC1623; //Prose UE source ID. Size 24 bits. + uint8_t DST07; //Prose UE destination ID. Size 24 bits. + uint8_t DST815; //Prose UE destination ID. Size 24 bits. + uint8_t DST1623; //Prose UE destination ID. Size 24 bits. + uint8_t LCID:5; + uint8_t E:1; + uint8_t R1:2; + uint8_t L_MSB:7; // Length field indicating the size of the corresponding SDU in bytes. + uint8_t F:1; + uint8_t L_LSB:8; +}__attribute__((__packed__))SLSCH_SUBHEADER_24_Bit_DST_LONG; + +/*!\brief MAC subheader long with 24bit DST field */ +typedef struct { + uint8_t R0:4; + uint8_t V:4;//Version number: Possible values "0001", "0010", "0011" based on TS36.321 section 6.2.3. + uint8_t SRC07; //Prose UE source ID. Size 24 bits. + uint8_t SRC815; //Prose UE source ID. Size 24 bits. + uint8_t DST07; //Prose UE destination ID. Size 16 bits. + uint8_t DST815; //Prose UE destination ID. Size 16 bits. + uint8_t LCID:5; + uint8_t E:1; + uint8_t R1:2; + uint8_t L:7; // Length field indicating the size of the corresponding SDU in bytes. + uint8_t F:1; +}__attribute__((__packed__))SLSCH_SUBHEADER_16_Bit_DST_SHORT; + +/*!\brief MAC subheader long with 24bit DST field */ +typedef struct { + uint8_t R0:4; + uint8_t V:4;//Version number: Possible values "0001", "0010", "0011" based on TS36.321 section 6.2.3. + uint8_t SRC07; //Prose UE source ID. Size 24 bits. + uint8_t SRC815; //Prose UE source ID. Size 24 bits. + uint8_t SRC1623; //Prose UE source ID. Size 24 bits. + uint8_t DST07; //Prose UE destination ID. Size 16 bits. + uint8_t DST815; //Prose UE destination ID. Size 16 bits. + uint8_t LCID:5; + uint8_t E:1; + uint8_t R1:2; + uint8_t L_MSB:7; // Length field indicating the size of the corresponding SDU in bytes. + uint8_t F:1; + uint8_t L_LSB:8; +}__attribute__((__packed__))SLSCH_SUBHEADER_16_Bit_DST_LONG; + /*!\brief mac control element: short buffer status report for a specific logical channel group ID*/ typedef struct { uint8_t Buffer_size:6; // octet 1 LSB @@ -248,6 +328,30 @@ typedef struct { uint8_t Buffer_size0:6; } __attribute__ ((__packed__)) BSR_LONG; +// Panos: +/*!\brief mac control element: sidelink buffer status report */ +typedef struct { + uint8_t DST_1:4; + uint8_t LCGID_1: 2; + uint8_t Buffer_size_1:6; + uint8_t DST_2:4; + uint8_t LCGID_2: 2; + uint8_t Buffer_size_2:6; +}__attribute__((__packed__))SL_BSR; + +/*!\brief mac control element: truncated sidelink buffer status report */ +typedef struct { + uint8_t DST:4; + uint8_t LCGID: 2; + uint8_t Buffer_size:6; + uint8_t R1:1; + uint8_t R2:1; + uint8_t R3:1; + uint8_t R4:1; +}__attribute__((__packed__))SL_BSR_Truncated; + + + #define BSR_LONG_SIZE (sizeof(BSR_LONG)) /*!\brief mac control element: timing advance */ typedef struct { @@ -281,7 +385,7 @@ typedef struct { uint8_t payload[PCCH_PAYLOAD_SIZE_MAX]; } __attribute__ ((__packed__)) PCCH_PDU; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*! \brief MCCH payload */ typedef struct { uint8_t payload[MCCH_PAYLOAD_SIZE_MAX]; @@ -338,7 +442,7 @@ typedef struct { /*!\brief LCID of padding LCID for DLSCH */ #define SHORT_PADDING 31 -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // MCH LCHAN IDs (table6.2.1-4 TS36.321) /*!\brief LCID of MCCH for DL */ #define MCCH_LCHANID 0 @@ -346,6 +450,9 @@ typedef struct { #define MCH_SCHDL_INFO 3 /*!\brief LCID of Carrier component activation/deactivation */ #define CC_ACT_DEACT 27 +//TTN (for D2D) +#define SL_DISCOVERY 8 //LCID (fake) +#define MAX_NUM_DEST 10 #endif // ULSCH LCHAN IDs @@ -392,7 +499,11 @@ typedef struct { uint16_t Pdu_size; } __attribute__ ((__packed__)) ULSCH_PDU; -#include "PHY/impl_defs_top.h" +/*! \brief Uplink SCH PDU Structure */ +typedef struct { + int8_t payload[DCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */ + uint16_t Pdu_size; +} __attribute__ ((__packed__)) ULDCH_PDU; /*!\brief RA process state*/ typedef enum { @@ -456,20 +567,20 @@ typedef struct { } eNB_DLSCH_INFO; /*! \brief eNB overall statistics */ typedef struct { - /// num BCCH PDU per CC + /// num BCCH PDU per CC uint32_t total_num_bcch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t bcch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_bcch_buffer; /// BCCH MCS uint32_t bcch_mcs; - /// num CCCH PDU per CC + /// num CCCH PDU per CC uint32_t total_num_ccch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t ccch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_ccch_buffer; /// BCCH MCS uint32_t ccch_mcs; @@ -530,7 +641,6 @@ typedef struct { } eNB_STATS; /*! \brief eNB statistics for the connected UEs*/ typedef struct { - /// CRNTI of UE rnti_t crnti; ///user id (rnti) of connected UEs // rrc status @@ -570,6 +680,13 @@ typedef struct { uint32_t num_retransmission; /// instantaneous tx throughput for each TTI // uint32_t tti_throughput[NB_RB_MAX]; + // Number of received MAC SDU + uint32_t num_mac_sdu_tx; + // LCID related to SDU + unsigned char lcid_sdu[NB_RB_MAX]; + // Length of SDU Got from LC DL + uint32_t sdu_length_tx[NB_RB_MAX]; + /// overall // @@ -616,6 +733,8 @@ typedef struct { /// uplink transport block size uint32_t ulsch_TBS; + uint32_t total_ulsch_TBS; + /// total rb used for a new uplink transmission uint32_t num_retransmission_rx; /// total rb used for a new uplink transmission @@ -624,9 +743,9 @@ typedef struct { uint32_t rbs_used_retx_rx; /// total rb used for a new uplink transmission uint32_t total_rbs_used_rx; - /// normalized rx power + /// normalized rx power int32_t normalized_rx_power; - /// target rx power + /// target rx power int32_t target_rx_power; /// num rx pdu @@ -656,6 +775,10 @@ typedef struct { uint32_t total_num_pdus_rx; /// num of error pdus uint32_t total_num_errors_rx; + // Number of error PDUS + uint32_t num_mac_sdu_rx; + // Length of SDU Got from LC UL - Size array can be refined + uint32_t sdu_length_rx[NB_RB_MAX]; } eNB_UE_STATS; /*! \brief eNB template for UE context information */ @@ -673,7 +796,7 @@ typedef struct { /// mcs from last UL scheduling uint8_t mcs_UL[8]; /// TBS from last UL scheduling - uint16_t TBS_UL[8]; + int TBS_UL[8]; /// Flag to indicate UL has been scheduled at least once boolean_t ul_active; /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received) @@ -700,7 +823,7 @@ typedef struct { uint16_t cshift[8]; // num_max_harq /// Number of Allocated RBs by the ulsch preprocessor - uint8_t pre_allocated_nb_rb_ul; + uint8_t pre_allocated_nb_rb_ul[MAX_NUM_SLICES]; /// index of Allocated RBs by the ulsch preprocessor int8_t pre_allocated_rb_table_index_ul; @@ -728,9 +851,6 @@ typedef struct { // Logical channel info for link with RLC - /// Last received UE BSR info for each logical channel group id - uint8_t bsr_info[MAX_NUM_LCGID]; - /// LCGID mapping long lcgidmap[11]; @@ -752,13 +872,11 @@ typedef struct { uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID]; /// maximum creation time of the downlink buffer head across all LCID uint32_t dl_buffer_head_sdu_creation_time_max; - /// a flag indicating that the downlink head SDU is segmented + /// a flag indicating that the downlink head SDU is segmented uint8_t dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID]; /// size of remaining size to send for the downlink head SDU uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID]; - /// total uplink buffer size - uint32_t ul_total_buffer; /// uplink buffer creation time for each LCID uint32_t ul_buffer_creation_time[MAX_NUM_LCGID]; /// maximum uplink buffer creation time across all the LCIDs @@ -766,6 +884,11 @@ typedef struct { /// uplink buffer size per LCID uint32_t ul_buffer_info[MAX_NUM_LCGID]; + /// uplink bytes that are currently scheduled + int scheduled_ul_bytes; + /// estimation of the UL buffer size + int estimated_ul_buffer; + /// UE tx power int32_t ue_tx_power; @@ -779,7 +902,7 @@ typedef struct { eNB_UE_estimated_distances distance; #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t rach_resource_type; uint16_t mpdcch_repetition_cnt; frame_t Msg2_frame; @@ -811,7 +934,8 @@ typedef struct { ///Contention resolution timer used during random access uint8_t mac_ContentionResolutionTimer; - uint16_t max_allowed_rbs[MAX_NUM_LCID]; + uint16_t max_rbs_allowed_slice[NFAPI_CC_MAX][MAX_NUM_SLICES]; + uint16_t max_rbs_allowed_slice_uplink[NFAPI_CC_MAX][MAX_NUM_SLICES]; uint8_t max_mcs[MAX_NUM_LCID]; @@ -820,14 +944,14 @@ typedef struct { // resource scheduling information /// Current DL harq round per harq_pid on each CC - uint8_t round[MAX_NUM_CCs][10]; + uint8_t round[NFAPI_CC_MAX][10]; /// Current Active TBs per harq_pid on each CC - uint8_t tbcnt[MAX_NUM_CCs][10]; + uint8_t tbcnt[NFAPI_CC_MAX][10]; /// Current UL harq round per harq_pid on each CC - uint8_t round_UL[MAX_NUM_CCs][8]; - uint8_t dl_pow_off[MAX_NUM_CCs]; - uint16_t pre_nb_available_rbs[MAX_NUM_CCs]; - unsigned char rballoc_sub_UE[MAX_NUM_CCs][N_RBG_MAX]; + uint8_t round_UL[NFAPI_CC_MAX][8]; + uint8_t dl_pow_off[NFAPI_CC_MAX]; + uint16_t pre_nb_available_rbs[NFAPI_CC_MAX]; + unsigned char rballoc_sub_UE[NFAPI_CC_MAX][N_RBG_MAX]; uint16_t ta_timer; int16_t ta_update; uint16_t ul_consecutive_errors; @@ -922,7 +1046,7 @@ typedef struct { int msg4_TBsize; /// MCS used for Msg4 int msg4_mcs; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t rach_resource_type; uint8_t msg2_mpdcch_repetition_cnt; uint8_t msg4_mpdcch_repetition_cnt; @@ -936,7 +1060,7 @@ typedef struct { /*! \brief subband bitmap confguration (for ALU icic algo purpose), in test phase */ typedef struct { - uint8_t sbmap[NUMBER_OF_SUBBANDS_MAX]; //13 = number of SB MAX for 100 PRB + uint8_t sbmap[13]; //13 = number of SB MAX for 100 PRB uint8_t periodicity; uint8_t first_subframe; uint8_t sb_size; @@ -946,34 +1070,38 @@ typedef struct { typedef struct { /// Dedicated information for UEs struct PhysicalConfigDedicated - *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// DLSCH pdu - DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX]; + *physicalConfigDedicated[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + /// DLSCH pdu + DLSCH_PDU DLSCH_pdu[NFAPI_CC_MAX][2][MAX_MOBILES_PER_ENB]; /// DCI template and MAC connection parameters for UEs - UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + UE_TEMPLATE UE_template[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; /// DCI template and MAC connection for RA processes - int pCC_id[NUMBER_OF_UE_MAX]; - /// sorted downlink component carrier for the scheduler - int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier - int numactiveCCs[NUMBER_OF_UE_MAX]; - /// sorted uplink component carrier for the scheduler - int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of uplink active component carrier - int numactiveULCCs[NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier - uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX]; + int pCC_id[MAX_MOBILES_PER_ENB]; + /// sorted downlink component carrier for the scheduler + int ordered_CCids[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + /// number of downlink active component carrier + int numactiveCCs[MAX_MOBILES_PER_ENB]; + /// sorted uplink component carrier for the scheduler + int ordered_ULCCids[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + /// number of uplink active component carrier + int numactiveULCCs[MAX_MOBILES_PER_ENB]; + /// number of downlink active component carrier + uint8_t dl_CC_bitmap[MAX_MOBILES_PER_ENB]; /// eNB to UE statistics - eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + eNB_UE_STATS eNB_UE_stats[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; /// scheduling control info - UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX]; - int next[NUMBER_OF_UE_MAX]; + UE_sched_ctrl UE_sched_ctrl[MAX_MOBILES_PER_ENB]; + int next[MAX_MOBILES_PER_ENB]; int head; - int next_ul[NUMBER_OF_UE_MAX]; + int next_ul[MAX_MOBILES_PER_ENB]; int head_ul; int avail; int num_UEs; - boolean_t active[NUMBER_OF_UE_MAX]; + boolean_t active[MAX_MOBILES_PER_ENB]; + + /// Sorting criteria for the UE list in the MAC preprocessor + uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; + } UE_list_t; /*! \brief deleting control information*/ @@ -1001,7 +1129,7 @@ typedef struct { uint32_t dl_CarrierFreq; BCCH_BCH_Message_t *mib; RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR; #endif TDD_Config_t *tdd_Config; @@ -1032,7 +1160,7 @@ typedef struct { struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /// MBMS Flag uint8_t MBMS_flag; /// Outgoing MCCH pdu for PHY @@ -1054,7 +1182,7 @@ typedef struct { /// Outgoing MCH pdu for PHY MCH_PDU MCH_pdu; #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) /// Rel13 parameters from SIB1 SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext; /// Counter for SIB1-BR scheduling @@ -1066,91 +1194,90 @@ typedef struct { /*! \brief top level eNB MAC structure */ typedef struct eNB_MAC_INST_s { /// Ethernet parameters for northbound midhaul interface - eth_params_t eth_params_n; - /// Ethernet parameters for fronthaul interface - eth_params_t eth_params_s; - /// - module_id_t Mod_id; - /// frame counter - frame_t frame; - /// subframe counter - sub_frame_t subframe; - /// Pointer to IF module instance for PHY - IF_Module_t *if_inst; - /// Common cell resources - COMMON_channels_t common_channels[MAX_NUM_CCs]; - /// current PDU index (BCH,MCH,DLSCH) - int16_t pdu_index[MAX_NUM_CCs]; - - /// NFAPI Config Request Structure - nfapi_config_request_t config[MAX_NUM_CCs]; - /// Preallocated DL pdu list - nfapi_dl_config_request_pdu_t - dl_config_pdu_list[MAX_NUM_CCs][MAX_NUM_DL_PDU]; - /// NFAPI DL Config Request Structure - nfapi_dl_config_request_t DL_req[MAX_NUM_CCs]; - /// Preallocated UL pdu list - nfapi_ul_config_request_pdu_t - ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU]; - /// Preallocated UL pdu list for ULSCH (n+k delay) - nfapi_ul_config_request_pdu_t - ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU]; - /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place - nfapi_ul_config_request_t UL_req[MAX_NUM_CCs]; - /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests - nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10]; - /// Preallocated HI_DCI0 pdu list - nfapi_hi_dci0_request_pdu_t - hi_dci0_pdu_list[MAX_NUM_CCs][10][MAX_NUM_HI_DCI0_PDU]; - /// NFAPI HI/DCI0 Config Request Structure - nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs][10]; - /// Prealocated TX pdu list - nfapi_tx_request_pdu_t - tx_request_pdu[MAX_NUM_CCs][MAX_NUM_TX_REQUEST_PDU]; - /// NFAPI DL PDU structure - nfapi_tx_request_t TX_req[MAX_NUM_CCs]; - /// UL handle - uint32_t ul_handle; - UE_list_t UE_list; - - ///subband bitmap configuration - SBMAP_CONF sbmap_conf; - /// CCE table used to build DCI scheduling information - int CCE_table[MAX_NUM_CCs][800]; - /// active flag for Other lcid - uint8_t lcid_active[NB_RB_MAX]; - /// eNB stats - eNB_STATS eNB_stats[MAX_NUM_CCs]; - // MAC function execution peformance profiler - /// processing time of eNB scheduler - time_stats_t eNB_scheduler; - /// processing time of eNB scheduler for SI - time_stats_t schedule_si; - /// processing time of eNB scheduler for Random access - time_stats_t schedule_ra; - /// processing time of eNB ULSCH scheduler - time_stats_t schedule_ulsch; - /// processing time of eNB DCI generation - time_stats_t fill_DLSCH_dci; - /// processing time of eNB MAC preprocessor - time_stats_t schedule_dlsch_preprocessor; - /// processing time of eNB DLSCH scheduler - time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor - /// processing time of eNB MCH scheduler - time_stats_t schedule_mch; - /// processing time of eNB ULSCH reception - time_stats_t rx_ulsch_sdu; // include rlc_data_ind - /// processing time of eNB PCH scheduler - time_stats_t schedule_pch; - - UE_free_list_t UE_free_list; - /// for scheduling selection - SCHEDULER_MODES scheduler_mode; - + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface + eth_params_t eth_params_s; + /// + module_id_t Mod_id; + /// frame counter + frame_t frame; + /// subframe counter + sub_frame_t subframe; + /// Pointer to IF module instance for PHY + IF_Module_t *if_inst; + /// Common cell resources + COMMON_channels_t common_channels[NFAPI_CC_MAX]; + /// current PDU index (BCH,MCH,DLSCH) + int16_t pdu_index[NFAPI_CC_MAX]; + + /// NFAPI Config Request Structure + nfapi_config_request_t config[NFAPI_CC_MAX]; + /// Preallocated DL pdu list + nfapi_dl_config_request_pdu_t + dl_config_pdu_list[NFAPI_CC_MAX][MAX_NUM_DL_PDU]; + /// NFAPI DL Config Request Structure + nfapi_dl_config_request_t DL_req[NFAPI_CC_MAX]; + /// Preallocated UL pdu list + nfapi_ul_config_request_pdu_t + ul_config_pdu_list[NFAPI_CC_MAX][MAX_NUM_UL_PDU]; + /// Preallocated UL pdu list for ULSCH (n+k delay) + nfapi_ul_config_request_pdu_t + ul_config_pdu_list_tmp[NFAPI_CC_MAX][10][MAX_NUM_UL_PDU]; + /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place + nfapi_ul_config_request_t UL_req[NFAPI_CC_MAX]; + /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests + nfapi_ul_config_request_t UL_req_tmp[NFAPI_CC_MAX][10]; + /// Preallocated HI_DCI0 pdu list + nfapi_hi_dci0_request_pdu_t + hi_dci0_pdu_list[NFAPI_CC_MAX][10][MAX_NUM_HI_DCI0_PDU]; + /// NFAPI HI/DCI0 Config Request Structure + nfapi_hi_dci0_request_t HI_DCI0_req[NFAPI_CC_MAX][10]; + /// Prealocated TX pdu list + nfapi_tx_request_pdu_t + tx_request_pdu[NFAPI_CC_MAX][MAX_NUM_TX_REQUEST_PDU]; + /// NFAPI DL PDU structure + nfapi_tx_request_t TX_req[NFAPI_CC_MAX]; + /// UL handle + uint32_t ul_handle; + UE_list_t UE_list; + + ///subband bitmap configuration + SBMAP_CONF sbmap_conf; + /// CCE table used to build DCI scheduling information + int CCE_table[NFAPI_CC_MAX][800]; + /// active flag for Other lcid + uint8_t lcid_active[NB_RB_MAX]; + /// eNB stats + eNB_STATS eNB_stats[NFAPI_CC_MAX]; + // MAC function execution peformance profiler + /// processing time of eNB scheduler + time_stats_t eNB_scheduler; + /// processing time of eNB scheduler for SI + time_stats_t schedule_si; + /// processing time of eNB scheduler for Random access + time_stats_t schedule_ra; + /// processing time of eNB ULSCH scheduler + time_stats_t schedule_ulsch; + /// processing time of eNB DCI generation + time_stats_t fill_DLSCH_dci; + /// processing time of eNB MAC preprocessor + time_stats_t schedule_dlsch_preprocessor; + /// processing time of eNB DLSCH scheduler + time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor + /// processing time of eNB MCH scheduler + time_stats_t schedule_mch; + /// processing time of eNB ULSCH reception + time_stats_t rx_ulsch_sdu; // include rlc_data_ind + /// processing time of eNB PCH scheduler + time_stats_t schedule_pch; + + UE_free_list_t UE_free_list; + /// for scheduling selection + SCHEDULER_MODES scheduler_mode; } eNB_MAC_INST; -/* - * UE part +/* + * UE part */ typedef enum { @@ -1254,10 +1381,36 @@ typedef struct { struct RACH_ConfigDedicated *rach_ConfigDedicated; /// pointer to RRC PHY configuration struct PhysicalConfigDedicated *physicalConfigDedicated; -#if defined(Rel10) || defined(Rel14) - /// pointer to RRC PHY configuration SCEll - struct PhysicalConfigDedicatedSCell_r10 - *physicalConfigDedicatedSCell_r10; +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + /// pointer to RRC PHY configuration SCEll + struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10; + /// Preconfiguration for Sidelink + struct SL_Preconfiguration_r12 *SL_Preconfiguration; + /// RX Pool for Sidelink from SIB18 + SL_CommRxPoolList_r12_t commRxPool_r12; + /// TX Pool Normal for Sidelink from SIB18 + struct SL_CommTxPoolList_r12 *commTxPoolNormalCommon_r12; + /// TX Pool Exceptional for Sidelink from SIB18 + struct SL_CommTxPoolList_r12 *commTxPoolExceptional_r12; + /// Common Sync Config for Sidelink from SIB18 + struct SL_SyncConfigList_r12 *commSyncConfig_r12; + /// Dedicated Sync TX control for Sidelink + struct SL_SyncTxControl_r12 *sl_SyncTxControl_r12; + /// Dedicated Discovery TX control for Sidelink + struct SL_DiscConfig_r12 *sl_DiscConfig_r12; + /// Dedicated TX config for Sidelink + struct SL_CommConfig_r12 *sl_CommConfig_r12; + //SL sourceL2ID + uint32_t sourceL2Id; + //SL groupL2Id + uint32_t groupL2Id; + //SL destinationL2Id + uint32_t destinationL2Id; + //List of destinations + uint32_t destinationList[MAX_NUM_DEST]; + uint8_t numCommFlows; + uint32_t SL_LCID[MAX_NUM_LCID]; + #endif /// pointer to TDD Configuration (NULL for FDD) TDD_Config_t *tdd_Config; @@ -1278,7 +1431,14 @@ typedef struct { /// Outgoing RAR pdu for PHY RAR_PDU RAR_pdu; /// Incoming DLSCH pdu for PHY - DLSCH_PDU DLSCH_pdu[NUMBER_OF_UE_MAX][2]; + DLSCH_PDU DLSCH_pdu[MAX_MOBILES_PER_ENB][2]; +#ifdef Rel14 + int sltx_active; + SLSCH_t slsch; + SLDCH_t sldch; + ULSCH_PDU slsch_pdu; + int slsch_lcid; +#endif /// number of attempt for rach uint8_t RA_attempt_number; /// Random-access procedure flag @@ -1319,7 +1479,7 @@ typedef struct { /// power backoff due to power management (as allowed by P-MPRc) for this cell uint8_t PHR_reporting_active; /// power backoff due to power management (as allowed by P-MPRc) for this cell - uint8_t power_backoff_db[NUMBER_OF_eNB_MAX]; + uint8_t power_backoff_db[MAX_eNB]; /// BSR report falg management uint8_t BSR_reporting_active; /// retxBSR-Timer expires flag @@ -1331,7 +1491,7 @@ typedef struct { struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) /// number of active MBSFN area uint8_t num_active_mbsfn_area; /// MBSFN Area Info @@ -1343,26 +1503,41 @@ typedef struct { /// MSI status uint8_t msi_status; // could be an array if there are >1 MCH in one MBSFN area #endif - //#ifdef CBA - /// CBA RNTI for each group - uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; - /// last SFN for CBA channel access - uint8_t cba_last_access[NUM_MAX_CBA_GROUP]; - //#endif - /// total UE scheduler processing time - time_stats_t ue_scheduler; // total - /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation - time_stats_t tx_ulsch_sdu; - /// UE DLSCH rx processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser - time_stats_t rx_dlsch_sdu; - /// UE query for MCH subframe processing time - time_stats_t ue_query_mch; - /// UE MCH rx processing time - time_stats_t rx_mch_sdu; - /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) - time_stats_t rx_si; - /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) - time_stats_t rx_p; + //#ifdef CBA + /// CBA RNTI for each group + uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; + /// last SFN for CBA channel access + uint8_t cba_last_access[NUM_MAX_CBA_GROUP]; + //#endif + /// total UE scheduler processing time + time_stats_t ue_scheduler; // total + /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation + time_stats_t tx_ulsch_sdu; + /// UE DLSCH rx processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser + time_stats_t rx_dlsch_sdu ; + /// UE query for MCH subframe processing time + time_stats_t ue_query_mch; + /// UE MCH rx processing time + time_stats_t rx_mch_sdu; + /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) + time_stats_t rx_si; + /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) + time_stats_t rx_p; + /// Panos: Mutex for nfapi UL_INFO + pthread_mutex_t UL_INFO_mutex; + /// Panos: UE_Mode variable should be used in the case of Phy_stub operation since we won't have access to PHY_VARS_UE + /// where the UE_mode originally is for the full stack operation mode. The transitions between the states of the UE_Mode + /// will be triggered within phy_stub_ue.c in this case + UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Panos: Phy_stub mode: Boolean variable to distinguish whether a Msg3 or a regular ULSCH data pdu should be generated + /// after the reception of NFAPI_UL_CONFIG_ULSCH_PDU_TYPE. + uint8_t first_ULSCH_Tx; + uint8_t SI_Decoded; + int ra_frame; // This variable keeps the frame in which the RA started for the specific UE. It is used in order + // to make sure that different UEs RA starts within a number of frames difference. + + eth_params_t eth_params_n; + } UE_MAC_INST; /*! \brief ID of the neighboring cells used for HO*/ typedef struct { @@ -1370,7 +1545,6 @@ typedef struct { uint8_t n_adj_cells; } neigh_cell_id_t; - typedef struct { volatile uint8_t flag; rnti_t rnti; @@ -1387,6 +1561,7 @@ typedef struct { mui_t rrc_mui[128]; }mac_rlc_am_muilist_t; -#include "proto.h" +#include "mac_proto.h" + /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/MAC/extern.h b/openair2/LAYER2/MAC/mac_extern.h similarity index 76% rename from openair2/LAYER2/MAC/extern.h rename to openair2/LAYER2/MAC/mac_extern.h index 8f5d55dfd375d56264adac9707a2452acd317d25..ca72882471f11122633b5dc76af58740f73ce757 100644 --- a/openair2/LAYER2/MAC/extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -32,10 +32,10 @@ #ifndef __MAC_EXTERN_H__ #define __MAC_EXTERN_H__ -#include "PHY/defs.h" -#include "defs.h" +//#include "PHY/defs_common.h" +#include "mac.h" -#include "RRC/LITE/defs.h" +#include "RRC/LTE/rrc_defs.h" extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE]; //extern uint32_t EBSR_Level[63]; @@ -52,8 +52,8 @@ extern UE_RRC_INST *UE_rrc_inst; extern UE_MAC_INST *UE_mac_inst; -extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 -extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 +extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 +extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 @@ -75,27 +75,6 @@ extern uint32_t RRC_CONNECTION_FLAG; extern uint8_t rb_table[34]; -extern DCI0_5MHz_TDD_1_6_t UL_alloc_pdu; - -extern DCI1A_5MHz_TDD_1_6_t RA_alloc_pdu; -extern DCI1A_5MHz_TDD_1_6_t DLSCH_alloc_pdu1A; -extern DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu; - -extern DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; -extern DCI1_5MHz_TDD_t DLSCH_alloc_pdu; - -extern DCI0_5MHz_FDD_t UL_alloc_pdu_fdd; - -extern DCI1A_5MHz_FDD_t DLSCH_alloc_pdu1A_fdd; -extern DCI1A_5MHz_FDD_t RA_alloc_pdu_fdd; -extern DCI1A_5MHz_FDD_t BCCH_alloc_pdu_fdd; - -extern DCI1A_5MHz_FDD_t CCCH_alloc_pdu_fdd; -extern DCI1_5MHz_FDD_t DLSCH_alloc_pdu_fdd; - -extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1; -extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2; -extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E; #if defined(PRE_SCD_THREAD) extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/mac_proto.h similarity index 89% rename from openair2/LAYER2/MAC/proto.h rename to openair2/LAYER2/MAC/mac_proto.h index 1e33f3ac8d61f419943f9d4201672b1aa79c22bb..2388c097b9047eb1361fb48fc857ca325f59d6d5 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -29,12 +29,29 @@ #ifndef __LAYER2_MAC_PROTO_H__ #define __LAYER2_MAC_PROTO_H__ -#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/mac.h" +#include "PHY/defs_common.h" // for PRACH_RESOURCES_t and lte_subframe_t /** \addtogroup _mac * @{ */ +/** + * slice specific scheduler + */ +typedef void (*slice_scheduler_dl)(module_id_t mod_id, + slice_id_t slice_id, + frame_t frame, + sub_frame_t subframe, + int *mbsfn_flag); + +typedef void (*slice_scheduler_ul)(module_id_t mod_id, + slice_id_t slice_id, + frame_t frame, + sub_frame_t subframe, + unsigned char sched_subframe, + uint16_t *first_rb); + /** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); \brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. @param Mod_id Instance ID of eNB @@ -102,11 +119,15 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, /** \brief ULSCH Scheduling per RNTI @param Mod_id Instance ID of eNB +@param slice_id Instance slice for this eNB @param frame Frame index @param subframe Subframe number on which to act @param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup) */ -void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, uint16_t *first_rb); +void schedule_ulsch_rnti(module_id_t module_idP, slice_id_t slice_idP, frame_t frameP, + sub_frame_t subframe, + unsigned char sched_subframe, + uint16_t * first_rb); /** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called. This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY. It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation. It assumes localized allocation of type 0 (DCI.rah=0). The allocation is done for tranmission modes 1,2,4. @param Mod_id Instance of eNB @@ -123,9 +144,15 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,i @param mbsfn_flag Indicates that MCH/MCCH is in this subframe */ -void schedule_ue_spec(module_id_t module_idP, frame_t frameP, +void schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag); +void schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, + frame_t frameP,sub_frame_t subframe, int *mbsfn_flag); + +void schedule_ue_spec_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag); +void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP); + /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure. @param Mod_id Module id of UE @@ -183,16 +210,13 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, int subframeP, int N_RBG, uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], + nb_rbs_required[NFAPI_CC_MAX] + [MAX_MOBILES_PER_ENB], unsigned char - rballoc_sub[MAX_NUM_CCs] + rballoc_sub[NFAPI_CC_MAX] [N_RBG_MAX], unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] + MIMO_mode_indicator[NFAPI_CC_MAX] [N_RBG_MAX]); // eNB functions @@ -204,24 +228,25 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, */ -void dlsch_scheduler_pre_processor (module_id_t module_idP, - frame_t frameP, - sub_frame_t subframe, - int N_RBG[MAX_NUM_CCs], - int *mbsfn_flag); +void dlsch_scheduler_pre_processor(module_id_t module_idP, + slice_id_t slice_idP, + frame_t frameP, + sub_frame_t subframe, + int N_RBG[NFAPI_CC_MAX], + int *mbsfn_flag); -void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], - unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); +void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, + int UE_id, + uint8_t CC_id, + int N_RBG, + int transmission_mode, + int min_rb_unit, + uint8_t N_RB_DL, + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f. @@ -241,7 +266,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame void initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframeP, uint16_t preamble_index, int16_t timing_offset, uint16_t rnti -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif ); @@ -260,7 +285,7 @@ unsigned short fill_rar(const module_id_t module_idP, const uint16_t N_RB_UL, const uint8_t input_buffer_length); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) unsigned short fill_rar_br(eNB_MAC_INST * eNB, int CC_id, RA_t * ra, @@ -489,8 +514,17 @@ void ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frame, sub_frame_t subframe, uint8_t * sdu, uint16_t sdu_len, uint8_t CH_index); - -#if defined(Rel10) || defined(Rel14) +void ue_send_sl_sdu(module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t* sdu, + uint16_t sdu_len, + uint8_t eNB_index, + sl_discovery_flag_t sl_discovery_flag + ); + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /* \brief Called by PHY to transfer MCH transport block to ue MAC. @param Mod_id Index of module instance @param frame Frame index @@ -522,13 +556,36 @@ int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame, @param eNB_id Index of eNB that UE is attached to @param rnti C_RNTI of UE @param subframe subframe number -@returns 0 for no SR, 1 for SR */ void ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index, uint8_t * ulsch_buffer, uint16_t buflen, uint8_t * access_mode); +/* \brief Called by PHY to get sdu for PSBCH/SSS/PSS transmission. +@param Mod_id Instance id of UE in machine +@param frame_tx TX frame index +@param subframe_tx TX subframe index +@returns pointer to SLSS_t descriptor +*/ +SLSS_t *ue_get_slss(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe); + +/* \brief Called by PHY to get sdu for PSDCH transmission. +@param Mod_id Instance id of UE in machine +@param frame_tx TX frame index +@param subframe_tx TX subframe index +@returns pointer to SLDCH_t descriptor +*/ +SLDCH_t *ue_get_sldch(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe); + +/* \brief Called by PHY to get sdu for PSSCH transmission. +@param Mod_id Instance id of UE in machine +@param frame_tx TX frame index +@param subframe_tx TX subframe index +@returns pointer to SLSCH_t descriptor +*/ +SLSCH_t *ue_get_slsch(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe); + /* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for random-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321) @param Mod_id Index of UE instance @param Mod_id Component Carrier Index @@ -610,11 +667,9 @@ uint8_t *parse_ulsch_header(uint8_t * mac_header, int to_prb(int); int to_rbg(int); -int l2_init(LTE_DL_FRAME_PARMS * frame_parms, int eMBMS_active, - char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); int mac_init(void); int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti, int harq_pid -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif ); @@ -629,23 +684,29 @@ void dump_ue_list(UE_list_t * listP, int ul_flag); int UE_num_active_CC(UE_list_t * listP, int ue_idP); int UE_PCCID(module_id_t mod_idP, int ue_idP); rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP); + uint8_t find_rb_table_index(uint8_t average_rbs); -void ulsch_scheduler_pre_processor(module_id_t module_idP, int frameP, sub_frame_t subframeP, unsigned char sched_subframeP,uint16_t *first_rb); - -void -set_ul_DAI( - int module_idP, - int UE_idP, - int CC_idP, - int frameP, - int subframeP -); -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); +void set_ul_DAI(int module_idP, + int UE_idP, + int CC_idP, + int frameP, + int subframeP); + +void ulsch_scheduler_pre_processor(module_id_t module_idP, slice_id_t slice_id, int frameP, + sub_frame_t subframeP, + unsigned char sched_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 slice_id, 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); +void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP); /*! \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. @@ -830,15 +891,15 @@ in the DLSCH buffer. @param post_padding number of bytes for padding at the end of MAC PDU @returns Number of bytes used for header */ -unsigned char generate_dlsch_header(unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - unsigned short timing_advance_cmd, - unsigned char *ue_cont_res_id, - unsigned char short_padding, - unsigned short post_padding); +int generate_dlsch_header(unsigned char *mac_header, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding); /** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages. @param Mod_id Instance ID of eNB @@ -868,20 +929,20 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, int p_eNB, int Ncp, int eutra_band, uint32_t dl_CarrierFreq, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int pbch_repetition, #endif rnti_t rntiP, BCCH_BCH_Message_t * mib, RadioResourceConfigCommonSIB_t * radioResourceConfigCommon, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BR, #endif struct PhysicalConfigDedicated *physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) SCellToAddMod_r10_t * sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -899,13 +960,13 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , uint8_t MBMS_Flag, MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, PMCH_InfoList_r9_t * pmch_InfoList #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , SystemInformationBlockType1_v1310_IEs_t * sib1_ext_r13 @@ -939,7 +1000,7 @@ int rrc_mac_config_req_ue(module_id_t module_idP, radioResourceConfigCommon, struct PhysicalConfigDedicated *physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) SCellToAddMod_r10_t * sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -958,7 +1019,7 @@ int rrc_mac_config_req_ue(module_id_t module_idP, additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , uint8_t MBMS_Flag, MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, @@ -968,7 +1029,13 @@ int rrc_mac_config_req_ue(module_id_t module_idP, , uint8_t num_active_cba_groups, uint16_t cba_rnti #endif - ); +#if defined(Rel14) + ,config_action_t config_action + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + ); + uint16_t getRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs); @@ -1059,7 +1126,7 @@ void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t * uint8_t current_tx_nb, uint8_t n_srs, uint16_t size); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * ul_config_pdu, uint8_t ue_type, uint16_t @@ -1136,7 +1203,7 @@ uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP); uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int get_numnarrowbandbits(long dl_Bandwidth); int mpdcch_sf_condition(eNB_MAC_INST * eNB, int CC_id, frame_t frameP, @@ -1167,5 +1234,10 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]); #endif +/*Slice related functions */ +uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); + +int ue_slice_membership(int UE_id, int slice_id); + #endif /** @}*/ diff --git a/openair2/LAYER2/MAC/vars.h b/openair2/LAYER2/MAC/mac_vars.h similarity index 94% rename from openair2/LAYER2/MAC/vars.h rename to openair2/LAYER2/MAC/mac_vars.h index 51aa3c0112f79508137f3c77eab7e115740017c3..76842afd38358bed4baeb0ff3b72d0c68cf728db 100644 --- a/openair2/LAYER2/MAC/vars.h +++ b/openair2/LAYER2/MAC/mac_vars.h @@ -32,8 +32,8 @@ #ifndef __MAC_VARS_H__ #define __MAC_VARS_H__ -#include "PHY/defs.h" -#include "defs.h" +#include "PHY/defs_common.h" +#include "mac.h" #include "COMMON/mac_rrc_primitives.h" const uint32_t BSR_TABLE[BSR_TABLE_SIZE] = @@ -103,8 +103,8 @@ int pCC_id[NUMBER_OF_eNB_MAX]; -eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 -eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 +eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 +eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 #ifdef OPENAIR2 @@ -124,7 +124,7 @@ DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu; DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; DCI1_5MHz_TDD_t DLSCH_alloc_pdu; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) DCI1C_5MHz_t MCCH_alloc_pdu; #endif diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index b067d87cd42d0c013785382e12802e6fc964480d..003450ed126d1ee2fabd2094187824dea6c68ba9 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -29,94 +29,21 @@ */ -#include "defs.h" -#include "proto.h" -#include "extern.h" +#include "mac.h" +#include "mac_proto.h" +#include "mac_extern.h" #include "assertions.h" -#include "PHY_INTERFACE/extern.h" -#include "PHY/defs.h" -#include "SCHED/defs.h" +//#include "PHY_INTERFACE/phy_extern.h" +//#include "PHY/defs_eNB.h" +//#include "SCHED/sched_eNB.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" -#include "RRC/LITE/defs.h" +#include "RRC/LTE/rrc_defs.h" #include "UTIL/LOG/log.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#include "SCHED/defs.h" - - #include "common/ran_context.h" extern RAN_CONTEXT_t RC; -extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active); - -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) - int mme_enabled = 1; -#else - int mme_enabled = 0; -#endif - - if (first_sync == 1 && !(mme_enabled == 1)) { - //layer2_init_UE(module_idP); - openair_rrc_ue_init(module_idP, eNB_index); - } else { - rrc_in_sync_ind(module_idP, frameP, eNB_index); - } -} - -void -mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, - uint16_t eNB_index) -{ - - // Mac_rlc_xface->mac_out_of_sync_ind(Mod_id, frameP, eNB_index); -} - - -int -mac_top_init_ue(int eMBMS_active, char *uecap_xer, - uint8_t cba_group_active, uint8_t HO_active) -{ - - int i; - - LOG_I(MAC, "[MAIN] Init function start:Nb_UE_INST=%d\n", NB_UE_INST); - - if (NB_UE_INST > 0) { - UE_mac_inst = - (UE_MAC_INST *) malloc16(NB_UE_INST * sizeof(UE_MAC_INST)); - - AssertFatal(UE_mac_inst != NULL, - "[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n", - NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, - sizeof(UE_MAC_INST)); - - LOG_D(MAC, "[MAIN] ALLOCATE %zu Bytes for %d UE_MAC_INST @ %p\n", - NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, UE_mac_inst); - - bzero(UE_mac_inst, NB_UE_INST * sizeof(UE_MAC_INST)); - - for (i = 0; i < NB_UE_INST; i++) { - ue_init_mac(i); - } - } else { - UE_mac_inst = NULL; - } - - - LOG_I(MAC, "[MAIN] calling RRC\n"); - openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, - HO_active); - - - LOG_I(MAC, "[MAIN][INIT] Init function finished\n"); - - return (0); - -} void mac_top_init_eNB(void) @@ -194,7 +121,7 @@ void mac_top_init_eNB(void) UE_list->head_ul = -1; UE_list->avail = 0; - for (list_el = 0; list_el < NUMBER_OF_UE_MAX - 1; list_el++) { + for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) { UE_list->next[list_el] = list_el + 1; UE_list->next_ul[list_el] = list_el + 1; } @@ -218,7 +145,7 @@ void mac_init_cell_params(int Mod_idP, int CC_idP) UE_template = (UE_TEMPLATE *) & RC.mac[Mod_idP]->UE_list.UE_template[CC_idP][0]; - for (j = 0; j < NUMBER_OF_UE_MAX; j++) { + for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { UE_template[j].rnti = 0; // initiallize the eNB to UE statistics memset(&RC.mac[Mod_idP]->UE_list.eNB_UE_stats[CC_idP][j], 0, @@ -259,20 +186,6 @@ void mac_top_cleanup(void) } -int -l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, - uint8_t HO_active) -{ - LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n"); - // NB_NODE=2; - // NB_INST=2; - - rlcmac_init_global_param(); - LOG_I(MAC, "[MAIN] init UE MAC functions \n"); - mac_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active); - return (1); -} - int l2_init_eNB(void) { diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..272ca5cddd7c953ed87bc458f9018451c161d0f1 --- /dev/null +++ b/openair2/LAYER2/MAC/main_ue.c @@ -0,0 +1,148 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 main.c + * \brief top init of Layer 2 + * \author Navid Nikaein and Raymond Knopp + * \date 2010 - 2014 + * \version 1.0 + * \email: navid.nikaein@eurecom.fr + * @ingroup _mac + + */ + +#include "mac.h" +#include "mac_proto.h" +#include "mac_extern.h" +#include "assertions.h" +#include "PHY_INTERFACE/phy_interface_extern.h" +#include "PHY/defs_UE.h" +#include "SCHED_UE/sched_UE.h" +#include "LAYER2/PDCP_v10.1.0/pdcp.h" +#include "RRC/LTE/rrc_defs.h" +#include "UTIL/LOG/log.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" + + +#include "common/ran_context.h" + +extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active); + +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) + int mme_enabled = 1; +#else + int mme_enabled = 0; +#endif + + if (first_sync == 1 && !(mme_enabled == 1)) { + //layer2_init_UE(module_idP); + openair_rrc_ue_init(module_idP, eNB_index); + } else { + rrc_in_sync_ind(module_idP, frameP, eNB_index); + } +} + +void +mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, + uint16_t eNB_index) +{ + + // Mac_rlc_xface->mac_out_of_sync_ind(Mod_id, frameP, eNB_index); +} + + +int +mac_top_init_ue(int eMBMS_active, char *uecap_xer, + uint8_t cba_group_active, uint8_t HO_active) +{ + + int i; + + LOG_I(MAC, "[MAIN] Init function start:Nb_UE_INST=%d\n", NB_UE_INST); + + if (NB_UE_INST > 0) { + UE_mac_inst = + (UE_MAC_INST *) malloc16(NB_UE_INST * sizeof(UE_MAC_INST)); + + AssertFatal(UE_mac_inst != NULL, + "[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n", + NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, + sizeof(UE_MAC_INST)); + + LOG_D(MAC, "[MAIN] ALLOCATE %zu Bytes for %d UE_MAC_INST @ %p\n", + NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, UE_mac_inst); + + bzero(UE_mac_inst, NB_UE_INST * sizeof(UE_MAC_INST)); + + for (i = 0; i < NB_UE_INST; i++) { + ue_init_mac(i); + } + } else { + UE_mac_inst = NULL; + } + + + LOG_I(MAC, "[MAIN] calling RRC\n"); + openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, + HO_active); + + + LOG_I(MAC, "[MAIN][INIT] Init function finished\n"); + + return (0); + +} + +int rlcmac_init_global_param_ue(void) +{ + + + LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n"); + + if (rlc_module_init() != 0) { + return (-1); + } + + pdcp_layer_init(); + + LOG_I(MAC, "[MAIN] Init Global Param Done\n"); + + return 0; +} + +int +l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, + uint8_t HO_active) +{ + LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n"); + // NB_NODE=2; + // NB_INST=2; + + rlcmac_init_global_param_ue(); + LOG_I(MAC, "[MAIN] init UE MAC functions \n"); + mac_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active); + return (1); +} + diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 3bc05c538dcbad89f51e539040330aaee0fa5ceb..49ca284935aab188c9dabe189f3457b3862e2c64 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -33,30 +33,35 @@ #include <stdlib.h> #include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "rlc.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; #define DEBUG_eNB_SCHEDULER 1 #define DEBUG_HEADER_PARSING 1 //#define DEBUG_PACKET_TRACE 1 +extern float slice_percentage[MAX_NUM_SLICES]; +extern float slice_percentage_uplink[MAX_NUM_SLICES]; +extern uint32_t sorting_policy[MAX_NUM_SLICES]; + +extern int slice_maxmcs[MAX_NUM_SLICES]; +extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; + + //#define ICIC 0 /* this function checks that get_eNB_UE_stats returns @@ -90,7 +95,7 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) // This function stores the downlink buffer for all the logical channels void -store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, +store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP) { @@ -100,10 +105,13 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_TEMPLATE *UE_template; - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; + UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; @@ -111,13 +119,26 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, UE_template->dl_buffer_total = 0; UE_template->dl_pdus_total = 0; + for (i = 0; i < MAX_NUM_LCID; i++) { + UE_template->dl_buffer_info[i] = 0; + UE_template->dl_pdus_in_buffer[i] = 0; + UE_template->dl_buffer_head_sdu_creation_time[i] = 0; + UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0; + } + + rnti = UE_RNTI(Mod_id, UE_id); - for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels + for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, - ENB_FLAG_YES, MBMS_FLAG_NO, i, 0); + ENB_FLAG_YES, MBMS_FLAG_NO, i, 0 +#ifdef Rel14 + ,0, 0 +#endif + ); + UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; UE_template->dl_buffer_head_sdu_creation_time[i] = @@ -140,8 +161,8 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, */ if (UE_template->dl_buffer_info[i] > 0) LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, frameP, subframeP, UE_id, + "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", + Mod_id, slice_id, frameP, subframeP, UE_id, i, UE_template->dl_pdus_in_buffer[i], UE_template->dl_buffer_info[i], UE_template->dl_buffer_head_sdu_creation_time[i], @@ -169,11 +190,12 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, // This function returns the estimated number of RBs required by each UE for downlink scheduling void assign_rbs_required(module_id_t Mod_id, + slice_id_t slice_id, frame_t frameP, sub_frame_t subframe, uint16_t - nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - int min_rb_unit[MAX_NUM_CCs]) + nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + int min_rb_unit[NFAPI_CC_MAX]) { uint16_t TBS = 0; @@ -184,20 +206,20 @@ assign_rbs_required(module_id_t Mod_id, int N_RB_DL; // clear rb allocations across all CC_id - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; - + if (!ue_slice_membership(UE_id, slice_id)) + continue; pCCid = UE_PCCID(Mod_id, UE_id); //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 = &UE_list->eNB_UE_stats[CC_id][UE_id]; - eNB_UE_stats->dlsch_mcs1 = - cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; + eNB_UE_stats->dlsch_mcs1 =cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], + slice_maxmcs[slice_id]); } @@ -207,7 +229,7 @@ assign_rbs_required(module_id_t Mod_id, &UE_list->eNB_UE_stats[UE_list-> ordered_CCids[i][UE_id]][UE_id]; for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { - DevAssert(j < MAX_NUM_CCs); + DevAssert(j < NFAPI_CC_MAX); eNB_UE_stats_j = &UE_list-> eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; @@ -249,16 +271,17 @@ assign_rbs_required(module_id_t Mod_id, to_prb(RC.mac[Mod_id]->common_channels[CC_id]. mib->message.dl_Bandwidth); + UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); + /* 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] > N_RB_DL) { - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, N_RB_DL); - nb_rbs_required[CC_id][UE_id] = N_RB_DL; + if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); + nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; break; } @@ -290,7 +313,7 @@ maxround(module_id_t Mod_id, uint16_t rnti, int frame, UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; COMMON_channels_t *cc; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { cc = &RC.mac[Mod_id]->common_channels[CC_id]; @@ -330,6 +353,7 @@ struct sort_ue_dl_params { int Mod_idP; int frameP; int subframeP; + int slice_id; }; static int ue_dl_compare(const void *_a, const void *_b, void *_params) @@ -337,62 +361,73 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) struct sort_ue_dl_params *params = _params; UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; + int i; + int slice_id = params->slice_id; int UE_id1 = *(const int *) _a; int UE_id2 = *(const int *) _b; int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); - int round1 = - maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, - 1); + int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); - int round2 = - maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, - 1); + int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); int cqi1 = maxcqi(params->Mod_idP, UE_id1); int cqi2 = maxcqi(params->Mod_idP, UE_id2); - if (round1 > round2) - return -1; - if (round1 < round2) - return 1; - - 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]) - return -1; - 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]) - return 1; - - 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) - return -1; - 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) - return 1; - - if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total > - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) - return -1; - if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) - return 1; - - if (cqi1 > cqi2) - return -1; - if (cqi1 < cqi2) - return 1; + for (i = 0; i < CR_NUM; ++i) { + switch (UE_list->sorting_criteria[slice_id][i]) { + + case CR_ROUND : + if (round1 > round2) + return -1; + if (round1 < round2) + return 1; + break; + + case CR_SRB12 : + 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]) + return -1; + 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]) + return 1; + break; + + case CR_HOL : + 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) + return -1; + 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) + return 1; + break; + + case CR_LC : + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total > + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) + return -1; + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) + return 1; + break; + + case CR_CQI : + if (cqi1 > cqi2) + return -1; + if (cqi1 < cqi2) + return 1; + + default : + break; + } + } return 0; #if 0 @@ -427,41 +462,66 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) #endif } +void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { + int i; + + UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + uint32_t policy = sorting_policy[slice_id]; + uint32_t mask = 0x0000000F; + uint16_t criterion; + + for(i = 0; i < CR_NUM; ++i) { + criterion = (uint16_t)(policy >> 4*(CR_NUM - 1 - i) & mask); + if (criterion >= CR_NUM) { + LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); + sorting_policy[slice_id] = 0x1234; + break; + } + UE_list->sorting_criteria[slice_id][i] = criterion; + } +} + + // 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) +void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP) { int i; - int list[NUMBER_OF_UE_MAX]; + int list[MAX_MOBILES_PER_ENB]; int list_size = 0; int rnti; - struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP }; + struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP, slice_id }; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_list->active[i] == FALSE) - continue; - if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) - continue; + if (UE_list->active[i] == FALSE) + continue; + if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) + continue; #if 0 - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; #endif - list[list_size] = i; - list_size++; - } + if (!ue_slice_membership(i, slice_id)) + continue; + + list[list_size] = i; + list_size++; + } - qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); + decode_sorting_policy(Mod_idP, slice_id); - if (list_size) { - for (i = 0; i < list_size - 1; i++) - UE_list->next[list[i]] = list[i + 1]; - UE_list->next[list[list_size - 1]] = -1; - UE_list->head = list[0]; - } else { - UE_list->head = -1; - } + qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); + + if (list_size) { + for (i = 0; i < list_size - 1; i++) + UE_list->next[list[i]] = list[i + 1]; + UE_list->next[list[list_size - 1]] = -1; + UE_list->head = list[0]; + } else { + UE_list->head = -1; + } #if 0 @@ -536,544 +596,591 @@ void sort_UEs(module_id_t Mod_idP, int frameP, sub_frame_t subframeP) #endif } +void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int N_RBG[NFAPI_CC_MAX], + int min_rb_unit[NFAPI_CC_MAX], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { -// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done -void dlsch_scheduler_pre_processor (module_id_t Mod_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], - int *mbsfn_flag) -{ + int UE_id, CC_id; + int ii, r1; - unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,round=0,total_ue_count; - uint16_t ii; - uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t r1=0; -// int rrc_status = RRC_IDLE; - unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; - int UE_id, i; - uint16_t j; - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; -// uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0}; - rnti_t rnti; - int min_rb_unit[MAX_NUM_CCs]; -// uint16_t r1=0; - uint8_t CC_id; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + rnti_t rnti; + uint8_t harq_pid, round, transmission_mode; + uint8_t total_rbs_used[NFAPI_CC_MAX]; + uint8_t total_ue_count[NFAPI_CC_MAX]; + uint16_t average_rbs_per_user[NFAPI_CC_MAX]; + uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; int N_RB_DL; - int transmission_mode = 0; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; - // int rrc_status = RRC_IDLE; COMMON_channels_t *cc; -#ifdef TM5 - int harq_pid1 = 0; - int round1 = 0, round2 = 0; - int UE_id2; - uint16_t i1, i2, i3; - rnti_t rnti1, rnti2; - LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; - LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; - UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; -#endif - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; - - + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + total_ue_count[CC_id] = 0; + total_rbs_used[CC_id] = 0; + average_rbs_per_user[CC_id] = 0; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { + nb_rbs_required_remaining[CC_id][UE_id] = 0; + } + } - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); + // loop over all active UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; + if (rnti == NOT_A_RNTI) + continue; +#if 0 + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; +#endif + if (!ue_slice_membership(UE_id, slice_id)) + continue; - UE_id = i; - // Initialize scheduling information for all active UEs + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + // TODO Can we use subframe2harqpid() here? + if (cc->tdd_Config) + harq_pid = ((frameP * 10) + subframeP) % 10; + else + harq_pid = ((frameP * 10) + subframeP) & 7; + round = ue_sched_ctl->round[CC_id][harq_pid]; + + average_rbs_per_user[CC_id] = 0; + + if (round != 8) { + nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + total_rbs_used[CC_id] += nb_rbs_required[CC_id][UE_id]; + } + + //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; + if (nb_rbs_required[CC_id][UE_id] > 0) { + total_ue_count[CC_id] = total_ue_count[CC_id] + 1; + } + } + } + // loop over all active UEs and calculate avg rb per user based on total active UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; - dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, - frameP, - subframeP, - N_RBG[CC_id], - nb_rbs_required, - nb_rbs_required_remaining, - rballoc_sub, - MIMO_mode_indicator); + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; - } + // hypothetical assignment + /* + * If schedule is enabled and if the priority of the UEs is modified + * The average rbs per logical channel per user will depend on the level of + * priority. Concerning the hypothetical assignement, we should assign more + * rbs to prioritized users. Maybe, we can do a mapping between the + * average rbs per user and the level of priority or multiply the average rbs + * per user by a coefficient which represents the degree of priority. + */ + + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - total_rbs_used[CC_id]; + + // recalculate based on the what is left after retransmission + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = + flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + + if (total_ue_count[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= + (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { + average_rbs_per_user[CC_id] = + (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); + } else { + // consider the total number of use that can be scheduled UE + average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; + } } + } - // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id, frameP, subframeP); + // note: nb_rbs_required is assigned according to total_buffer_dl + // extend nb_rbs_required to capture per LCID RB required + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) + continue; +#if 0 + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; +#endif + if (!ue_slice_membership(UE_id, slice_id)) + continue; + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + round = ue_sched_ctl->round[CC_id][harq_pid]; + + // control channel or retransmission + /* TODO: do we have to check for retransmission? */ + if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) { + nb_rbs_required_remaining_1[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id]; + } else { + nb_rbs_required_remaining_1[CC_id][UE_id] = + cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + } + } + } - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, frameP, subframeP, nb_rbs_required, - min_rb_unit); + //Allocation to UEs is done in 2 rounds, + // 1st stage: average number of RBs allocated to each UE + // 2nd stage: remaining RBs are allocated to high priority UEs + for (r1 = 0; r1 < 2; r1++) { + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + if (r1 == 0) { + nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_required_remaining_1[CC_id][UE_id]; + } else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round + nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id] - + nb_rbs_required_remaining_1[CC_id][UE_id] + + nb_rbs_required_remaining[CC_id][UE_id]; + if (nb_rbs_required_remaining[CC_id][UE_id] < 0) + abort(); + } + + if (nb_rbs_required[CC_id][UE_id] > 0) + LOG_D(MAC, + "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + r1, CC_id, UE_id, + nb_rbs_required_remaining[CC_id][UE_id], + nb_rbs_required_remaining_1[CC_id][UE_id], + nb_rbs_required[CC_id][UE_id], + UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], + N_RBG[CC_id], + min_rb_unit[CC_id]); + + } + } - // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs (Mod_id,frameP,subframeP); + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - total_ue_count =0; + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - //total_ue_count =0; + CC_id = UE_list->ordered_CCids[ii][UE_id]; + // if there are UEs with traffic + if (total_ue_count[CC_id] > 0) { + // ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + // round = ue_sched_ctl->round[CC_id][harq_pid]; - // loop over all active UEs - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); + rnti = UE_RNTI(Mod_id, UE_id); - if (rnti == NOT_A_RNTI) - continue; + // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); + if (rnti == NOT_A_RNTI) + continue; #if 0 - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; #endif - UE_id = i; + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + transmission_mode = get_tmode(Mod_id, CC_id, UE_id); + // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); + // rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); + /* 1st allocate for the retx */ + + // retransmission in data channels + // control channel in the 1st transmission + // data channel for all TM + LOG_T(MAC, + "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, + CC_id, + N_RBG[CC_id], + transmission_mode, + min_rb_unit + [CC_id], + to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth), + nb_rbs_required, + nb_rbs_required_remaining, + rballoc_sub, + MIMO_mode_indicator); - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - cc = &RC.mac[Mod_id]->common_channels[ii]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - round = ue_sched_ctl->round[CC_id][harq_pid]; +#ifdef TM5 + // data chanel TM5: to be revisited + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + + for (j = 0; j < N_RBG[CC_id]; j += 2) { + + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_required_remaining[CC_id][UE_id] + > 0)) { + + for (ii = UE_list->next[UE_id + 1]; ii >= 0; + ii = UE_list->next[ii]) { + + UE_id2 = ii; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { + + if ((((j == (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_required_remaining + [CC_id] + [UE_id2] > 0)) { + + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> + rballoc_sub_UE[CC_id] + [j] = 1; + ue_sched_ctl2-> + rballoc_sub_UE[CC_id] + [j] = 1; + MIMO_mode_indicator[CC_id] + [j] = 0; + + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } + + ue_sched_ctl-> + dl_pow_off[CC_id] + = 0; + ue_sched_ctl2-> + dl_pow_off[CC_id] + = 0; + + + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { + + nb_rbs_required_remaining + [CC_id][UE_id] = + nb_rbs_required_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_required_remaining + [CC_id][UE_id2] = + nb_rbs_required_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { + + nb_rbs_required_remaining + [CC_id][UE_id] = + nb_rbs_required_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_required_remaining + [CC_id][UE_id2] = + nb_rbs_required_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } + + break; + } + } + } + } + } + } + } +#endif + } // total_ue_count + } // CC + } // UE + } // end of for for r1 and r2 +} - average_rbs_per_user[CC_id] = 0; +// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done +void +dlsch_scheduler_pre_processor(module_id_t Mod_id, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int N_RBG[NFAPI_CC_MAX], + int *mbsfn_flag) { + + int UE_id; + uint8_t CC_id; + uint16_t i, j; + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting - if (round != 8) { - nb_rbs_required[CC_id][UE_id] = - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - } - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count = total_ue_count + 1; - } - // hypothetical assignment - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ + int min_rb_unit[NFAPI_CC_MAX]; + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - N_RB_DL = - to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth); - - if (total_ue_count == 0) { - average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count) <= (N_RB_DL)) { - average_rbs_per_user[CC_id] = - (uint16_t) floor(N_RB_DL / total_ue_count); - } else { - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE - } - } - } - - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; +// int rrc_status = RRC_IDLE; - if (rnti == NOT_A_RNTI) - continue; -#if 0 - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; +#ifdef TM5 + int harq_pid1 = 0; + int round1 = 0, round2 = 0; + int UE_id2; + uint16_t i1, i2, i3; + rnti_t rnti1, rnti2; + LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; + LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; + UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; #endif - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[i]; - round = ue_sched_ctl->round[CC_id][harq_pid]; - - // control channel or retransmission - /* TODO: do we have to check for retransmission? */ - if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED - || round > 0) { - nb_rbs_required_remaining_1[CC_id][i] = - nb_rbs_required[CC_id][i]; - } else { - nb_rbs_required_remaining_1[CC_id][i] = - cmin(average_rbs_per_user[CC_id], - nb_rbs_required[CC_id][i]); - } - } - } + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { - //Allocation to UEs is done in 2 rounds, - // 1st stage: average number of RBs allocated to each UE - // 2nd stage: remaining RBs are allocated to high priority UEs - for (r1 = 0; r1 < 2; r1++) { - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - - if (r1 == 0) { - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required_remaining_1[CC_id][i]; - } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required[CC_id][i] - - nb_rbs_required_remaining_1[CC_id][i] + - nb_rbs_required_remaining[CC_id][i]; - if (nb_rbs_required_remaining[CC_id][i] < 0) - abort(); - } + if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here + continue; - if (nb_rbs_required[CC_id][i] > 0) - LOG_D(MAC, - "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", - r1, CC_id, i, - nb_rbs_required_remaining[CC_id][i], - nb_rbs_required_remaining_1[CC_id][i], - nb_rbs_required[CC_id][i], - UE_list->UE_sched_ctrl[i]. - pre_nb_available_rbs[CC_id], N_RBG[CC_id], - min_rb_unit[CC_id]); + min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - } - } - - if (total_ue_count > 0) { - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { + if (UE_list->active[UE_id] != TRUE) + continue; - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - round = ue_sched_ctl->round[CC_id][harq_pid]; + if (!ue_slice_membership(UE_id, slice_id)) + continue; - rnti = UE_RNTI(Mod_id, UE_id); + // Initialize scheduling information for all active UEs + dlsch_scheduler_pre_processor_reset(Mod_id, + UE_id, + CC_id, + frameP, + subframeP, + N_RBG[CC_id], + nb_rbs_required, + rballoc_sub, + MIMO_mode_indicator); - // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); - if (rnti == NOT_A_RNTI) - continue; -#if 0 - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; -#endif - transmission_mode = get_tmode(Mod_id, CC_id, UE_id); - // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); - //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); - /* 1st allocate for the retx */ - - // retransmission in data channels - // control channel in the 1st transmission - // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, - CC_id, - N_RBG[CC_id], - transmission_mode, - min_rb_unit - [CC_id], - to_prb(RC.mac - [Mod_id]->common_channels - [CC_id].mib->message.dl_Bandwidth), - nb_rbs_required, - nb_rbs_required_remaining, - rballoc_sub, - MIMO_mode_indicator); + } + } -#ifdef TM5 + // Store the DLSCH buffer for each logical channel + store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); - // data chanel TM5: to be revisted - if ((round == 0) && - (transmission_mode == 5) && - (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { - - for (j = 0; j < N_RBG[CC_id]; j += 2) { - - if ((((j == (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j] == 0) - && (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j + 1] == 0) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j + 1] == 0))) - && (nb_rbs_required_remaining[CC_id][UE_id] - > 0)) { - - for (ii = UE_list->next[i + 1]; ii >= 0; - ii = UE_list->next[ii]) { - - UE_id2 = ii; - rnti2 = UE_RNTI(Mod_id, UE_id2); - ue_sched_ctl2 = - &UE_list->UE_sched_ctrl[UE_id2]; - round2 = ue_sched_ctl2->round[CC_id]; - if (rnti2 == NOT_A_RNTI) - continue; -#if 0 if (UE_list-> - UE_sched_ctrl - [UE_id2].ul_out_of_sync == 1) - continue; -#endif - eNB_UE_stats2 = - UE_list-> - eNB_UE_stats[CC_id][UE_id2]; - //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); - - if ((mac_eNB_get_rrc_status - (Mod_id, - rnti2) >= RRC_RECONFIGURED) - && (round2 == 0) - && - (get_tmode(Mod_id, CC_id, UE_id2) - == 5) - && (ue_sched_ctl-> - dl_pow_off[CC_id] != 1)) { - - if ((((j == (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j + - 1] - == 0))) - && - (nb_rbs_required_remaining - [CC_id] - [UE_id2] > 0)) { - - if ((((eNB_UE_stats2-> - DL_pmi_single ^ - eNB_UE_stats1-> - DL_pmi_single) - << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration - - rballoc_sub[CC_id][j] = 1; - ue_sched_ctl-> - rballoc_sub_UE[CC_id] - [j] = 1; - ue_sched_ctl2-> - rballoc_sub_UE[CC_id] - [j] = 1; - MIMO_mode_indicator[CC_id] - [j] = 0; - - if (j < N_RBG[CC_id] - 1) { - rballoc_sub[CC_id][j + - 1] = - 1; - ue_sched_ctl-> - rballoc_sub_UE - [CC_id][j + 1] = 1; - ue_sched_ctl2->rballoc_sub_UE - [CC_id][j + 1] = 1; - MIMO_mode_indicator - [CC_id][j + 1] - = 0; - } - - ue_sched_ctl-> - dl_pow_off[CC_id] - = 0; - ue_sched_ctl2-> - dl_pow_off[CC_id] - = 0; - - - if ((j == N_RBG[CC_id] - 1) - && ((N_RB_DL == 25) - || (N_RB_DL == - 50))) { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - } else { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - 4; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + 4; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - 4; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + 4; - } - - break; - } - } - } - } - } - } - } -#endif - } - } - } // total_ue_count - } // end of for for r1 and r2 -#ifdef TM5 + // Calculate the number of RBs required by each UE on the basis of logical channel's buffer + assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, min_rb_unit); - // This has to be revisited!!!! - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - i1 = 0; - i2 = 0; - i3 = 0; - - for (j = 0; j < N_RBG[CC_id]; j++) { - if (MIMO_mode_indicator[CC_id][j] == 2) { - i1 = i1 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 1) { - i2 = i2 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 0) { - i3 = i3 + 1; - } - } + // Sorts the user on the basis of dlsch logical channel buffer and CQI + sort_UEs(Mod_id, slice_id, frameP, subframeP); - if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_SUMIMO_transmissions + 1; - } + // This function does the main allocation of the number of RBs + dlsch_scheduler_pre_processor_accounting(Mod_id, + slice_id, + frameP, + subframeP, + N_RBG, + min_rb_unit, + rballoc_sub, + MIMO_mode_indicator, + nb_rbs_required); - if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + - 1; - } - if((i1 < N_RBG[CC_id]) && (i3 > 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_MUMIMO_transmissions + 1; - } +#ifdef TM5 + // This has to be revisited!!!! + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + i1 = 0; + i2 = 0; + i3 = 0; + + for (j = 0; j < N_RBG[CC_id]; j++) { + if (MIMO_mode_indicator[CC_id][j] == 2) { + i1 = i1 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 1) { + i2 = i2 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 0) { + i3 = i3 + 1; + } + } - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + - 1; + if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_SUMIMO_transmissions + 1; + } - } + if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + + 1; + } -#endif + if ((i1 < N_RBG[CC_id]) && (i3 > 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_MUMIMO_transmissions + 1; + } - for(i=UE_list->head; i>=0; i=UE_list->next[i]) { - UE_id = i; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + + 1; - for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; + } +#endif - if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { - LOG_D(MAC, - "******************DL Scheduling Information for UE%d ************************\n", - UE_id); - LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, - ue_sched_ctl->dl_pow_off[CC_id]); - LOG_D(MAC, - "***********RB Alloc for every subband for UE%d ***********\n", - UE_id); - - for (j = 0; j < N_RBG[CC_id]; j++) { - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; - LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", - UE_id, j, - ue_sched_ctl->rballoc_sub_UE[CC_id][j]); - } + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; - LOG_D(MAC, "Total RBs allocated for UE%d = %d\n", UE_id, - ue_sched_ctl->pre_nb_available_rbs[CC_id]); - } - } + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; + + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { + LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", UE_id); + LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, ue_sched_ctl->dl_pow_off[CC_id]); + LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", UE_id); + + for (j = 0; j < N_RBG[CC_id]; j++) { + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id]; + LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", UE_id, j, ue_sched_ctl->rballoc_sub_UE[CC_id][j]); + } + + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; + LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", + Mod_id, slice_id, UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]); + } } + } } #define SF0_LIMIT 1 void dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] - [N_RBG_MAX]) + int UE_id, + uint8_t CC_id, + int frameP, + int subframeP, + int N_RBG, + uint16_t nb_rbs_required[NFAPI_CC_MAX] + [MAX_MOBILES_PER_ENB], + unsigned char + rballoc_sub[NFAPI_CC_MAX] + [N_RBG_MAX], + unsigned char + MIMO_mode_indicator[NFAPI_CC_MAX] + [N_RBG_MAX]) { - int i, j; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - rnti_t rnti = UE_RNTI(module_idP, UE_id); - - uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; - int N_RB_DL = - to_prb(RC.mac[module_idP]->common_channels[CC_id].mib-> - message.dl_Bandwidth); - int RBGsize = N_RB_DL / N_RBG, RBGsize_last; + int i, j; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti_t rnti = UE_RNTI(module_idP, UE_id); + + uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; + int N_RB_DL = + to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); + int RBGsize = N_RB_DL / N_RBG, RBGsize_last; #ifdef SF0_LIMIT - int sf0_upper = -1, sf0_lower = -1; + int sf0_upper = -1, sf0_lower = -1; #endif - LOG_D(MAC,"Running preprocessor for UE %d (%x)\n",UE_id,rnti); - // initialize harq_pid and round - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; + LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); + // initialize harq_pid and round + + if (ue_sched_ctl->ta_timer) + ue_sched_ctl->ta_timer--; /* eNB_UE_stats *eNB_UE_stats; @@ -1088,7 +1195,6 @@ dlsch_scheduler_pre_processor_reset(int module_idP, &ue_sched_ctl->round[CC_id], openair_harq_DL); - if (ue_sched_ctl->ta_timer == 0) { // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... @@ -1133,94 +1239,96 @@ dlsch_scheduler_pre_processor_reset(int module_idP, } */ - nb_rbs_required[CC_id][UE_id] = 0; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; - ue_sched_ctl->dl_pow_off[CC_id] = 2; - nb_rbs_required_remaining[CC_id][UE_id] = 0; + nb_rbs_required[CC_id][UE_id] = 0; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; + ue_sched_ctl->dl_pow_off[CC_id] = 2; - switch (N_RB_DL) { + switch (N_RB_DL) { case 6: - RBGsize = 1; - RBGsize_last = 1; - break; + RBGsize = 1; + RBGsize_last = 1; + break; case 15: - RBGsize = 2; - RBGsize_last = 1; - break; + RBGsize = 2; + RBGsize_last = 1; + break; case 25: - RBGsize = 2; - RBGsize_last = 1; - break; + RBGsize = 2; + RBGsize_last = 1; + break; case 50: - RBGsize = 3; - RBGsize_last = 2; - break; + RBGsize = 3; + RBGsize_last = 2; + break; case 75: - RBGsize = 4; - RBGsize_last = 3; - break; + RBGsize = 4; + RBGsize_last = 3; + break; case 100: - RBGsize = 4; - RBGsize_last = 4; - break; + RBGsize = 4; + RBGsize_last = 4; + break; default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #ifdef SF0_LIMIT - switch (N_RBG) { + switch (N_RBG) { case 6: - sf0_lower = 0; - sf0_upper = 5; - break; + sf0_lower = 0; + sf0_upper = 5; + break; case 8: - sf0_lower = 2; - sf0_upper = 5; - break; + sf0_lower = 2; + sf0_upper = 5; + break; case 13: - sf0_lower = 4; - sf0_upper = 7; - break; + sf0_lower = 4; + sf0_upper = 7; + break; case 17: - sf0_lower = 7; - sf0_upper = 9; - break; + sf0_lower = 7; + sf0_upper = 9; + break; case 25: - sf0_lower = 11; - sf0_upper = 13; - break; + sf0_lower = 11; + sf0_upper = 13; + break; default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #endif - // Initialize Subbands according to VRB map - for (i = 0; i < N_RBG; i++) { - int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; + // Initialize Subbands according to VRB map + for (i = 0; i < N_RBG; i++) { + int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; + + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; + rballoc_sub[CC_id][i] = 0; + #ifdef SF0_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) - /* TODO: make it proper - allocate those RBs, do not "protect" them, but - * compute number of available REs and limit MCS according to the - * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) - */ - if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) - rballoc_sub[CC_id][i] = 1; + // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) + /* TODO: make it proper - allocate those RBs, do not "protect" them, but + * compute number of available REs and limit MCS according to the + * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) + */ + if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) + rballoc_sub[CC_id][i] = 1; #endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < rb_size; j++) { - if (vrb_map[j + (i * RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", - frameP, subframeP, j + (i * RBGsize)); - break; - } - } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; + + // for SI-RNTI,RA-RNTI and P-RNTI allocations + for (j = 0; j < rb_size; j++) { + if (vrb_map[j + (i * RBGsize)] != 0) { + rballoc_sub[CC_id][i] = 1; + LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", + frameP, subframeP, j + (i * RBGsize)); + break; + } } + LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", + frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + MIMO_mode_indicator[CC_id][i] = 2; + } } @@ -1232,17 +1340,10 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int transmission_mode, int min_rb_unit, uint8_t N_RB_DL, - uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], unsigned char - MIMO_mode_indicator - [MAX_NUM_CCs][N_RBG_MAX]) + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { int i; @@ -1303,6 +1404,7 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, /// ULSCH PRE_PROCESSOR void ulsch_scheduler_pre_processor(module_id_t module_idP, + slice_id_t slice_id, int frameP, sub_frame_t subframeP, unsigned char sched_subframeP, @@ -1312,20 +1414,20 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, int16_t i; uint16_t UE_id, n, r; uint8_t CC_id, harq_pid; - uint16_t nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - total_allocated_rbs[MAX_NUM_CCs], - average_rbs_per_user[MAX_NUM_CCs]; - int16_t total_remaining_rbs[MAX_NUM_CCs]; - uint16_t max_num_ue_to_be_scheduled = 0; - uint16_t total_ue_count = 0; + uint16_t nb_allocated_rbs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + total_allocated_rbs[NFAPI_CC_MAX], + average_rbs_per_user[NFAPI_CC_MAX]; + int16_t total_remaining_rbs[NFAPI_CC_MAX]; + uint16_t total_ue_count[NFAPI_CC_MAX]; rnti_t rnti = -1; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; UE_TEMPLATE *UE_template = 0; - int N_RB_DL; - int N_RB_UL; + UE_sched_ctrl *ue_sched_ctl; + int N_RB_UL = 0; + LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - assign_max_mcs_min_rb(module_idP, frameP, subframeP, first_rb); + assign_max_mcs_min_rb(module_idP, slice_id, frameP, subframeP, first_rb); LOG_D(MAC, "In ulsch_preprocessor: sort ue \n"); // sort ues @@ -1334,322 +1436,317 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // we need to distribute RBs among UEs // step1: reset the vars - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - N_RB_DL = - to_prb(RC.mac[module_idP]->common_channels[CC_id].mib-> - message.dl_Bandwidth); - N_RB_UL = - to_prb(RC.mac[module_idP]->common_channels[CC_id]. - ul_Bandwidth); - total_allocated_rbs[CC_id] = 0; - total_remaining_rbs[CC_id] = 0; - average_rbs_per_user[CC_id] = 0; - - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - nb_allocated_rbs[CC_id][i] = 0; - } + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { + total_allocated_rbs[CC_id] = 0; + total_remaining_rbs[CC_id] = 0; + average_rbs_per_user[CC_id] = 0; + total_ue_count[CC_id] = 0; + } + + // Step 1.5: Calculate total_ue_count + for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { + for (n = 0; n < UE_list->numactiveULCCs[i]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][i]; + UE_template = &UE_list->UE_template[CC_id][i]; + if (!ue_slice_membership(i, slice_id)) + continue; + if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { + total_ue_count[CC_id] += 1; + } + } } LOG_D(MAC, "In ulsch_preprocessor: step2 \n"); // step 2: calculate the average rb per UE - total_ue_count = 0; - max_num_ue_to_be_scheduled = 0; - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); - - if (rnti == NOT_A_RNTI) - continue; - - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - - UE_id = i; - - LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, - rnti); - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - LOG_D(MAC, - "In ulsch_preprocessor: handling UE %d/%x CCid %d\n", - UE_id, rnti, CC_id); - UE_template = &UE_list->UE_template[CC_id][UE_id]; - average_rbs_per_user[CC_id] = 0; - - if (UE_template->pre_allocated_nb_rb_ul > 0) { - total_ue_count += 1; - } - /* - if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<<aggregation)) { - nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation); - max_num_ue_to_be_scheduled+=1; - } */ - - max_num_ue_to_be_scheduled += 1; - - if (total_ue_count == 0) { - average_rbs_per_user[CC_id] = 0; - } else if (total_ue_count == 1) { // increase the available RBs, special case, - average_rbs_per_user[CC_id] = - N_RB_UL - first_rb[CC_id] + 1; - } else if ((total_ue_count <= (N_RB_DL - first_rb[CC_id])) - && (total_ue_count <= max_num_ue_to_be_scheduled)) { - average_rbs_per_user[CC_id] = - (uint16_t) floor((N_RB_UL - first_rb[CC_id]) / - total_ue_count); - } else if (max_num_ue_to_be_scheduled > 0) { - average_rbs_per_user[CC_id] = - (uint16_t) floor((N_RB_UL - first_rb[CC_id]) / - max_num_ue_to_be_scheduled); - } else { - average_rbs_per_user[CC_id] = 1; - LOG_W(MAC, - "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", - module_idP, frameP, subframeP, UE_id, CC_id); - } - } + rnti = UE_RNTI(module_idP, i); + UE_id = i; + + if (rnti == NOT_A_RNTI) + continue; + + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, + rnti); + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + LOG_D(MAC, + "In ulsch_preprocessor: handling UE %d/%x CCid %d\n", + UE_id, rnti, CC_id); + + average_rbs_per_user[CC_id] = 0; + + /* + if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<<aggregation)) { + nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation); + max_num_ue_to_be_scheduled+=1; + } */ + + + + N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); + + if (total_ue_count[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if (total_ue_count[CC_id] == 1) { // increase the available RBs, special case, + average_rbs_per_user[CC_id] = ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] + 1; + } else if (total_ue_count[CC_id] <= (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) { + average_rbs_per_user[CC_id] = (uint16_t) floor((ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]) / total_ue_count[CC_id]); + } else { + average_rbs_per_user[CC_id] = 1; + LOG_W(MAC, + "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", + module_idP, frameP, subframeP, UE_id, CC_id); + } + if (total_ue_count[CC_id] > 0) + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d\n", + module_idP, frameP, subframeP, total_ue_count[CC_id]); + } } - if (total_ue_count > 0) - LOG_D(MAC, - "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n", - module_idP, frameP, subframeP, total_ue_count, - max_num_ue_to_be_scheduled); - - //LOG_D(MAC,"step3\n"); // step 3: assigne RBS for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); - - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - UE_id = i; - - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - harq_pid = - subframe2harqpid(&RC.mac[module_idP]-> - common_channels[CC_id], frameP, - sched_subframeP); - - - // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); - - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id] > 0) { - nb_allocated_rbs[CC_id][UE_id] = - UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; - } else { - nb_allocated_rbs[CC_id][UE_id] = - cmin(UE_list-> - UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul, - average_rbs_per_user[CC_id]); - } - - total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id]; - LOG_D(MAC, - "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n", - nb_allocated_rbs[CC_id][UE_id], UE_id, rnti, CC_id, - harq_pid); - } + rnti = UE_RNTI(module_idP, i); + + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(i, slice_id)) + continue; + + + UE_id = i; + + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id], + frameP, sched_subframeP); + + // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); + + if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id] > 0) { + nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; + } else { + nb_allocated_rbs[CC_id][UE_id] = + cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_id], + average_rbs_per_user[CC_id]); + } + + total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id]; + LOG_D(MAC, + "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n", + nb_allocated_rbs[CC_id][UE_id], UE_id, rnti, CC_id, + harq_pid); + } } // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly - for (r = 0; r < 2; r++) { - - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); + for (r = 0; r < 2; r++) { - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - UE_id = i; - - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - total_remaining_rbs[CC_id] = - N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id]; - - if (total_ue_count == 1) { - total_remaining_rbs[CC_id] += 1; - } - - if (r == 0) { - while ((UE_template->pre_allocated_nb_rb_ul > 0) && - (nb_allocated_rbs[CC_id][UE_id] < - UE_template->pre_allocated_nb_rb_ul) - && (total_remaining_rbs[CC_id] > 0)) { - nb_allocated_rbs[CC_id][UE_id] = - cmin(nb_allocated_rbs[CC_id][UE_id] + 1, - UE_template->pre_allocated_nb_rb_ul); - total_remaining_rbs[CC_id]--; - total_allocated_rbs[CC_id]++; - } - } else { - UE_template->pre_allocated_nb_rb_ul = - nb_allocated_rbs[CC_id][UE_id]; - LOG_D(MAC, - "******************UL Scheduling Information for UE%d CC_id %d ************************\n", - UE_id, CC_id); - LOG_D(MAC, - "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", - module_idP, UE_id, CC_id, - UE_template->pre_allocated_nb_rb_ul); - } - } - } + for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { + rnti = UE_RNTI(module_idP, i); + + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(i, slice_id)) + continue; + + UE_id = i; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + total_remaining_rbs[CC_id] = + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; + + if (total_ue_count[CC_id] == 1) { + total_remaining_rbs[CC_id] += 1; + } + + if (r == 0) { + while ((UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) + && (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_id]) + && (total_remaining_rbs[CC_id] > 0)) { + nb_allocated_rbs[CC_id][UE_id] = + cmin(nb_allocated_rbs[CC_id][UE_id] + 1, + UE_template->pre_allocated_nb_rb_ul[slice_id]); + total_remaining_rbs[CC_id]--; + total_allocated_rbs[CC_id]++; + } + } else { + UE_template->pre_allocated_nb_rb_ul[slice_id] = + nb_allocated_rbs[CC_id][UE_id]; + LOG_D(MAC, + "******************UL Scheduling Information for UE%d CC_id %d ************************\n", + UE_id, CC_id); + LOG_D(MAC, + "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", + module_idP, UE_id, CC_id, + UE_template->pre_allocated_nb_rb_ul[slice_id]); + } + } } + } - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { +#if 0 + /* this logging is wrong, ue_sched_ctl may not be valid here + * TODO: fix + */ + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { if (total_allocated_rbs[CC_id] > 0) { LOG_D(MAC, "[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], - N_RB_UL - first_rb[CC_id]); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]); } } +#endif } void -assign_max_mcs_min_rb(module_id_t module_idP, int frameP, +assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t * first_rb) { - int i; - uint16_t n, UE_id; - uint8_t CC_id; - rnti_t rnti = -1; - int mcs; - int rb_table_index = 0, tbs, tx_power; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - - UE_TEMPLATE *UE_template; - int Ncp; - int N_RB_UL; - - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; - - rnti = UE_RNTI(module_idP, i); - - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - if (UE_list->UE_sched_ctrl[i].phr_received == 1) - mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs - else - mcs = 10; // otherwise, limit to QPSK PUSCH - - UE_id = i; - - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - - if (CC_id >= MAX_NUM_CCs) { - LOG_E(MAC, - "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", - CC_id, MAX_NUM_CCs, n, UE_id, - UE_list->numactiveULCCs[UE_id]); - } - - AssertFatal(CC_id < MAX_NUM_CCs, - "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", - CC_id, MAX_NUM_CCs, n, UE_id, - UE_list->numactiveULCCs[UE_id]); - - UE_template = &UE_list->UE_template[CC_id][UE_id]; - - Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; - N_RB_UL = - to_prb(RC.mac[module_idP]->common_channels[CC_id]. - ul_Bandwidth); - // if this UE has UL traffic - if (UE_template->ul_total_buffer > 0) { - - - tbs = get_TBS_UL(mcs, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! - rb_table_index = 2; - - // fixme: set use_srs flag - tx_power = - estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, - Ncp, 0); - - while ((((UE_template->phr_info - tx_power) < 0) - || (tbs > UE_template->ul_total_buffer)) - && (mcs > 3)) { - // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); - mcs--; - tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; - tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs - } - - while ((tbs < UE_template->ul_total_buffer) && - (rb_table[rb_table_index] < - (N_RB_UL - first_rb[CC_id])) - && ((UE_template->phr_info - tx_power) > 0) - && (rb_table_index < 32)) { - - rb_table_index++; - tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; - tx_power = - estimate_ue_tx_power(tbs, rb_table[rb_table_index], - 0, Ncp, 0); - } + int i; + uint16_t n, UE_id; + uint8_t CC_id; + rnti_t rnti = -1; + int mcs; + int rb_table_index = 0, tbs, tx_power; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; - UE_template->ue_tx_power = tx_power; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *ue_sched_ctl; + int Ncp; + int N_RB_UL; + + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (UE_list->active[i] != TRUE) + continue; + + rnti = UE_RNTI(module_idP, i); + + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(i, slice_id)) + continue; + + if (UE_list->UE_sched_ctrl[i].phr_received == 1) { + /* if we've received the power headroom information the UE, we can go to + * maximum mcs */ + mcs = cmin(20, slice_maxmcs_uplink[slice_id]); + } else { + /* otherwise, limit to QPSK PUSCH */ + mcs = cmin(10, slice_maxmcs_uplink[slice_id]); + } - if (rb_table[rb_table_index] > - (N_RB_UL - first_rb[CC_id] - 1)) { - rb_table_index--; - } - // 1 or 2 PRB with cqi enabled does not work well - if (rb_table[rb_table_index] < 3) { - rb_table_index = 2; //3PRB - } + UE_id = i; - UE_template->pre_assigned_mcs_ul = mcs; - UE_template->pre_allocated_rb_table_index_ul = - rb_table_index; - UE_template->pre_allocated_nb_rb_ul = - rb_table[rb_table_index]; - LOG_D(MAC, - "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", - module_idP, frameP, subframeP, UE_id, CC_id, - UE_template->pre_assigned_mcs_ul, - UE_template->pre_allocated_rb_table_index_ul, - UE_template->pre_allocated_nb_rb_ul, - UE_template->phr_info, tx_power); - } else { - /* if UE has pending scheduling request then pre-allocate 3 RBs */ - //if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) { - if (UE_is_to_be_scheduled(module_idP, CC_id, i)) { - /* use QPSK mcs */ - UE_template->pre_assigned_mcs_ul = 10; - UE_template->pre_allocated_rb_table_index_ul = 2; - UE_template->pre_allocated_nb_rb_ul = 3; - } else { - UE_template->pre_assigned_mcs_ul = 0; - UE_template->pre_allocated_rb_table_index_ul = -1; - UE_template->pre_allocated_nb_rb_ul = 0; - } - } - } + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + + + + AssertFatal(CC_id < RC.nb_mac_CC[module_idP], + "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", + CC_id, NFAPI_CC_MAX, n, UE_id, + UE_list->numactiveULCCs[UE_id]); + + UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_template->pre_assigned_mcs_ul = mcs; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; + N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); + + int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + int bits_to_schedule = bytes_to_schedule * 8; + + // if this UE has UL traffic + if (bits_to_schedule > 0) { + tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! + rb_table_index = 2; + + // fixme: set use_srs flag + tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); + + while ((((UE_template->phr_info - tx_power) < 0) + || (tbs > bits_to_schedule)) + && (UE_template->pre_assigned_mcs_ul > 3)) { + // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); + UE_template->pre_assigned_mcs_ul--; + tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; + tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs + } + + while ((tbs < bits_to_schedule) + && (rb_table[rb_table_index] < (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) + && ((UE_template->phr_info - tx_power) > 0) + && (rb_table_index < 32)) { + rb_table_index++; + tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; + tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); + } + + UE_template->ue_tx_power = tx_power; + + if (rb_table[rb_table_index] > (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - 1)) { + rb_table_index--; + } + // 1 or 2 PRB with cqi enabled does not work well + if (rb_table[rb_table_index] < 3) { + rb_table_index = 2; //3PRB + } + + UE_template->pre_allocated_rb_table_index_ul = rb_table_index; + UE_template->pre_allocated_nb_rb_ul[slice_id] = rb_table[rb_table_index]; + LOG_D(MAC, + "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", + module_idP, frameP, subframeP, UE_id, CC_id, + UE_template->pre_assigned_mcs_ul, + UE_template->pre_allocated_rb_table_index_ul, + UE_template->pre_allocated_nb_rb_ul[slice_id], + UE_template->phr_info, tx_power); + } else { + /* if UE has pending scheduling request then pre-allocate 3 RBs */ + //if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) { + if (UE_is_to_be_scheduled(module_idP, CC_id, i)) { + /* use QPSK mcs */ + UE_template->pre_assigned_mcs_ul = 10; + UE_template->pre_allocated_rb_table_index_ul = 2; + UE_template->pre_allocated_nb_rb_ul[slice_id] = 3; + } else { + UE_template->pre_assigned_mcs_ul = 0; + UE_template->pre_allocated_rb_table_index_ul = -1; + UE_template->pre_allocated_nb_rb_ul[slice_id] = 0; + } + } } + } } struct sort_ue_ul_params { @@ -1688,11 +1785,14 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) return 1; - if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer > - UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) + int bytes_to_schedule1 = UE_list->UE_template[pCCid1][UE_id1].estimated_ul_buffer - UE_list->UE_template[pCCid1][UE_id1].scheduled_ul_bytes; + if (bytes_to_schedule1 < 0) bytes_to_schedule1 = 0; + int bytes_to_schedule2 = UE_list->UE_template[pCCid2][UE_id2].estimated_ul_buffer - UE_list->UE_template[pCCid2][UE_id2].scheduled_ul_bytes; + if (bytes_to_schedule2 < 0) bytes_to_schedule2 = 0; + + if (bytes_to_schedule1 > bytes_to_schedule2) return -1; - if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer < - UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) + if (bytes_to_schedule1 < bytes_to_schedule2) return 1; if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul > @@ -1733,14 +1833,14 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP) { int i; - int list[NUMBER_OF_UE_MAX]; + int list[MAX_MOBILES_PER_ENB]; int list_size = 0; int rnti; struct sort_ue_ul_params params = { module_idP, frameP, subframeP }; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (UE_list->active[i] == FALSE) continue; if ((rnti = UE_RNTI(module_idP, i)) == NOT_A_RNTI) diff --git a/openair2/LAYER2/MAC/proto_NB_IoT.h b/openair2/LAYER2/MAC/proto_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..6e6d98eba1628abc8e20a6c46dae81de5722e4c7 --- /dev/null +++ b/openair2/LAYER2/MAC/proto_NB_IoT.h @@ -0,0 +1,198 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 LAYER2/MAC/proto_NB_IoT.h + * \brief MAC functions prototypes for eNB and UE + * \author Navid Nikaein and Raymond Knopp + * \date 2010 - 2014 + * \email navid.nikaein@eurecom.fr + * \version 1.0 + */ + +#ifndef __LAYER2_MAC_PROTO_NB_IoT_H__ +#define __LAYER2_MAC_PROTO_NB_IoT_H__ + +#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include "LAYER2/MAC/defs_NB_IoT.h" +#include "COMMON/platform_types.h" +#include "openair2/RRC/LITE/defs_NB_IoT.h" +/** \addtogroup _mac + * @{ + */ + +int l2_init_eNB_NB_IoT(void); + +///config +void rrc_mac_config_req_NB_IoT( + module_id_t Mod_idP, + int CC_idP, + int rntiP, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + SystemInformationBlockType1_NB_t *sib1_NB_IoT, + RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon, + PhysicalConfigDedicated_NB_r13_t *physicalConfigDedicated, + LogicalChannelConfig_NB_r13_t *logicalChannelConfig, //FIXME: decide how to use it + uint8_t ded_flag, + uint8_t ue_list_ded_num); + +///system +void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst); +//void init_rrc_NB_IoT(); +void release_mac_inst(uint8_t order); +eNB_MAC_INST_NB_IoT *get_mac_inst(uint8_t order); +uint8_t register_mac_inst(eNB_MAC_INST_NB_IoT *inst, uint8_t order); + +///tool +void init_tool(sib1_NB_IoT_sched_t *config); +void UE_info_setting(UE_TEMPLATE_NB_IoT *UE_info); +UE_TEMPLATE_NB_IoT *get_ue_from_rnti(eNB_MAC_INST_NB_IoT *inst, rnti_t rnti); + +///scheduler +void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe); +void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe); + +//Calvin temp define self-tools +int init_debug(eNB_MAC_INST_NB_IoT *inst); +void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst); +void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe); +available_resource_DL_t *check_sibs_resource(eNB_MAC_INST_NB_IoT *mac_inst, int check_start_subframe, int check_end_subframe, int num_subframe, int *residual_subframe, int *out_last_subframe, int *out_first_subframe); +uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe); +void init(eNB_MAC_INST_NB_IoT *mac_inst); +void init_dl_list(eNB_MAC_INST_NB_IoT *mac_inst); +int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void fill_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, available_resource_DL_t *node, int start_subframe, int end_subframe, schedule_result_t *new_node); +available_resource_DL_t *check_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int check_subframe, int num_subframes, int *out_last_subframe, int *out_first_subframe); +void print_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst); +void print_schedule_result_DL(void); +void print_schedule_result_UL(void); +void add_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce, uint32_t PHR, uint32_t ul_total_buffer); +void remove_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce); +// SIBs +void schedule_sibs(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t sibs_order, int start_subframe); + +//RA +void msg3_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti); +void msg4_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti); +void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst); +void init_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint8_t preamble_index, ce_level_t ce_level, uint32_t sfn_id, uint16_t ta); +void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void receive_msg3_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti, uint32_t phr, uint32_t ul_total_buffer); +void schedule_msg3_retransimission_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void fill_rar_NB_IoT(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template, uint8_t msg3_schedule_delay, uint8_t msg3_rep, sched_temp_UL_NB_IoT_t *schedule_template); +void receive_msg4_ack_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t rnti); + +//USS +void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int index_ss); + +//DATA +uint8_t *parse_ulsch_header( uint8_t *mac_header, + uint8_t *num_ce, + uint8_t *num_sdu, + uint8_t *rx_ces, + uint8_t *rx_lcids, + uint16_t *rx_lengths, + uint16_t tb_length ); + +/*******UL Scheduler**********/ +void print_scheduling_result_UL(void); +void print_available_UL_resource(void); +/*set nprach configuration at intial time*/ +void setting_nprach(void); +/*Uplink main scheduler*/ +int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info, uint32_t subframe, uint32_t frame, uint32_t H_SFN); +/*Check available uplink resource list, if there is available uplink resource, return 0, otherwise, return 1*/ +int Check_UL_resource(uint32_t DL_end, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int multi_tone, int fmt2_flag); +/*Get I Repetition number in DCI*/ +int get_I_REP(int N_rep); +/*Get N REP from preamble repeat*/ +int get_N_REP(int CE_level); +/*Get TBS from mcs, multi-tone, Iru*/ +int get_TBS_UL_NB_IoT(uint32_t mcs,uint32_t multi_tone,int Iru); +/*get I tbs from mcs and multi-tone*/ +int get_I_TBS_NB_IoT(int x,int y); +/*Get DCI REP from R max and R*/ +int get_DCI_REP(uint32_t R,uint32_t R_max); +/*Check single tone resource list*/ +int single_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int fmt2_flag); +/*Check multi tone resource list*/ +int multi_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info); +/*Generate scheduling result of DCI N0 and Uplink config*/ +void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subframe, uint32_t UL_subframe, uint32_t UL_end_subframe, DCIFormatN0_t *DCI_inst, rnti_t rnti, uint8_t *ul_debug_str, uint8_t *dl_debug_str); +/*Adjust UL resource by removing the used resource*/ +void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info); +/*Initialize resource by nprach configuration*/ +void Initialize_Resource(void); +/*Function to extend uplink resource grid*/ +//void add_UL_Resource(eNB_MAC_INST_NB_IoT *mac_inst); +void add_UL_Resource(void); +/*Get ACK/NAK resource field*/ +int get_resource_field_value(int subcarrier, int k0); +/*Get DL Repetition index*/ +uint8_t get_index_Rep_dl(uint16_t R); + +/*******DL Scheduler********/ +void schedule_DL_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, UE_TEMPLATE_NB_IoT *UE_info, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start); +int check_resource_NPDCCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, sched_temp_DL_NB_IoT_t *NPDCCH_info, uint32_t cdd_num, uint32_t dci_rep); +int check_resource_NPDSCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDSCH_info, uint32_t sf_end, uint32_t I_delay, uint32_t R_max, uint32_t R_dl, uint32_t n_sf); +int check_resource_DL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, uint32_t dlsf_require, sched_temp_DL_NB_IoT_t *schedule_info); +uint32_t get_I_mcs(int CE_level); +uint32_t get_max_tbs(uint32_t I_tbs); +uint32_t get_tbs(uint32_t data_size, uint32_t I_tbs, uint32_t *I_sf); +uint32_t get_num_sf(uint32_t I_sf); +uint32_t get_scheduling_delay(uint32_t I_delay, uint32_t R_max); +uint32_t get_HARQ_delay(int subcarrier_spacing, uint32_t HARQ_delay_index); +//void generate_scheduling_result_DL(uint32_t DCI_subframe, uint32_t NPDSCH_subframe, uint32_t HARQ_subframe, DCIFormatN1_t *DCI, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu); +void generate_scheduling_result_DL(sched_temp_DL_NB_IoT_t* DCI_info, sched_temp_DL_NB_IoT_t* NPDSCH_info, sched_temp_UL_NB_IoT_t* HARQ_info, DCIFormatN1_t *DCI_inst, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu); +void fill_DCI_N1(DCIFormatN1_t *DCI_N1, UE_TEMPLATE_NB_IoT *UE_info, uint32_t scheddly, uint32_t I_sf, uint32_t I_harq); +//Transfrom source into hyperSF, Frame, Subframe format +void convert_system_number(uint32_t source_sf,uint32_t *hyperSF, uint32_t *frame, uint32_t *subframe); +//Trnasform hyperSF, Frame, Subframe format into subframe unit +uint32_t convert_system_number_sf(uint32_t hyperSF, uint32_t frame, uint32_t subframe); +/*input start position amd num_dlsf DL subframe, caculate the last subframe number*/ +uint32_t cal_num_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF, uint32_t frame, uint32_t subframe, uint32_t* hyperSF_result, uint32_t* frame_result, uint32_t* subframe_result, uint32_t num_dlsf_require); +void init_dlsf_info(eNB_MAC_INST_NB_IoT *mac_inst, DLSF_INFO_t *DLSF_info); +uint32_t generate_dlsch_header_NB_IoT(uint8_t *pdu, uint32_t num_sdu, logical_chan_id_t *logical_channel, uint32_t *sdu_length, uint8_t flag_drx, uint8_t flag_ta, uint32_t TBS); +void maintain_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDCCH_info, sched_temp_DL_NB_IoT_t *NPDSCH_info); +void init_tool_sib1(eNB_MAC_INST_NB_IoT *mac_inst); +//int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +/**DL test , delete**/ +available_resource_DL_t* new_dl_node(uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf); +void initialize_dl_resource(available_resource_DL_t *DL_Resource_node, uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf); +void insert_dl_resource(available_resource_DL_t *DL_Resource_node); +void insert_schedule_result(schedule_result_t **list, int subframe, schedule_result_t *node); +//interface with IF + +uint8_t *parse_ulsch_header_NB_IoT( uint8_t *mac_header, uint8_t *num_ce, uint8_t *num_sdu, uint8_t *rx_ces, uint8_t *rx_lcids, uint16_t *rx_lengths, uint16_t tb_length); + +void rx_sdu_NB_IoT(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t subframe, uint16_t rnti, uint8_t *sdu, uint16_t length); + +int output_handler(eNB_MAC_INST_NB_IoT *mac_inst, module_id_t module_id, int CC_id, uint32_t hypersfn, uint32_t frame, uint32_t subframe, uint8_t MIB_flag, uint8_t SIB1_flag, uint32_t current_time); +// main + +void mac_top_init_eNB_NB_IoT(void); + +uint32_t to_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_CarrierFreq, float m_dl); + +uint32_t from_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_earfcn, float m_dl); + +int32_t get_uldl_offset_NB_IoT(int eutra_band); +#endif diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index 3f2df025c773db688fd255b1439d86dcb15e4478..5a66645e3d81e9d5b2ae324372d111193af5eab3 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -30,71 +30,25 @@ * \warning */ -#include "extern.h" -#include "defs.h" -#include "proto.h" +#include "mac_extern.h" +#include "mac.h" +#include "mac_proto.h" #include "UTIL/LOG/vcd_signal_dumper.h" -#include "PHY_INTERFACE/extern.h" -#include "SCHED/defs.h" +#include "PHY_INTERFACE/phy_interface_extern.h" +#include "SCHED_UE/sched_UE.h" #include "COMMON/mac_rrc_primitives.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "UTIL/LOG/log.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#ifdef PHY_EMUL -#include "SIMULATION/simulation_defs.h" -#endif - -#include "SIMULATION/TOOLS/defs.h" // for taus - -int8_t get_DELTA_PREAMBLE(module_id_t module_idP, int CC_id) -{ - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - uint8_t prachConfigIndex = - UE_mac_inst[module_idP].radioResourceConfigCommon-> - prach_Config.prach_ConfigInfo.prach_ConfigIndex; - uint8_t preambleformat; - - if (UE_mac_inst[module_idP].tdd_Config) { // TDD - if (prachConfigIndex < 20) { - preambleformat = 0; - } else if (prachConfigIndex < 30) { - preambleformat = 1; - } else if (prachConfigIndex < 40) { - preambleformat = 2; - } else if (prachConfigIndex < 48) { - preambleformat = 3; - } else { - preambleformat = 4; - } - } else { // FDD - preambleformat = prachConfigIndex >> 2; - } - - switch (preambleformat) { - case 0: - case 1: - return (0); - - case 2: - case 3: - return (-3); - - case 4: - return (8); - - default: - AssertFatal(1 == 0, - "[UE %d] ue_procedures.c: FATAL, Illegal preambleformat %d, prachConfigIndex %d\n", - module_idP, preambleformat, prachConfigIndex); - } - -} +#include "SIMULATION/TOOLS/sim.h" // for taus +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" +extern uint8_t nfapi_mode; +extern UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); /// This routine implements Section 5.1.2 (UE Random Access Resource Selection) from 36.321 void @@ -105,7 +59,6 @@ get_prach_resources(module_id_t module_idP, uint8_t first_Msg3, RACH_ConfigDedicated_t * rach_ConfigDedicated) { - uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources; @@ -344,9 +297,18 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, sub_frame_t subframeP) { - uint8_t Size = 0; - UE_MODE_t UE_mode = get_ue_mode(module_idP, 0, eNB_indexP); + UE_MODE_t UE_mode; + // Panos: Modification for phy_stub_ue operation + if(nfapi_mode == 3) { // Panos: phy_stub_ue mode + UE_mode = UE_mac_inst[module_idP].UE_mode[0]; + LOG_D(MAC, "ue_get_rach , UE_mode: %d", UE_mode); + } + else { // Full stack mode + UE_mode = get_ue_mode(module_idP,0,eNB_indexP); + } + + uint8_t lcid = CCCH; uint16_t Size16; struct RACH_ConfigCommon *rach_ConfigCommon = @@ -361,6 +323,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, "Transmission on secondary CCs is not supported yet\n"); if (UE_mode == PRACH) { + LOG_D(MAC, "ue_get_rach 3, RA_active value: %d", UE_mac_inst[module_idP].RA_active); if (UE_mac_inst[module_idP].radioResourceConfigCommon) { rach_ConfigCommon = &UE_mac_inst[module_idP]. @@ -372,14 +335,14 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, if (UE_mac_inst[module_idP].RA_active == 0) { LOG_I(MAC, "RA not active\n"); // check if RRC is ready to initiate the RA procedure - Size = mac_rrc_data_req(module_idP, + Size = mac_rrc_data_req_ue(module_idP, CC_id, frameP, CCCH, 1, &UE_mac_inst[module_idP]. CCCH_pdu.payload[sizeof (SCH_SUBHEADER_SHORT) - + 1], 0, eNB_indexP, + + 1], eNB_indexP, 0); Size16 = (uint16_t) Size; @@ -392,7 +355,6 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, module_idP, frameP, Size); if (Size > 0) { - UE_mac_inst[module_idP].RA_active = 1; UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1; @@ -447,7 +409,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, subframeP, - ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6); + ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6 +#ifdef Rel14 + ,0, 0 +#endif + ); + if (UE_mac_inst[module_idP].crnti_before_ho) LOG_D(MAC, @@ -463,7 +430,13 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, dcch_header_len); sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used - (char *) &ulsch_buff[0]); + (char *) &ulsch_buff[0] +#ifdef Rel14 + ,0, + 0 +#endif + ); + LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n", module_idP, sdu_lengths[0]); diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 28dba58a3edff319441342d9da1d2ade5bd711c1..9e5824fdd38eecadf44da1b77a58a361e1ac2179 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -28,10 +28,10 @@ */ -#include "defs.h" -#include "proto.h" -#include "extern.h" -#include "SIMULATION/TOOLS/defs.h" +#include "mac.h" +#include "mac_proto.h" +#include "mac_extern.h" +#include "SIMULATION/TOOLS/sim.h" #include "UTIL/LOG/log.h" #include "OCG.h" #include "OCG_extern.h" @@ -108,7 +108,7 @@ fill_rar(const module_id_t module_idP, return (ra->rnti); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //------------------------------------------------------------------------------ unsigned short fill_rar_br(eNB_MAC_INST * eNB, @@ -192,104 +192,3 @@ fill_rar_br(eNB_MAC_INST * eNB, } #endif -//------------------------------------------------------------------------------ -uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const frame_t frameP, const rnti_t ra_rnti, uint8_t * const dlsch_buffer, rnti_t * const t_crnti, const uint8_t preamble_index, uint8_t * selected_rar_buffer // output argument for storing the selected RAR header and RAR payload - ) -//------------------------------------------------------------------------------ -{ - uint16_t ret = 0; // return value - - RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; - // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); - uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); - - // get the last RAR payload for working with CMW500 - uint8_t n_rarpy = 0; // number of RAR payloads - uint8_t n_rarh = 0; // number of MAC RAR subheaders - uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs - while (1) { - n_rarh++; - if (rarh->T == 1) { - n_rarpy++; - LOG_D(MAC, "RAPID %d\n", rarh->RAPID); - } - - if (rarh->RAPID == preamble_index) { - LOG_D(PHY, "Found RAR with the intended RAPID %d\n", - rarh->RAPID); - rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); - break; - } - - if (abs((int) rarh->RAPID - (int) preamble_index) < - abs((int) best_rx_rapid - (int) preamble_index)) { - best_rx_rapid = rarh->RAPID; - rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); - } - - if (rarh->E == 0) { - LOG_I(PHY, - "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", - best_rx_rapid); - break; - } else { - rarh++; - } - }; - LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", - n_rarh, n_rarpy); - - if (CC_id > 0) { - LOG_W(MAC, "Should not have received RAR on secondary CCs! \n"); - return (0xffff); - } - - LOG_I(MAC, - "[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", - module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], - rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); -#ifdef DEBUG_RAR - LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", module_idP, rarh->E); - LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", module_idP, rarh->T); - LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", module_idP, - rarh->RAPID); - - // LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R); - LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n", - module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); - // LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag); - // LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc); - // LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs); - // LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC); - // LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay); - // LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req); - LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", module_idP, - (uint16_t) rar[5] + (rar[4] << 8)); -#endif - - if (opt_enabled) { - LOG_D(OPT, - "[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n", - module_idP, CC_id, frameP, ra_rnti); - trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, - module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame, - UE_mac_inst[module_idP].rxSubframe, 0, 0); - } - - if (preamble_index == rarh->RAPID) { - *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti; - UE_mac_inst[module_idP].crnti = *t_crnti; //rar->t_crnti; - //return(rar->Timing_Advance_Command); - ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); - } else { - UE_mac_inst[module_idP].crnti = 0; - ret = (0xffff); - } - - // move the selected RAR to the front of the RA_PDSCH buffer - memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1); - memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6); - - return ret; - -} diff --git a/openair2/LAYER2/MAC/rar_tools_ue.c b/openair2/LAYER2/MAC/rar_tools_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..7d24e4c0af31c5fd2a87ea13ec06427f08902d6f --- /dev/null +++ b/openair2/LAYER2/MAC/rar_tools_ue.c @@ -0,0 +1,143 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 rar_tools.c + * \brief random access tools + * \author Raymond Knopp and navid nikaein + * \date 2011 - 2014 + * \version 1.0 + * @ingroup _mac + + */ + +#include "mac.h" +#include "mac_proto.h" +#include "mac_extern.h" +#include "SIMULATION/TOOLS/sim.h" +#include "UTIL/LOG/log.h" +#include "OCG.h" +#include "OCG_extern.h" +#include "UTIL/OPT/opt.h" +#include "common/ran_context.h" + +#define DEBUG_RAR + +//------------------------------------------------------------------------------ +uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const frame_t frameP, const rnti_t ra_rnti, uint8_t * const dlsch_buffer, rnti_t * const t_crnti, const uint8_t preamble_index, uint8_t * selected_rar_buffer // output argument for storing the selected RAR header and RAR payload + ) +//------------------------------------------------------------------------------ +{ + uint16_t ret = 0; // return value + + RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; + // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); + uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); + + // get the last RAR payload for working with CMW500 + uint8_t n_rarpy = 0; // number of RAR payloads + uint8_t n_rarh = 0; // number of MAC RAR subheaders + uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs + while (1) { + n_rarh++; + if (rarh->T == 1) { + n_rarpy++; + LOG_D(MAC, "RAPID %d\n", rarh->RAPID); + } + + if (rarh->RAPID == preamble_index) { + LOG_D(PHY, "Found RAR with the intended RAPID %d\n", + rarh->RAPID); + rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); + break; + } + + if (abs((int) rarh->RAPID - (int) preamble_index) < + abs((int) best_rx_rapid - (int) preamble_index)) { + best_rx_rapid = rarh->RAPID; + rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); + } + + if (rarh->E == 0) { + LOG_I(PHY, + "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", + best_rx_rapid); + break; + } else { + rarh++; + } + }; + LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", + n_rarh, n_rarpy); + + if (CC_id > 0) { + LOG_W(MAC, "Should not have received RAR on secondary CCs! \n"); + return (0xffff); + } + + LOG_I(MAC, + "[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", + module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], + rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); +#ifdef DEBUG_RAR + LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", module_idP, rarh->E); + LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", module_idP, rarh->T); + LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", module_idP, + rarh->RAPID); + + // LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R); + LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n", + module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); + // LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag); + // LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc); + // LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs); + // LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC); + // LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay); + // LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req); + LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", module_idP, + (uint16_t) rar[5] + (rar[4] << 8)); +#endif + + if (opt_enabled) { + LOG_D(OPT, + "[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n", + module_idP, CC_id, frameP, ra_rnti); + trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, + module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); + } + + if (preamble_index == rarh->RAPID) { + *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti; + UE_mac_inst[module_idP].crnti = *t_crnti; //rar->t_crnti; + //return(rar->Timing_Advance_Command); + ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); + } else { + UE_mac_inst[module_idP].crnti = 0; + ret = (0xffff); + } + + // move the selected RAR to the front of the RA_PDSCH buffer + memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1); + memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6); + + return ret; + +} diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 7a9b811d0e86cd9e47daa747e3cfe04e0e4d1468..948f6c08d0032c6a105a2d6850aa01431e390db2 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -33,29 +33,25 @@ #include <pthread.h> #endif -#include "extern.h" -#include "defs.h" -#include "proto.h" -#ifdef PHY_EMUL -#include "SIMULATION/PHY_EMULATION/impl_defs.h" -#else -#include "SCHED/defs.h" +#include "mac_extern.h" +#include "mac.h" +#include "mac_proto.h" +#include "SCHED_UE/sched_UE.h" #include "PHY/impl_defs_top.h" -#endif -#include "PHY_INTERFACE/extern.h" +#include "PHY_INTERFACE/phy_interface_extern.h" #include "COMMON/mac_rrc_primitives.h" +#include "PHY/INIT/phy_init.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" +#include "openair2/PHY_INTERFACE/phy_stub_UE.h" -#ifdef PHY_EMUL -#include "SIMULATION/simulation_defs.h" -#endif #include "pdcp.h" #if defined(ENABLE_ITTI) @@ -64,13 +60,24 @@ #include "assertions.h" -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #define DEBUG_HEADER_PARSING 1 #define ENABLE_MAC_PAYLOAD_DEBUG 1 extern uint8_t usim_test; +extern UL_IND_t *UL_INFO; + +extern uint8_t nfapi_mode; + +/* + * +#ifndef USER_MODE +#define msg debug_msg +#endif + */ + mapping BSR_names[] = { {"NONE", 0}, {"SHORT BSR", 1}, @@ -83,6 +90,7 @@ mapping BSR_names[] = { void ue_init_mac(module_id_t module_idP) { + int i; // default values as deined in 36.331 sec 9.2.2 LOG_I(MAC, "[UE%d] Applying default macMainConfig\n", module_idP); @@ -145,6 +153,19 @@ void ue_init_mac(module_id_t module_idP) UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0; } + if(nfapi_mode == 3) { + pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL); + UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH; + UE_mac_inst[module_idP].first_ULSCH_Tx =0; + UE_mac_inst[module_idP].SI_Decoded = 0; + next_ra_frame = 0; + next_Mod_id = 0; + tx_request_pdu_list = NULL; + tx_req_num_elems = 0; + + + } + #ifdef CBA for (i = 0; i < NUM_MAX_CBA_GROUP; i++) { @@ -395,7 +416,8 @@ ue_send_sdu(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); - LOG_T(MAC, "sdu: %x.%x.%x\n", sdu[0], sdu[1], sdu[2]); + + //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); if (opt_enabled) { trace_pdu(1, sdu, sdu_len, module_idP, 3, @@ -453,7 +475,16 @@ ue_send_sdu(module_id_t module_idP, LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP); - ra_failed(module_idP, CC_id, eNB_index); + if(nfapi_mode == 3) { // Panos: phy_stub mode + // Panos: Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to + // PRACH state. + LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n"); + UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH; + //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; + } + else{ + ra_failed(module_idP, CC_id, eNB_index); + } UE_mac_inst [module_idP]. RA_contention_resolution_timer_active = 0; @@ -469,7 +500,14 @@ ue_send_sdu(module_id_t module_idP, UE_mac_inst [module_idP]. RA_contention_resolution_timer_active = 0; - ra_succeeded(module_idP, CC_id, eNB_index); + if(nfapi_mode == 3) // phy_stub mode + { + //Panos: Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH + UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH; + } + else { // Full stack mode + ra_succeeded(module_idP,CC_id,eNB_index); + } } payload_ptr += 6; @@ -480,9 +518,14 @@ ue_send_sdu(module_id_t module_idP, LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, payload_ptr[0]); #endif - process_timing_advance(module_idP, CC_id, payload_ptr[0]); - payload_ptr++; - break; + + // Panos: Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct? + if (nfapi_mode!=3) + { + process_timing_advance(module_idP,CC_id,payload_ptr[0]); + } + payload_ptr++; + break; case DRX_CMD: #ifdef DEBUG_HEADER_PARSING @@ -498,7 +541,6 @@ ue_send_sdu(module_id_t module_idP, LOG_D(MAC, "[UE] SDU %d : LCID %d, length %d\n", i, rx_lcids[i], rx_lengths[i]); #endif - if (rx_lcids[i] == CCCH) { LOG_D(MAC, @@ -515,13 +557,14 @@ ue_send_sdu(module_id_t module_idP, LOG_T(MAC, "\n"); #endif - mac_rrc_data_ind(module_idP, + + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, subframeP, UE_mac_inst[module_idP].crnti, CCCH, (uint8_t *) payload_ptr, - rx_lengths[i], ENB_FLAG_NO, eNB_index, 0); + rx_lengths[i], eNB_index, 0); } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) { LOG_D(MAC, @@ -584,9 +627,9 @@ ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP, LOG_D(MAC, "[UE %d] Frame %d Sending SI to RRC (LCID Id %d,len %d)\n", module_idP, frameP, BCCH, len); - mac_rrc_data_ind(module_idP, CC_id, frameP, 0, // unknown subframe + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe SI_RNTI, - BCCH, (uint8_t *) pdu, len, ENB_FLAG_NO, eNB_index, + BCCH, (uint8_t *) pdu, len, eNB_index, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); @@ -622,9 +665,9 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, "[UE %d] Frame %d Sending Paging message to RRC (LCID Id %d,len %d)\n", module_idP, frameP, PCCH, len); - mac_rrc_data_ind(module_idP, CC_id, frameP, 0, // unknown subframe + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe P_RNTI, - PCCH, (uint8_t *) pdu, len, ENB_FLAG_NO, eNB_index, + PCCH, (uint8_t *) pdu, len, eNB_index, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT); @@ -646,7 +689,7 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, } } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) unsigned char *parse_mch_header(unsigned char *mac_header, unsigned char *num_sdu, unsigned char *rx_lcids, @@ -744,10 +787,10 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, "[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n", module_idP, frameP, i, sync_area, eNB_index, rx_lengths[i]); - mac_rrc_data_ind(module_idP, CC_id, frameP, 0, // unknown subframe + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe M_RNTI, MCCH, - payload_ptr, rx_lengths[i], 0, eNB_index, + payload_ptr, rx_lengths[i], eNB_index, sync_area); } else if (rx_lcids[i] == MTCH) { if (UE_mac_inst[module_idP].msi_status == 1) { @@ -778,9 +821,93 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, #endif } -int8_t -ue_get_mbsfn_sf_alloction(module_id_t module_idP, - uint8_t mbsfn_sync_area, unsigned char eNB_index) +void ue_send_sl_sdu(module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t* sdu, + uint16_t sdu_len, + uint8_t eNB_index, + sl_discovery_flag_t sl_discovery_flag + ) { + + int rlc_sdu_len; + char *rlc_sdu; + uint32_t destinationL2Id =0x00000000; + + if (sl_discovery_flag == SL_DISCOVERY_FLAG_NO) { + + // Notes: 1. no control elements are supported yet + // 2. we exit with error if LCID != 3 + // 3. we exit with error if E=1 (more than one SDU/CE) + // extract header + SLSCH_SUBHEADER_24_Bit_DST_LONG *longh = (SLSCH_SUBHEADER_24_Bit_DST_LONG *)sdu; + AssertFatal(longh->E==0,"E is non-zero\n"); + AssertFatal(((longh->LCID==3)|(longh->LCID==10)),"LCID is %d (not 3 or 10)\n",longh->LCID); + //filter incoming packet based on destination address + destinationL2Id = (longh->DST07<<16) | (longh->DST815 <<8) | (longh->DST1623); + LOG_I( MAC, "[DestinationL2Id: 0x%08x] \n", destinationL2Id ); + //in case of 1-n communication, verify that UE belongs to that group + int i=0; + for (i=0; i< MAX_NUM_DEST; i++) + if (UE_mac_inst[module_idP].destinationList[i] == destinationL2Id) break; + //match the destinationL2Id with UE L2Id or groupL2ID + if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (i < MAX_NUM_DEST))){ + LOG_I( MAC, "[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!! \n"); + return; + } + + + if (longh->F==1) { + rlc_sdu_len = ((longh->L_MSB<<8)&0x7F00)|(longh->L_LSB&0xFF); + rlc_sdu = (char *)sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG); + } + else { + rlc_sdu_len = ((SLSCH_SUBHEADER_24_Bit_DST_SHORT *)sdu)->L; + rlc_sdu = (char *)sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_SHORT); + } + mac_rlc_data_ind( + module_idP, + 0x1234, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + longh->LCID, //3/10 + rlc_sdu, + rlc_sdu_len, + 1, + NULL); + } else { //SL_DISCOVERY + uint16_t len = sdu_len; + LOG_I( MAC, "SL DISCOVERY \n"); + // Panos: Ask TTN if we should be calling mac_rrc_data_ind_ue() instead of mac_rrc_data_ind() now! + /*mac_rrc_data_ind(module_idP, + CC_id, + frameP,subframeP, + UE_mac_inst[module_idP].crnti, + SL_DISCOVERY, + sdu, //(uint8_t*)&UE_mac_inst[Mod_id].SL_Discovery[0].Rx_buffer.Payload[0], + len, + ENB_FLAG_NO, + eNB_index, + 0);*/ + mac_rrc_data_ind_ue(module_idP, + CC_id, + frameP,subframeP, + UE_mac_inst[module_idP].crnti, + SL_DISCOVERY, + sdu, //(uint8_t*)&UE_mac_inst[Mod_id].SL_Discovery[0].Rx_buffer.Payload[0], + len, + eNB_index, + 0); + + } +} + + +int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_area, unsigned char eNB_index) + { // currently there is one-to-one mapping between sf allocation pattern and sync area if (mbsfn_sync_area >= MAX_MBSFN_AREA) { @@ -1496,6 +1623,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t * ulsch_buffer, uint16_t buflen, uint8_t * access_mode) { + //LOG_I(MAC, "Panos-D: UE[%d] In ue_get_sdu() 1 \n", module_idP); uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0; uint16_t buflen_remain = 0; uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; @@ -1724,9 +1852,13 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, MBMS_FLAG_NO, lcid, buflen_remain, - (char *) - &ulsch_buff - [sdu_length_total]); + (char *)&ulsch_buff[sdu_length_total] +#ifdef Rel14 + ,0, + 0 +#endif + ); + AssertFatal(buflen_remain >= sdu_lengths[num_sdus], @@ -1864,7 +1996,15 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, } // build PHR and update the timers if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { - phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index); + if(nfapi_mode ==3){ + //Panos: Substitute with a static value for the MAC layer abstraction (phy_stub mode) + phr_p->PH = 40; + } + else{ + phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index); + } + + phr_p->R = 0; LOG_D(MAC, "[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", @@ -1878,7 +2018,6 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, LOG_T(MAC, "[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n", module_idP, frameP, bsr_s, bsr_l, phr_p); - // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 /* For Padding BSR: @@ -2073,6 +2212,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, buflen - sdu_length_total - payload_offset); // cycle through SDUs and place in ulsch_buffer if (sdu_length_total) { + //LOG_I(MAC, "Panos-D: [UE %d] ue_get_sdu() 2 before copying to ulsch_buffer, SFN/SF: %d/%d \n \n \n", module_idP, frameP, subframe); memcpy(&ulsch_buffer[payload_offset], ulsch_buff, sdu_length_total); } @@ -2139,6 +2279,8 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, } } + + //------------------------------------------------------------------------------ // called at each subframe // Performs : @@ -2230,10 +2372,10 @@ ue_scheduler(const module_id_t module_idP, UE_mac_inst[module_idP].rxSubframe = rxSubframeP; #ifdef CELLULAR - rrc_rx_tx(module_idP, txFrameP, 0, eNB_indexP); + rrc_rx_tx_ue(module_idP, txFrameP, 0, eNB_indexP); #else - switch (rrc_rx_tx(&ctxt, eNB_indexP, CC_id)) { + switch (rrc_rx_tx_ue(&ctxt, eNB_indexP, CC_id)) { case RRC_OK: break; @@ -2300,6 +2442,7 @@ ue_scheduler(const module_id_t module_idP, #if UE_TIMING_TRACE stop_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif + //return(RRC_OK); } @@ -2323,7 +2466,17 @@ ue_scheduler(const module_id_t module_idP, LOG_E(MAC, "Module id %u Contention resolution timer expired, RA failed\n", module_idP); - ra_failed(module_idP, 0, eNB_indexP); + if(nfapi_mode == 3) { // Panos: phy_stub mode + // Panos: Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to + // PRACH state. + LOG_I(MAC, "nfapi_mode3: Setting UE_mode to PRACH 2 \n"); + UE_mac_inst[module_idP].UE_mode[eNB_indexP] = PRACH; + //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; + } + else{ + ra_failed(module_idP, CC_id, eNB_indexP); + } + //ra_failed(module_idP, 0, eNB_indexP); } } // Get RLC status info and update Bj for all lcids that are active @@ -2641,92 +2794,92 @@ update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, eNB_index_t eNB_index) { - mac_rlc_status_resp_t rlc_status; - boolean_t bsr_regular_triggered = FALSE; - uint8_t lcid; - uint8_t lcgid; - uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined - uint16_t lcgid_buffer_remain[MAX_NUM_LCGID] = { 0, 0, 0, 0 }; - int32_t lcid_bytes_in_buffer[MAX_NUM_LCID]; - /* Array for ordering LCID with data per decreasing priority order */ - uint8_t lcid_reordered_array[MAX_NUM_LCID] = - { MAX_NUM_LCID, MAX_NUM_LCID, MAX_NUM_LCID, MAX_NUM_LCID, - MAX_NUM_LCID, MAX_NUM_LCID, MAX_NUM_LCID, MAX_NUM_LCID, - MAX_NUM_LCID, - MAX_NUM_LCID, MAX_NUM_LCID - }; - uint8_t pos_next = 0; - uint8_t highest_priority = 16; - uint8_t array_index = 0; - - // Reset All BSR Infos - lcid_bytes_in_buffer[0] = 0; - for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { - // Reset transmission status - lcid_bytes_in_buffer[lcid] = 0; - UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = - LCID_EMPTY; - } - - for (lcgid = 0; lcgid < MAX_NUM_LCGID; lcgid++) { - // Reset Buffer Info - UE_mac_inst[module_idP].scheduling_info.BSR[lcgid] = 0; - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] = 0; - } - - //Get Buffer Occupancy and fill lcid_reordered_array - for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { - if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) { - lcgid = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]; - - // Store already available data to transmit per Group - if (lcgid < MAX_NUM_LCGID) { - lcgid_buffer_remain[lcgid] += - UE_mac_inst[module_idP]. - scheduling_info.LCID_buffer_remain[lcid]; - } - - rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP, subframeP, ENB_FLAG_NO, MBMS_FLAG_NO, lcid, 0xFFFF); //TBS is not used in RLC at this step, set a special value for debug - - lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d subframe %d\n", - module_idP, lcid, lcgid, rlc_status.bytes_in_buffer, - frameP, subframeP); - - UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = - LCID_NOT_EMPTY; - //Update BSR_bytes and position in lcid_reordered_array only if Group is defined - if (lcgid < MAX_NUM_LCGID) { - num_lcid_with_data++; - // sum lcid buffer which has same lcgid - UE_mac_inst[module_idP].scheduling_info. - BSR_bytes[lcgid] += rlc_status.bytes_in_buffer; - - //Fill in the array - array_index = 0; - do { - if (UE_mac_inst[module_idP].logicalChannelConfig - [lcid]->ul_SpecificParameters->priority <= - highest_priority) { - //Insert if priority is higher or equal (lower or equal in value) - for (pos_next = num_lcid_with_data - 1; - pos_next > array_index; pos_next--) { - lcid_reordered_array[pos_next] = - lcid_reordered_array[pos_next - 1]; - - } - lcid_reordered_array[array_index] = lcid; - break; - - } - array_index++; - } - while ((array_index < num_lcid_with_data) - && (array_index < MAX_NUM_LCID)); - } + mac_rlc_status_resp_t rlc_status; + boolean_t bsr_regular_triggered = FALSE; + uint8_t lcid; + uint8_t lcgid; + uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined + uint16_t lcgid_buffer_remain[MAX_NUM_LCGID] = {0,0,0,0}; + int32_t lcid_bytes_in_buffer[MAX_NUM_LCID]; + /* Array for ordering LCID with data per decreasing priority order */ + uint8_t lcid_reordered_array[MAX_NUM_LCID]= + {MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID}; + uint8_t pos_next = 0; + uint8_t highest_priority = 16; + uint8_t array_index = 0; + + // Reset All BSR Infos + lcid_bytes_in_buffer[0] = 0; + for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++) + { + // Reset transmission status + lcid_bytes_in_buffer[lcid] = 0; + UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid]=LCID_EMPTY; + } + + for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++) + { + // Reset Buffer Info + UE_mac_inst[module_idP].scheduling_info.BSR[lcgid]=0; + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid]=0; + } + + //Get Buffer Occupancy and fill lcid_reordered_array + for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++) + { + if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) + { + lcgid = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]; + + // Store already available data to transmit per Group + if (lcgid < MAX_NUM_LCGID) + { + lcgid_buffer_remain[lcgid] += UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]; + } + + rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, + lcid, + 0xFFFF //TBS is not used in RLC at this step, set a special value for debug +#ifdef Rel14 + ,0, 0 +#endif + ); + + lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; + + if (rlc_status.bytes_in_buffer > 0) + { + LOG_D(MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d subframe %d\n", + module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,subframeP); + + UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY; + //Update BSR_bytes and position in lcid_reordered_array only if Group is defined + if (lcgid < MAX_NUM_LCGID) + { + num_lcid_with_data ++; + // sum lcid buffer which has same lcgid + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer; + + //Fill in the array + array_index = 0; + do + { + if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) + { + //Insert if priority is higher or equal (lower or equal in value) + for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) + { + lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1]; + + } + lcid_reordered_array[array_index] = lcid; + break; + + } + array_index ++; + } + while ((array_index < num_lcid_with_data) && (array_index < MAX_NUM_LCID)); + } } } @@ -3037,3 +3190,164 @@ int get_db_dl_PathlossChange(uint8_t dl_PathlossChange) break; } } + + +SLSS_t *ue_get_slss(module_id_t Mod_id,int CC_id,frame_t frame_tx,sub_frame_t subframe_tx) { + + return((SLSS_t*)NULL); +} + +SLDCH_t *ue_get_sldch(module_id_t Mod_id,int CC_id,frame_t frame_tx,sub_frame_t subframe_tx) { + + //UE_MAC_INST *ue = &UE_mac_inst[Mod_id]; + SLDCH_t *sldch = &UE_mac_inst[Mod_id].sldch; + // Panos: Ask TTN if we should be calling mac_rrc_data_req_ue() instead of mac_rrc_data_req() now! + /*sldch->payload_length = mac_rrc_data_req(Mod_id, + CC_id, + frame_tx, + SL_DISCOVERY, + 1, + (char*)(sldch->payload), //&UE_mac_inst[Mod_id].SL_Discovery[0].Tx_buffer.Payload[0], + 0, + 0, //eNB_indexP + 0);*/ + + sldch->payload_length = mac_rrc_data_req_ue(Mod_id, + CC_id, + frame_tx, + SL_DISCOVERY, + 1, + (uint8_t*)(sldch->payload), //&UE_mac_inst[Mod_id].SL_Discovery[0].Tx_buffer.Payload[0], + 0, //eNB_indexP + 0); + + + + if (sldch->payload_length >0 ) { + LOG_I(MAC,"Got %d bytes from RRC for SLDCH @ %p\n",sldch->payload_length,sldch); + return (sldch); + } + else + + return((SLDCH_t*)NULL); +} + + +SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) { + + mac_rlc_status_resp_t rlc_status; //, rlc_status_data; + uint32_t absSF = (frameP*10)+subframeP; + UE_MAC_INST *ue = &UE_mac_inst[module_idP]; + int rvtab[4] = {0,2,3,1}; + int sdu_length; + //uint8_t sl_lcids[2] = {3, 10}; //list of lcids for SL - hardcoded + int i = 0; + + // Note: this is hard-coded for now for the default SL configuration (4 SF PSCCH, 36 SF PSSCH) + SLSCH_t *slsch = &UE_mac_inst[module_idP].slsch; + + LOG_D(MAC,"Checking SLSCH for absSF %d\n",absSF); + if ((absSF%40) == 0) { // fill PSCCH data later in first subframe of SL period + ue->sltx_active = 0; + + for (i = 0; i < MAX_NUM_LCID; i++){ + if (ue->SL_LCID[i] > 0) { + for (int j = 0; j < ue->numCommFlows; j++){ + if ((ue->sourceL2Id > 0) && (ue->destinationList[j] >0) ){ + rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, + ue->SL_LCID[i], 0xFFFF, ue->sourceL2Id, ue->destinationList[j]); + if (rlc_status.bytes_in_buffer > 2){ + LOG_I(MAC,"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer\n",frameP,subframeP,rlc_status.bytes_in_buffer); + // Fill in group id for off-network communications + ue->sltx_active = 1; + //store LCID, destinationL2Id + ue->slsch_lcid = ue->SL_LCID[i]; + ue->destinationL2Id = ue->destinationList[j]; + break; + } + } + } + } + if ( ue->sltx_active == 1) break; + } + } // we're not in the SCCH period + else if (((absSF & 3) == 0 ) && + (ue->sltx_active == 1)) { // every 4th subframe, check for new data from RLC + // 10 PRBs, mcs 19 + int TBS = 4584/8; + int req; + + + if (TBS <= rlc_status.bytes_in_buffer) req = TBS; + else req = rlc_status.bytes_in_buffer; + + if (req>0) { + sdu_length = mac_rlc_data_req(module_idP, + 0x1234, + 0, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + ue->slsch_lcid, + req, + (char*)(ue->slsch_pdu.payload + sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG)) +#ifdef Rel14 + ,ue->sourceL2Id, + ue->destinationL2Id +#endif + ); + + // Notes: 1. hard-coded to 24-bit destination format for now + if (sdu_length > 0) { + + LOG_I(MAC,"SFN.SF %d.%d : got %d bytes from Sidelink buffer (%d requested)\n",frameP,subframeP,sdu_length,req); + LOG_I(MAC,"sourceL2Id: 0x%08x \n",ue->sourceL2Id); + LOG_I(MAC,"groupL2Id/destinationL2Id: 0x%08x \n",ue->destinationL2Id); + + slsch->payload = (unsigned char*)ue->slsch_pdu.payload; + if (sdu_length < 128) { + slsch->payload++; + SLSCH_SUBHEADER_24_Bit_DST_SHORT *shorth= (SLSCH_SUBHEADER_24_Bit_DST_SHORT *)slsch->payload; + shorth->F = 0; + shorth->L = sdu_length; + shorth->E = 0; + shorth->LCID = ue->slsch_lcid; + shorth->SRC07 = (ue->sourceL2Id>>16) & 0x000000ff; + shorth->SRC815 = (ue->sourceL2Id>>8) & 0x000000ff; + shorth->SRC1623 = ue->sourceL2Id & 0x000000ff; + shorth->DST07 = (ue->destinationL2Id >>16) & 0x000000ff; + shorth->DST815 = (ue->destinationL2Id >>8) & 0x000000ff; + shorth->DST1623 = ue->destinationL2Id & 0x000000ff; + shorth->V = 0x1; + } + else { + SLSCH_SUBHEADER_24_Bit_DST_LONG *longh= (SLSCH_SUBHEADER_24_Bit_DST_LONG *)slsch->payload; + longh->F = 1; + longh->L_LSB = sdu_length&0xff; + longh->L_MSB = (sdu_length>>8)&0x7f; + longh->E = 0; + longh->LCID = ue->slsch_lcid; + longh->SRC07 = (ue->sourceL2Id >>16) & 0x000000ff; + longh->SRC815 = (ue->sourceL2Id>>8) & 0x000000ff; + longh->SRC1623 = ue->sourceL2Id & 0x000000ff; + longh->DST07 = (ue->destinationL2Id >>16) & 0x000000ff; + longh->DST815 = (ue->destinationL2Id>>8) & 0x000000ff; + longh->DST1623 = ue->destinationL2Id & 0x000000ff; + longh->V = 0x1; + } + slsch->rvidx = 0; + slsch->payload_length = TBS; + // fill in SLSCH configuration + return(&ue->slsch); + } + else ue->sltx_active = 0; + } + + } else if ((absSF%40)>3 && ue->sltx_active == 1) { // handle retransmission of SDU + LOG_I(MAC,"SFN.SF %d.%d : retransmission\n",frameP,subframeP); + slsch->rvidx = rvtab[absSF&3]; + return(&ue->slsch); + } + + return(NULL); +} diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 7023defc439d8b61893bc5c9410784907e650381..c77f33e308d4d7b03b3b19df4ea6177ccd170909 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -36,8 +36,8 @@ #include "pdcp_util.h" #include "pdcp_sequence_manager.h" #include "LAYER2/RLC/rlc.h" -#include "LAYER2/MAC/extern.h" -#include "RRC/LITE/proto.h" +#include "LAYER2/MAC/mac_extern.h" +#include "RRC/LTE/rrc_proto.h" #include "pdcp_primitives.h" #include "OCG.h" #include "OCG_extern.h" @@ -83,6 +83,10 @@ boolean_t pdcp_data_req( const sdu_size_t sdu_buffer_sizeP, unsigned char *const sdu_buffer_pP, const pdcp_transmission_mode_t modeP +#ifdef Rel14 + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif ) //----------------------------------------------------------------------------- { @@ -99,6 +103,8 @@ boolean_t pdcp_data_req( hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; + uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 : 0; + uint16_t pdcp_uid=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN); CHECK_CTXT_ARGS(ctxt_pP); @@ -144,7 +150,7 @@ boolean_t pdcp_data_req( ctxt_pP->configured=TRUE; } - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -163,7 +169,11 @@ boolean_t pdcp_data_req( (unsigned char*)&pdcp_pdu_p->data[0], sdu_buffer_sizeP); #endif - rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p); + rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p +#ifdef Rel14 + ,NULL, NULL +#endif + ); } else { rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES; LOG_W(PDCP,PROTOCOL_CTXT_FMT" PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", @@ -215,7 +225,7 @@ boolean_t pdcp_data_req( LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -233,8 +243,9 @@ boolean_t pdcp_data_req( if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char*)pdcp_pdu_p->data, &pdu_header) == FALSE) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); + + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -256,7 +267,7 @@ boolean_t pdcp_data_req( free_mem_block(pdcp_pdu_p, __func__); - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -284,7 +295,7 @@ boolean_t pdcp_data_req( (((pdcp_p->cipheringAlgorithm) != 0) || ((pdcp_p->integrityProtAlgorithm) != 0))) { - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].apply_security); } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].apply_security); @@ -348,7 +359,12 @@ boolean_t pdcp_data_req( LOG_F(PDCP,"\n"); #endif - rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p); + rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p +#ifdef Rel14 + ,sourceL2Id + ,destinationL2Id +#endif + ); } @@ -379,7 +395,7 @@ boolean_t pdcp_data_req( break; } - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -389,16 +405,23 @@ boolean_t pdcp_data_req( * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK * so we return TRUE afterwards */ - /* - if (rb_id>=DTCH) { - if (ctxt_pP->enb_flag == 1) { - Pdcp_stats_tx[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH]++; - Pdcp_stats_tx_bytes[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH] += sdu_buffer_size; - } else { - Pdcp_stats_tx[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH]++; - Pdcp_stats_tx_bytes[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH] += sdu_buffer_size; - } - }*/ + + for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ + if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) + break; + } + + //LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn); + Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; + Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; + Pdcp_stats_tx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=current_sn; + + Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); return ret; @@ -428,6 +451,9 @@ pdcp_data_ind( boolean_t packet_forwarded = FALSE; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; + uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 :0; + uint16_t pdcp_uid=0; + uint8_t oo_flag=0; #if defined(LINK_ENB_PDCP_TO_GTPV1U) MessageDef *message_p = NULL; uint8_t *gtpu_buffer_p = NULL; @@ -577,6 +603,7 @@ pdcp_data_ind( else LOG_D(PDCP, "Passing piggybacked SDU to RRC ...\n");*/ } else { + oo_flag=1; LOG_W(PDCP, PROTOCOL_PDCP_CTXT_FMT"Incoming PDU has an unexpected sequence number (%d), RX window synchronisation have probably been lost!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), @@ -630,11 +657,12 @@ pdcp_data_ind( PROTOCOL_PDCP_CTXT_FMT" DATA-IND len %u", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len); - rrc_data_ind(ctxt_pP, + rrc_data_ind(ctxt_pP, rb_id, sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len, (uint8_t*)&sdu_buffer_pP->data[pdcp_header_len]); - free_mem_block(sdu_buffer_pP, __func__); + free_mem_block(sdu_buffer_pP, __func__); + // free_mem_block(new_sdu, __func__); if (ctxt_pP->enb_flag) { @@ -729,9 +757,9 @@ pdcp_data_ind( GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); - packet_forwarded = TRUE; + packet_forwarded = TRUE; } - + #else packet_forwarded = FALSE; #endif @@ -765,6 +793,8 @@ pdcp_data_ind( } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); } + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; + #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU static uint32_t pdcp_inst = 0; ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = pdcp_inst++; @@ -776,28 +806,44 @@ pdcp_data_ind( sdu_buffer_sizeP - payload_offset); list_add_tail_eurecom (new_sdu_p, sdu_list_p); - /* Print octets of incoming data in hexadecimal form */ - LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", - sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), - sdu_buffer_sizeP - payload_offset); - //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - - /* - * Update PDCP statistics - * XXX Following two actions are identical, is there a merge error? - */ - - /*if (ctxt_pP->enb_flag == 1) { - Pdcp_stats_rx[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH]++; - Pdcp_stats_rx_bytes[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH] += sdu_buffer_sizeP; - } else { - Pdcp_stats_rx[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH]++; - Pdcp_stats_rx_bytes[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH] += sdu_buffer_sizeP; - }*/ + + } } + /* Print octets of incoming data in hexadecimal form */ + LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", + sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), + sdu_buffer_sizeP - payload_offset); + //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + + /* + * Update PDCP statistics + * XXX Following two actions are identical, is there a merge error? + */ + + for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ + if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ){ + break; + } + } + + Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + + Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; + + if (oo_flag == 1 ) + Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + + Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; + + #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) else { AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n", @@ -818,6 +864,55 @@ pdcp_data_ind( return TRUE; } +void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ + + uint8_t pdcp_uid = 0; + uint8_t rb_id = 0; + + // these stats are measured for both eNB and UE on per seond basis + for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++){ + for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ + //printf("frame %d and subframe %d \n", pdcp_enb[ctxt_pP->module_id].frame, pdcp_enb[ctxt_pP->module_id].subframe); + // tx stats + if (Pdcp_stats_tx_window_ms[ctxt_pP->module_id][pdcp_uid] > 0 && + pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_tx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0){ + // unit: bit/s + Pdcp_stats_tx_throughput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; + Pdcp_stats_tx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_tx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + if (Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ + Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=(Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); + }else { + Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + // reset the tmp vars + Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + + } + if (Pdcp_stats_rx_window_ms[ctxt_pP->module_id][pdcp_uid] > 0 && + pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_rx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0){ + // rx stats + Pdcp_stats_rx_goodput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; + Pdcp_stats_rx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_rx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + + if(Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ + Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]= (Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); + } else { + Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + + // reset the tmp vars + Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + } + + } +} //----------------------------------------------------------------------------- void pdcp_run ( @@ -825,6 +920,7 @@ pdcp_run ( ) //----------------------------------------------------------------------------- { + #if defined(ENABLE_ITTI) MessageDef *msg_p; const char *msg_name; @@ -833,12 +929,19 @@ pdcp_run ( protocol_ctxt_t ctxt; #endif + + if (ctxt_pP->enb_flag) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run); } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run); } + pdcp_enb[ctxt_pP->module_id].sfn++; // range: 0 to 18,446,744,073,709,551,615 + pdcp_enb[ctxt_pP->module_id].frame=ctxt_pP->frame; // 1023 + pdcp_enb[ctxt_pP->module_id].subframe= ctxt_pP->subframe; + pdcp_update_stats(ctxt_pP); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); #if defined(ENABLE_ITTI) @@ -878,7 +981,11 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).confirmp, RRC_DCCH_DATA_REQ (msg_p).sdu_size, RRC_DCCH_DATA_REQ (msg_p).sdu_p, - RRC_DCCH_DATA_REQ (msg_p).mode); + RRC_DCCH_DATA_REQ (msg_p).mode +#ifdef Rel14 + , NULL, NULL +#endif + ); if (result != TRUE) LOG_E(PDCP, "PDCP data request failed!\n"); @@ -971,6 +1078,28 @@ pdcp_run ( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT); } +void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){ + int i, ue_flag=1; //, ret=-1; to be decied later + for (i=0; i < MAX_MOBILES_PER_ENB; i++){ + if (pdcp_enb[ctxt_pP->module_id].rnti[i] == ctxt_pP->rnti) { + ue_flag=-1; + break; + } + } + if (ue_flag == 1 ){ + for (i=0; i < MAX_MOBILES_PER_ENB ; i++){ + if (pdcp_enb[ctxt_pP->module_id].rnti[i] == 0 ){ + pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti; + pdcp_enb[ctxt_pP->module_id].uid[i]=i; + pdcp_enb[ctxt_pP->module_id].num_ues++; + printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti); + // ret=1; + break; + } + } + } + //return ret; +} //----------------------------------------------------------------------------- boolean_t @@ -983,17 +1112,17 @@ pdcp_remove_UE( DRB_Identity_t drb_id = 0; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; + int i; + // check and remove SRBs first - // check and remove SRBs first - - for(int i = 0;i<NUMBER_OF_UE_MAX;i++){ + for(int i = 0;i<MAX_MOBILES_PER_ENB;i++){ if(pdcp_eNB_UE_instance_to_rnti[i] == ctxt_pP->rnti){ pdcp_eNB_UE_instance_to_rnti[i] = NOT_A_RNTI; break; } } - for (srb_id=0; srb_id<2; srb_id++) { + for (srb_id=1; srb_id<3; srb_id++) { key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES); h_rc = hashtable_remove(pdcp_coll_p, key); } @@ -1006,6 +1135,19 @@ pdcp_remove_UE( (void)h_rc; /* remove gcc warning "set but not used" */ + // remove ue for pdcp enb inst + for (i=0; i < MAX_MOBILES_PER_ENB; i++) { + if (pdcp_enb[ctxt_pP->module_id].rnti[i] == ctxt_pP->rnti ) { + LOG_I(PDCP, "remove uid is %d/%d %x\n", i, + pdcp_enb[ctxt_pP->module_id].uid[i], + pdcp_enb[ctxt_pP->module_id].rnti[i]); + pdcp_enb[ctxt_pP->module_id].uid[i]=0; + pdcp_enb[ctxt_pP->module_id].rnti[i]=0; + pdcp_enb[ctxt_pP->module_id].num_ues--; + break; + } + } + return 1; } @@ -1021,7 +1163,7 @@ rrc_pdcp_config_asn1_req ( uint8_t *const kRRCenc_pP, uint8_t *const kRRCint_pP, uint8_t *const kUPenc_pP -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,PMCH_InfoList_r9_t* const pmch_InfoList_r9_pP #endif ,rb_id_t *const defaultDRB @@ -1048,7 +1190,7 @@ rrc_pdcp_config_asn1_req ( hashtable_rc_t h_rc; hash_key_t key_defaultDRB = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_defaultDRB_rc; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) int i,j; MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; @@ -1090,7 +1232,7 @@ rrc_pdcp_config_asn1_req ( return TRUE; } else { - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); } @@ -1346,7 +1488,7 @@ rrc_pdcp_config_asn1_req ( } } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (pmch_InfoList_r9_pP != NULL) { for (i=0; i<pmch_InfoList_r9_pP->list.count; i++) { @@ -1400,7 +1542,6 @@ rrc_pdcp_config_asn1_req ( return 0; } - //----------------------------------------------------------------------------- boolean_t pdcp_config_req_asn1 ( @@ -1421,25 +1562,27 @@ pdcp_config_req_asn1 ( uint8_t *const kUPenc_pP) //----------------------------------------------------------------------------- { - + switch (actionP) { case CONFIG_ACTION_ADD: DevAssert(pdcp_pP != NULL); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { pdcp_pP->is_ue = FALSE; + pdcp_add_UE(ctxt_pP); + //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; // pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; if( srb_flagP == SRB_FLAG_NO ) { - for(int i = 0;i<NUMBER_OF_UE_MAX;i++){ + for(int i = 0;i<MAX_MOBILES_PER_ENB;i++){ if(pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] == NOT_A_RNTI){ break; } - pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX; + pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; } pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; - pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX; + pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; } - //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX; + //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; } else { pdcp_pP->is_ue = TRUE; pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; @@ -1536,6 +1679,10 @@ pdcp_config_req_asn1 ( lc_idP, rb_idP); + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { + // pdcp_remove_UE(ctxt_pP); + } + /* Security keys */ if (pdcp_pP->kUPenc != NULL) { free(pdcp_pP->kUPenc); @@ -1551,7 +1698,7 @@ pdcp_config_req_asn1 ( memset(pdcp_pP, 0, sizeof(pdcp_t)); break; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case CONFIG_ACTION_MBMS_ADD: case CONFIG_ACTION_MBMS_MODIFY: @@ -1667,6 +1814,7 @@ rrc_pdcp_config_req ( if (ctxt_pP->enb_flag == ENB_FLAG_NO) { pdcp_p->is_ue = TRUE; + pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } else { pdcp_p->is_ue = FALSE; } @@ -1685,9 +1833,9 @@ rrc_pdcp_config_req ( } pdcp_p->first_missing_pdu = -1; - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d (already added) configured\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), - rb_idP); + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d (already added) configured\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), + rb_idP); break; case CONFIG_ACTION_MODIFY: @@ -1744,10 +1892,10 @@ rrc_pdcp_config_req ( if (ctxt_pP->enb_flag == ENB_FLAG_NO) { pdcp_p->is_ue = TRUE; - + pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } else { pdcp_p->is_ue = FALSE; -} + } pdcp_p->next_pdcp_tx_sn = 0; pdcp_p->next_pdcp_rx_sn = 0; @@ -1787,13 +1935,14 @@ rrc_pdcp_config_req ( //----------------------------------------------------------------------------- -// TODO PDCP module initialization code might be removed + int pdcp_module_init ( void ) //----------------------------------------------------------------------------- { + #ifdef PDCP_USE_RT_FIFO int ret; @@ -1869,7 +2018,8 @@ void pdcp_layer_init(void) { module_id_t instance; -#if defined(Rel10) || defined(Rel14) + int i,j; +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) mbms_session_id_t session_id; mbms_service_id_t service_id; #endif @@ -1880,8 +2030,8 @@ void pdcp_layer_init(void) pdcp_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, pdcp_free); AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed"); - for (instance = 0; instance < NUMBER_OF_UE_MAX; instance++) { -#if defined(Rel10) || defined(Rel14) + for (instance = 0; instance < MAX_MOBILES_PER_ENB; instance++) { +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (service_id = 0; service_id < maxServiceCount; service_id++) { for (session_id = 0; session_id < maxSessionPerPMCH; session_id++) { @@ -1895,7 +2045,7 @@ void pdcp_layer_init(void) for (instance = 0; instance < NUMBER_OF_eNB_MAX; instance++) { -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (service_id = 0; service_id < maxServiceCount; service_id++) { for (session_id = 0; session_id < maxSessionPerPMCH; session_id++) { @@ -1912,15 +2062,42 @@ void pdcp_layer_init(void) pdcp_output_header_bytes_to_write=0; pdcp_input_sdu_remaining_size_to_read=0; + memset(pdcp_enb, 0, sizeof(pdcp_enb_t)); + + + memset(Pdcp_stats_tx_window_ms, 0, sizeof(Pdcp_stats_tx_window_ms)); + memset(Pdcp_stats_rx_window_ms, 0, sizeof(Pdcp_stats_rx_window_ms)); + for (i =0; i< MAX_NUM_CCs ; i ++){ + for (j=0; j< MAX_MOBILES_PER_ENB;j++){ + Pdcp_stats_tx_window_ms[i][j]=100; + Pdcp_stats_rx_window_ms[i][j]=100; + } + } + memset(Pdcp_stats_tx, 0, sizeof(Pdcp_stats_tx)); + memset(Pdcp_stats_tx_w, 0, sizeof(Pdcp_stats_tx_w)); + memset(Pdcp_stats_tx_tmp_w, 0, sizeof(Pdcp_stats_tx_tmp_w)); memset(Pdcp_stats_tx_bytes, 0, sizeof(Pdcp_stats_tx_bytes)); - memset(Pdcp_stats_tx_bytes_last, 0, sizeof(Pdcp_stats_tx_bytes_last)); - memset(Pdcp_stats_tx_rate, 0, sizeof(Pdcp_stats_tx_rate)); + memset(Pdcp_stats_tx_bytes_w, 0, sizeof(Pdcp_stats_tx_bytes_w)); + memset(Pdcp_stats_tx_bytes_tmp_w, 0, sizeof(Pdcp_stats_tx_bytes_tmp_w)); + memset(Pdcp_stats_tx_sn, 0, sizeof(Pdcp_stats_tx_sn)); + memset(Pdcp_stats_tx_throughput_w, 0, sizeof(Pdcp_stats_tx_throughput_w)); + memset(Pdcp_stats_tx_aiat, 0, sizeof(Pdcp_stats_tx_aiat)); + memset(Pdcp_stats_tx_iat, 0, sizeof(Pdcp_stats_tx_iat)); + memset(Pdcp_stats_rx, 0, sizeof(Pdcp_stats_rx)); + memset(Pdcp_stats_rx_w, 0, sizeof(Pdcp_stats_rx_w)); + memset(Pdcp_stats_rx_tmp_w, 0, sizeof(Pdcp_stats_rx_tmp_w)); memset(Pdcp_stats_rx_bytes, 0, sizeof(Pdcp_stats_rx_bytes)); - memset(Pdcp_stats_rx_bytes_last, 0, sizeof(Pdcp_stats_rx_bytes_last)); - memset(Pdcp_stats_rx_rate, 0, sizeof(Pdcp_stats_rx_rate)); + memset(Pdcp_stats_rx_bytes_w, 0, sizeof(Pdcp_stats_rx_bytes_w)); + memset(Pdcp_stats_rx_bytes_tmp_w, 0, sizeof(Pdcp_stats_rx_bytes_tmp_w)); + memset(Pdcp_stats_rx_sn, 0, sizeof(Pdcp_stats_rx_sn)); + memset(Pdcp_stats_rx_goodput_w, 0, sizeof(Pdcp_stats_rx_goodput_w)); + memset(Pdcp_stats_rx_aiat, 0, sizeof(Pdcp_stats_rx_aiat)); + memset(Pdcp_stats_rx_iat, 0, sizeof(Pdcp_stats_rx_iat)); + memset(Pdcp_stats_rx_outoforder, 0, sizeof(Pdcp_stats_rx_outoforder)); + } //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 30a45acc72fc9d7183b156a4bd85f5e8112bf251..6fd0621644423cd7d054f133339bfd1398bb1175 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -67,14 +67,14 @@ #include "UTIL/LISTS/list.h" #endif //NON_ACCESS_STRATUM //----------------------------------------------------------------------------- -#include "RRC/LITE/defs.h" +#include "RRC/LTE/rrc_defs.h" #include "COMMON/platform_constants.h" #include "COMMON/platform_types.h" #include "DRB-ToAddMod.h" #include "DRB-ToAddModList.h" #include "SRB-ToAddMod.h" #include "SRB-ToAddModList.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "MBMS-SessionInfoList-r9.h" #include "PMCH-InfoList-r9.h" #endif @@ -94,15 +94,54 @@ extern int pdcp_instance_cnt; int init_pdcp_thread(void); void cleanup_pdcp_thread(void); - -public_pdcp(unsigned int Pdcp_stats_tx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_tx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_tx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_tx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_window_ms[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]); +public_pdcp(uint32_t Pdcp_stats_tx_bytes[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_bytes_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_sn[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_throughput_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_iat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); + +public_pdcp(uint32_t Pdcp_stats_rx_window_ms[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]); +public_pdcp(uint32_t Pdcp_stats_rx[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_bytes[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_bytes_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_sn[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_goodput_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_iat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_outoforder[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]); + +public_pdcp(void pdcp_update_perioidical_stats(const protocol_ctxt_t* const ctxt_pP)); + + +/*Packet Probing for agent PDCP*/ +//public_pdcp(uint64_t *pdcp_packet_counter); +//public_pdcp(uint64_t *pdcp_size_packet); +typedef struct pdcp_enb_s { + // used for eNB stats generation + uint16_t uid[MAX_MOBILES_PER_ENB]; + rnti_t rnti[MAX_MOBILES_PER_ENB]; + uint16_t num_ues; + + uint64_t sfn; + frame_t frame; + sub_frame_t subframe; + +} pdcp_enb_t; + +public_pdcp(pdcp_enb_t pdcp_enb[MAX_NUM_CCs]); typedef struct pdcp_stats_s { time_stats_t pdcp_run; @@ -125,7 +164,7 @@ typedef struct pdcp_s { boolean_t is_ue; boolean_t is_srb; - /* Configured security algorithms */ + /* Configured security algorithms */ uint8_t cipheringAlgorithm; uint8_t integrityProtAlgorithm; @@ -184,7 +223,7 @@ typedef struct pdcp_s { } pdcp_t; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) typedef struct pdcp_mbms_s { boolean_t instanciated_instance; rb_id_t rb_id; @@ -220,7 +259,12 @@ public_pdcp(boolean_t pdcp_data_req( const confirm_t confirmP, \ const sdu_size_t sdu_buffer_size, unsigned char* const sdu_buffer, - const pdcp_transmission_mode_t mode)); + const pdcp_transmission_mode_t mode +#ifdef Rel14 + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + )); /*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) * \brief This functions handles data transfer indications coming from RLC @@ -284,7 +328,7 @@ public_pdcp( uint8_t *const kRRCenc, uint8_t *const kRRCint, uint8_t *const kUPenc -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif ,rb_id_t *const defaultDRB @@ -327,9 +371,15 @@ public_pdcp(boolean_t pdcp_config_req_asn1 ( uint8_t *const kRRCint, uint8_t *const kUPenc)); - +/*! \fn void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP) +* \brief Function (for RRC) to add a new UE in PDCP module +* \param[in] ctxt_pP Running context. +* \return A status about the processing, OK or error code. +*/ +public_pdcp(void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP)); + /*! \fn boolean_t pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP) -* \brief Function for RRC to configure a Radio Bearer clear all PDCP resources for a particular UE +* \brief Function for RRC to remove UE from PDCP module hashtable * \param[in] ctxt_pP Running context. * \return A status about the processing, OK or error code. */ @@ -387,6 +437,10 @@ typedef struct pdcp_data_req_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t traffic_type; +#ifdef Rel14 + uint32_t sourceL2Id; + uint32_t destinationL2Id; +#endif } pdcp_data_req_header_t; typedef struct pdcp_data_ind_header_s { @@ -394,6 +448,10 @@ typedef struct pdcp_data_ind_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t dummy_traffic_type; +#ifdef Rel14 + uint32_t sourceL2Id; + uint32_t destinationL2Id; +#endif } pdcp_data_ind_header_t; struct pdcp_netlink_element_s { @@ -403,6 +461,43 @@ struct pdcp_netlink_element_s { uint8_t *data; }; +//TTN for D2D (PC5S) +#ifdef Rel14 +#define PDCP_SOCKET_PORT_NO 9999 //temporary value +#define PC5_SIGNALLING_PAYLOAD_SIZE 100 //should be updated with a correct value +int pdcp_pc5_sockfd; +struct sockaddr_in prose_ctrl_addr; +struct sockaddr_in prose_pdcp_addr; +struct sockaddr_in pdcp_sin; +void pdcp_pc5_socket_init(void); + +typedef struct { + rb_id_t rb_id; + sdu_size_t data_size; + signed int inst; + ip_traffic_type_t traffic_type; + uint32_t sourceL2Id; + uint32_t destinationL2Id; +} __attribute__((__packed__)) pc5s_header_t; + +//new PC5S-message +typedef struct { + unsigned char bytes[PC5_SIGNALLING_PAYLOAD_SIZE]; +} __attribute__((__packed__)) PC5SignallingMessage ; + +//example of PC5-S messages +typedef struct { + pc5s_header_t pc5s_header; + union { + uint8_t status; + PC5SignallingMessage pc5_signalling_message; + } pc5sPrimitive; +} __attribute__((__packed__)) sidelink_pc5s_element; + + +#endif + + #if 0 /* * Missing PDU information struct, a copy of this will be enqueued @@ -437,19 +532,19 @@ typedef struct pdcp_missing_pdu_info_t { protected_pdcp(signed int pdcp_2_nas_irq;) -public_pdcp(pdcp_stats_t UE_pdcp_stats[NUMBER_OF_UE_MAX];) +public_pdcp(pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB];) public_pdcp(pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX];) -//protected_pdcp(pdcp_t pdcp_array_srb_ue[NUMBER_OF_UE_MAX][2];) -//protected_pdcp(pdcp_t pdcp_array_drb_ue[NUMBER_OF_UE_MAX][maxDRB];) -//public_pdcp(pdcp_t pdcp_array_srb_eNB[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][2];) -//protected_pdcp(pdcp_t pdcp_array_drb_eNB[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][maxDRB];) +//protected_pdcp(pdcp_t pdcp_array_srb_ue[MAX_MOBILES_PER_ENB][2];) +//protected_pdcp(pdcp_t pdcp_array_drb_ue[MAX_MOBILES_PER_ENB][maxDRB];) +//public_pdcp(pdcp_t pdcp_array_srb_eNB[NUMBER_OF_eNB_MAX][MAX_MOBILES_PER_ENB][2];) +//protected_pdcp(pdcp_t pdcp_array_drb_eNB[NUMBER_OF_eNB_MAX][MAX_MOBILES_PER_ENB][maxDRB];) // for UE code conly -protected_pdcp(rnti_t pdcp_UE_UE_module_id_to_rnti[NUMBER_OF_UE_MAX];) -protected_pdcp(rnti_t pdcp_eNB_UE_instance_to_rnti[NUMBER_OF_UE_MAX];) // for noS1 mode +protected_pdcp(rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];) +protected_pdcp(rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB];) // for noS1 mode protected_pdcp(unsigned int pdcp_eNB_UE_instance_to_rnti_index;) -#if defined(Rel10) || defined(Rel14) -public_pdcp(pdcp_mbms_t pdcp_mbms_array_ue[NUMBER_OF_UE_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +public_pdcp(pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h public_pdcp(pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h #endif protected_pdcp(sdu_size_t pdcp_output_sdu_bytes_to_write;) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index eb060e85352eab6dcd05cce3bed337bcee825f19..be3d4fd4344bdfe32c17871a3e4e5fb9fb04ae27 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -46,10 +46,10 @@ extern int otg_enabled; #define rtf_put write #define rtf_get read -#include "../MAC/extern.h" +#include "../MAC/mac_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "NETWORK_DRIVER/LITE/constant.h" -#include "SIMULATION/ETH_TRANSPORT/extern.h" +//#include "SIMULATION/ETH_TRANSPORT/extern.h" #include "UTIL/OCG/OCG.h" #include "UTIL/OCG/OCG_extern.h" #include "UTIL/LOG/log.h" @@ -58,6 +58,7 @@ extern int otg_enabled; #include "UTIL/LOG/vcd_signal_dumper.h" #include "platform_constants.h" #include "msc.h" +#include "pdcp.h" #include "assertions.h" @@ -72,7 +73,11 @@ extern struct nlmsghdr *nas_nlh_tx; extern struct nlmsghdr *nas_nlh_rx; extern struct iovec nas_iov_tx; extern struct iovec nas_iov_rx; +#ifdef UE_NAS_USE_TUN +extern int nas_sock_fd[MAX_MOBILES_PER_ENB]; +#else extern int nas_sock_fd; +#endif extern struct msghdr nas_msg_tx; extern struct msghdr nas_msg_rx; @@ -108,129 +113,163 @@ pdcp_data_req_header_t pdcp_read_header_g; //----------------------------------------------------------------------------- int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) { - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -//#if defined(PDCP_USE_NETLINK) && defined(LINUX) - int ret = 0; -//#endif + //#if defined(PDCP_USE_NETLINK) && defined(LINUX) + int ret = 0; + //#endif #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU #define THREAD_NAME_LEN 16 - static char threadname[THREAD_NAME_LEN]; - ret = pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN); - if (ret != 0) - { - perror("pthread_getname_np : "); - exit_fun("Error getting thread name"); - } + static char threadname[THREAD_NAME_LEN]; + ret = pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN); + if (ret != 0) + { + perror("pthread_getname_np : "); + exit_fun("Error getting thread name"); + } #undef THREAD_NAME_LEN #endif #ifdef PDCP_SDU_FLUSH_LOCK - ret = pthread_mutex_trylock(&mtex); - if (ret == EBUSY) { + ret = pthread_mutex_trylock(&mtex); + if (ret == EBUSY) { #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU - LOG_W(PDCP, "[%s] at SFN/SF=%d/%d wait for PDCP FIFO to be unlocked\n", - threadname, ctxt_pP->frame, ctxt_pP->subframe); + LOG_W(PDCP, "[%s] at SFN/SF=%d/%d wait for PDCP FIFO to be unlocked\n", + threadname, ctxt_pP->frame, ctxt_pP->subframe); #endif - if (pthread_mutex_lock(&mtex)) { - exit_fun("PDCP_SDU_FLUSH_LOCK lock error!"); - } + if (pthread_mutex_lock(&mtex)) { + exit_fun("PDCP_SDU_FLUSH_LOCK lock error!"); + } #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU - LOG_I(PDCP, "[%s] at SFN/SF=%d/%d PDCP FIFO is unlocked\n", - threadname, ctxt_pP->frame, ctxt_pP->subframe); + LOG_I(PDCP, "[%s] at SFN/SF=%d/%d PDCP FIFO is unlocked\n", + threadname, ctxt_pP->frame, ctxt_pP->subframe); #endif - } else if (ret != 0) { - exit_fun("PDCP_SDU_FLUSH_LOCK trylock error!"); - } + } else if (ret != 0) { + exit_fun("PDCP_SDU_FLUSH_LOCK trylock error!"); + } #endif - mem_block_t *sdu_p = list_get_head (&pdcp_sdu_list); - int bytes_wrote = 0; - int pdcp_nb_sdu_sent = 0; - uint8_t cont = 1; + mem_block_t *sdu_p = list_get_head (&pdcp_sdu_list); + int bytes_wrote = 0; + int pdcp_nb_sdu_sent = 0; + uint8_t cont = 1; #if defined(LINK_ENB_PDCP_TO_GTPV1U) - //MessageDef *message_p = NULL; + //MessageDef *message_p = NULL; #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 1 ); - while (sdu_p && cont) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 1 ); + while (sdu_p && cont) { #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU - LOG_D(PDCP, "[%s] SFN/SF=%d/%d inst=%d size=%d\n", - threadname, ctxt_pP->frame, ctxt_pP->subframe, - ((pdcp_data_ind_header_t*) sdu_p->data)->inst, - ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); + LOG_D(PDCP, "[%s] SFN/SF=%d/%d inst=%d size=%d\n", + threadname, ctxt_pP->frame, ctxt_pP->subframe, + ((pdcp_data_ind_header_t*) sdu_p->data)->inst, + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); +#else + ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) - if (ctxt_pP->enb_flag) { - AssertFatal(0, "Now execution should not go here"); - LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); - gtpv1u_new_data_req( - ctxt_pP->module_id, //gtpv1u_data_t *gtpv1u_data_p, - ctxt_pP->rnti,//rb_id/maxDRB, TO DO UE ID - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4, - &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]), - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, - 0); - - list_remove_head (&pdcp_sdu_list); - free_mem_block (sdu_p, __func__); - cont = 1; - pdcp_nb_sdu_sent += 1; - sdu_p = list_get_head (&pdcp_sdu_list); - LOG_D(OTG,"After GTPV1U\n"); - continue; // loop again - } + if (ctxt_pP->enb_flag) { + AssertFatal(0, "Now execution should not go here"); + LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); + gtpv1u_new_data_req( + ctxt_pP->module_id, //gtpv1u_data_t *gtpv1u_data_p, + ctxt_pP->rnti,//rb_id/maxDRB, TO DO UE ID + ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4, + &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]), + ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, + 0); + + list_remove_head (&pdcp_sdu_list); + free_mem_block (sdu_p, __func__); + cont = 1; + pdcp_nb_sdu_sent += 1; + sdu_p = list_get_head (&pdcp_sdu_list); + LOG_D(OTG,"After GTPV1U\n"); + continue; // loop again + } #endif /* defined(ENABLE_USE_MME) */ #ifdef PDCP_DEBUG - LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", - ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); + LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", + ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, + ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); #endif //PDCP_DEBUG - cont = 0; + cont = 0; - if (!pdcp_output_sdu_bytes_to_write) { - if (!pdcp_output_header_bytes_to_write) { - pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t); +//TTN - for D2D (PC5S) +#ifdef Rel14 + sidelink_pc5s_element *sl_pc5s_msg_recv = NULL; + char send_buf[BUFSIZE]; + int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id; + + if (rb_id == 10) { //hardcoded for PC5-Signaling + //if ((rb_id == 28) | (rb_id == 29) | (rb_id == 30)) + +#ifdef PDCP_DEBUG + sl_pc5s_msg_recv = calloc(1, sizeof(sidelink_pc5s_element)); + memcpy((void*)sl_pc5s_msg_recv, (void*)(sdu_p->data+sizeof(pdcp_data_ind_header_t)), sizeof(sidelink_pc5s_element)); + LOG_D(PDCP,"Received PC5S message, header traffic_type: %d)\n", sl_pc5s_msg_recv->pc5s_header.traffic_type); + LOG_D(PDCP,"Received PC5S message, header rb_id: %d)\n", sl_pc5s_msg_recv->pc5s_header.rb_id); + LOG_D(PDCP,"Received PC5S message, header data_size: %d)\n", sl_pc5s_msg_recv->pc5s_header.data_size); + LOG_D(PDCP,"Received PC5S message, header inst: %d)\n", sl_pc5s_msg_recv->pc5s_header.inst); + LOG_D(PDCP,"Received PC5-S message, sourceL2Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pc5s_header.sourceL2Id); + LOG_D(PDCP,"Received PC5-S message, destinationL1Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pc5s_header.destinationL2Id); + free(sl_pc5s_msg_recv); +#endif + memset(send_buf, 0, BUFSIZE); + memcpy((void *)send_buf, (void*)(sdu_p->data+sizeof(pdcp_data_ind_header_t)), sizeof(sidelink_pc5s_element)); + + int prose_addr_len = sizeof(prose_pdcp_addr); + int n = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len); + if (n < 0) { + LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } } +#endif + + if (!pdcp_output_sdu_bytes_to_write) { + if (!pdcp_output_header_bytes_to_write) { + pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t); + } #ifdef PDCP_USE_RT_FIFO - bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, - &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), - pdcp_output_header_bytes_to_write); + bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, + &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), + pdcp_output_header_bytes_to_write); #else #ifdef PDCP_USE_NETLINK #ifdef LINUX - memcpy(NLMSG_DATA(nas_nlh_tx), &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), - pdcp_output_header_bytes_to_write); - nas_nlh_tx->nlmsg_len = pdcp_output_header_bytes_to_write; + memcpy(NLMSG_DATA(nas_nlh_tx), &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), + pdcp_output_header_bytes_to_write); + nas_nlh_tx->nlmsg_len = pdcp_output_header_bytes_to_write; #endif //LINUX #endif //PDCP_USE_NETLINK - bytes_wrote = pdcp_output_header_bytes_to_write; + bytes_wrote = pdcp_output_header_bytes_to_write; #endif //PDCP_USE_RT_FIFO #ifdef PDCP_DEBUG - LOG_D(PDCP, "Frame %d Sent %d Bytes of header to Nas_mesh\n", - ctxt_pP->frame, - bytes_wrote); + LOG_D(PDCP, "Frame %d Sent %d Bytes of header to Nas_mesh\n", + ctxt_pP->frame, + bytes_wrote); #endif //PDCP_DEBUG - if (bytes_wrote > 0) { - pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote; + if (bytes_wrote > 0) { + pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote; - if (!pdcp_output_header_bytes_to_write) { // continue with sdu - pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu_p->data)->data_size; - AssertFatal(pdcp_output_sdu_bytes_to_write >= 0, "invalid data_size!"); + if (!pdcp_output_header_bytes_to_write) { // continue with sdu + pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu_p->data)->data_size; + AssertFatal(pdcp_output_sdu_bytes_to_write >= 0, "invalid data_size!"); #ifdef PDCP_USE_RT_FIFO - bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); + bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); #else #ifdef PDCP_USE_NETLINK @@ -239,7 +278,11 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) nas_nlh_tx->nlmsg_len += pdcp_output_sdu_bytes_to_write; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_SIZE, pdcp_output_sdu_bytes_to_write); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER, 1 ); +#ifdef UE_NAS_USE_TUN + ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); +#else ret = sendmsg(nas_sock_fd,&nas_msg_tx,0); +#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER, 0 ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_ERR, ret ); @@ -270,288 +313,616 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) #endif // LINUX #endif //PDCP_USE_NETLINK - bytes_wrote= pdcp_output_sdu_bytes_to_write; + bytes_wrote= pdcp_output_sdu_bytes_to_write; #endif // PDCP_USE_RT_FIFO #ifdef PDCP_DEBUG - LOG_D(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to higher layers\n", - ctxt_pP->frame, - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, - bytes_wrote, - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); + LOG_D(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to higher layers\n", + ctxt_pP->frame, + ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, + bytes_wrote, + ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); #endif //PDCP_DEBUG - if (bytes_wrote > 0) { - pdcp_output_sdu_bytes_to_write -= bytes_wrote; - - if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU - // LOG_D(PDCP, "rb sent a sdu qos_sap %d\n", sapiP); - LOG_D(PDCP, - "[FRAME %05d][xxx][PDCP][MOD xx/xx][RB %u][--- PDCP_DATA_IND / %d Bytes --->][IP][INSTANCE %u][RB %u]\n", - ctxt_pP->frame, - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); - - list_remove_head (&pdcp_sdu_list); - free_mem_block (sdu_p, __func__); - cont = 1; - pdcp_nb_sdu_sent += 1; - sdu_p = list_get_head (&pdcp_sdu_list); + if (bytes_wrote > 0) { + pdcp_output_sdu_bytes_to_write -= bytes_wrote; + + if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU + // LOG_D(PDCP, "rb sent a sdu qos_sap %d\n", sapiP); + LOG_D(PDCP, + "[FRAME %05d][xxx][PDCP][MOD xx/xx][RB %u][--- PDCP_DATA_IND / %d Bytes --->][IP][INSTANCE %u][RB %u]\n", + ctxt_pP->frame, + ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, + ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, + ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, + ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); + + list_remove_head (&pdcp_sdu_list); + free_mem_block (sdu_p, __func__); + cont = 1; + pdcp_nb_sdu_sent += 1; + sdu_p = list_get_head (&pdcp_sdu_list); + } else { + LOG_D(PDCP, "1 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write); + AssertFatal(pdcp_output_sdu_bytes_to_write > 0, "pdcp_output_sdu_bytes_to_write cannot be negative!"); + } + } else { + LOG_W(PDCP, "2: RADIO->IP SEND SDU CONGESTION!\n"); + } } else { - LOG_D(PDCP, "1 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write); - AssertFatal(pdcp_output_sdu_bytes_to_write > 0, "pdcp_output_sdu_bytes_to_write cannot be negative!"); + LOG_W(PDCP, "3: RADIO->IP SEND SDU CONGESTION!\n"); } - } else { - LOG_W(PDCP, "2: RADIO->IP SEND SDU CONGESTION!\n"); - } - } else { - LOG_W(PDCP, "3: RADIO->IP SEND SDU CONGESTION!\n"); - } + } else { + LOG_D(PDCP, "4 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote); + } } else { - LOG_D(PDCP, "4 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote); - } - } else { - // continue writing sdu + // continue writing sdu #ifdef PDCP_USE_RT_FIFO - bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, - (uint8_t *) (&(sdu_p->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size - pdcp_output_sdu_bytes_to_write])), - pdcp_output_sdu_bytes_to_write); + bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, + (uint8_t *) (&(sdu_p->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size - pdcp_output_sdu_bytes_to_write])), + pdcp_output_sdu_bytes_to_write); #else // PDCP_USE_RT_FIFO - bytes_wrote = pdcp_output_sdu_bytes_to_write; + bytes_wrote = pdcp_output_sdu_bytes_to_write; #endif // PDCP_USE_RT_FIFO + LOG_D(PDCP, "THINH 2 bytes_wrote = %d\n", bytes_wrote); - if (bytes_wrote > 0) { - pdcp_output_sdu_bytes_to_write -= bytes_wrote; - - if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU - //PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n"); - list_remove_head (&pdcp_sdu_list); - free_mem_block (sdu_p, __func__); - cont = 1; - pdcp_nb_sdu_sent += 1; - sdu_p = list_get_head (&pdcp_sdu_list); - // LOG_D(PDCP, "rb sent a sdu from rab\n"); - } else { - LOG_D(PDCP, "5 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write); - } - } else { - LOG_D(PDCP, "6 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote); + if (bytes_wrote > 0) { + pdcp_output_sdu_bytes_to_write -= bytes_wrote; + + if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU + //PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n"); + list_remove_head (&pdcp_sdu_list); + free_mem_block (sdu_p, __func__); + cont = 1; + pdcp_nb_sdu_sent += 1; + sdu_p = list_get_head (&pdcp_sdu_list); + // LOG_D(PDCP, "rb sent a sdu from rab\n"); + } else { + LOG_D(PDCP, "5 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write); + } + } else { + LOG_D(PDCP, "6 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote); + } } - } - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 0 ); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 0 ); #ifdef PDCP_USE_RT_FIFO - if ((pdcp_nb_sdu_sent)) { - if ((pdcp_2_nas_irq > 0)) { + if ((pdcp_nb_sdu_sent)) { + if ((pdcp_2_nas_irq > 0)) { #ifdef PDCP_DEBUG - LOG_D(PDCP, "Frame %d : Trigger NAS RX interrupt\n", - ctxt_pP->frame); + LOG_D(PDCP, "Frame %d : Trigger NAS RX interrupt\n", + ctxt_pP->frame); #endif //PDCP_DEBUG - rt_pend_linux_srq (pdcp_2_nas_irq); + rt_pend_linux_srq (pdcp_2_nas_irq); - } else { - LOG_E(PDCP, "Frame %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n", - ctxt_pP->frame, - pdcp_2_nas_irq); - } - } + } else { + LOG_E(PDCP, "Frame %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n", + ctxt_pP->frame, + pdcp_2_nas_irq); + } + } #endif //PDCP_USE_RT_FIFO #ifdef PDCP_SDU_FLUSH_LOCK - if (pthread_mutex_unlock(&mtex)) exit_fun("PDCP_SDU_FLUSH_LOCK unlock error!"); + if (pthread_mutex_unlock(&mtex)) exit_fun("PDCP_SDU_FLUSH_LOCK unlock error!"); #endif - return pdcp_nb_sdu_sent; + return pdcp_nb_sdu_sent; } //----------------------------------------------------------------------------- int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) { -#ifdef PDCP_USE_NETLINK - protocol_ctxt_t ctxt_cpy = *ctxt_pP; - protocol_ctxt_t ctxt; - hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; - hashtable_rc_t h_rc; - struct pdcp_netlink_element_s* data_p = NULL; - /* avoid gcc warnings */ - (void)data_p; - module_id_t ue_id = 0; - pdcp_t* pdcp_p = NULL; -# if defined(PDCP_USE_NETLINK_QUEUES) - rb_id_t rab_id = 0; +#ifdef UE_NAS_USE_TUN + protocol_ctxt_t ctxt = *ctxt_pP; + hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; + hashtable_rc_t h_rc; + pdcp_t* pdcp_p = NULL; + int len; + rb_id_t rab_id = DEFAULT_RAB_ID; + + do { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); + len = read(nas_sock_fd[ctxt_pP->module_id], &nl_rx_buf, NL_MAX_PAYLOAD); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); - pdcp_transmission_mode_t pdcp_mode = PDCP_TRANSMISSION_MODE_UNKNOWN; + if (len<=0) continue; + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + if (h_rc == HASH_TABLE_OK) { + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + ctxt.frame, ctxt.instance, len, rab_id); + + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, + ctxt.rnti, rab_id); + MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt.instance, rab_id, rab_id, len); + + pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf, + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + , NULL, NULL +#endif + ); + } else { + MSC_LOG_RX_DISCARDED_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt.instance, rab_id, rab_id, len); + LOG_D(PDCP, + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, + ctxt.rnti, rab_id, key); + } + } while (len > 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 ); + return len; +#else /* UE_NAS_USE_TUN */ - while (pdcp_netlink_dequeue_element(ctxt_pP, &data_p) != 0) { - DevAssert(data_p != NULL); - rab_id = data_p->pdcp_read_header.rb_id % maxDRB; - // ctxt_pP->rnti is NOT_A_RNTI - ctxt_cpy.rnti = pdcp_module_id_to_rnti[ctxt_cpy.module_id][data_p->pdcp_read_header.inst]; - key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_cpy.rnti, ctxt_pP->enb_flag, rab_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); +#ifdef PDCP_USE_NETLINK + protocol_ctxt_t ctxt_cpy = *ctxt_pP; + protocol_ctxt_t ctxt; + hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; + hashtable_rc_t h_rc; + struct pdcp_netlink_element_s* data_p = NULL; + /* avoid gcc warnings */ + (void)data_p; + module_id_t ue_id = 0; + pdcp_t* pdcp_p = NULL; + +//TTN for D2D (PC5S) +#ifdef Rel14 + int prose_addr_len; + char send_buf[BUFSIZE], receive_buf[BUFSIZE]; + // Panos: Remove the following definitions due to warnings of unused variables. + //int optval; + int bytes_received; + sidelink_pc5s_element *sl_pc5s_msg_recv = NULL; + sidelink_pc5s_element *sl_pc5s_msg_send = NULL; + //uint32_t sourceL2Id; + //uint32_t groupL2Id; + //module_id_t module_id = 0; + pc5s_header_t *pc5s_header; +#endif - if (h_rc != HASH_TABLE_OK) { - LOG_W(PDCP, PROTOCOL_CTXT_FMT" Dropped IP PACKET cause no PDCP instanciated\n", - PROTOCOL_CTXT_ARGS(ctxt_pP)); - free(data_p->data); - free(data_p); - data_p = NULL; - continue; - } +# if defined(PDCP_USE_NETLINK_QUEUES) + rb_id_t rab_id = 0; + + pdcp_transmission_mode_t pdcp_mode = PDCP_TRANSMISSION_MODE_UNKNOWN; + + + while (pdcp_netlink_dequeue_element(ctxt_pP, &data_p) != 0) { + DevAssert(data_p != NULL); + rab_id = data_p->pdcp_read_header.rb_id % maxDRB; + // ctxt_pP->rnti is NOT_A_RNTI + ctxt_cpy.rnti = pdcp_module_id_to_rnti[ctxt_cpy.module_id][data_p->pdcp_read_header.inst]; + key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_cpy.rnti, ctxt_pP->enb_flag, rab_id, SRB_FLAG_NO); + h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + + if (h_rc != HASH_TABLE_OK) { + LOG_W(PDCP, PROTOCOL_CTXT_FMT" Dropped IP PACKET cause no PDCP instanciated\n", + PROTOCOL_CTXT_ARGS(ctxt_pP)); + free(data_p->data); + free(data_p); + data_p = NULL; + continue; + } - CHECK_CTXT_ARGS(&ctxt_cpy); + CHECK_CTXT_ARGS(&ctxt_cpy); - AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); + AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); - if (rab_id != 0) { - LOG_D(PDCP, "[FRAME %05d][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ " - "/ %d Bytes --->][PDCP][MOD %u][RB %u]\n", - ctxt_cpy.frame, - (ctxt_cpy.enb_flag) ? "eNB" : "UE", - data_p->pdcp_read_header.inst, - data_p->pdcp_read_header.rb_id, - data_p->pdcp_read_header.data_size, - ctxt_cpy.module_id, - rab_id); + if (rab_id != 0) { + LOG_D(PDCP, "[FRAME %05d][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ " + "/ %d Bytes --->][PDCP][MOD %u][RB %u]\n", + ctxt_cpy.frame, + (ctxt_cpy.enb_flag) ? "eNB" : "UE", + data_p->pdcp_read_header.inst, + data_p->pdcp_read_header.rb_id, + data_p->pdcp_read_header.data_size, + ctxt_cpy.module_id, + rab_id); #ifdef OAI_NW_DRIVER_TYPE_ETHERNET - if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ || - (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ || - (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) { -#if defined(Rel10) || defined(Rel14) - PDCP_TRANSMISSION_MODE_TRANSPARENT; + if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ || + (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ || + (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) { +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + PDCP_TRANSMISSION_MODE_TRANSPARENT; #else - pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; + pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; #endif - } else if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_UNICAST) /* TRAFFIC_IPV6_TYPE_UNICAST */ || - (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_UNICAST) /*TRAFFIC_IPV4_TYPE_UNICAST*/ ) { - pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; - } else { - pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; - LOG_W(PDCP,"unknown IP traffic type \n"); - } + } else if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_UNICAST) /* TRAFFIC_IPV6_TYPE_UNICAST */ || + (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_UNICAST) /*TRAFFIC_IPV4_TYPE_UNICAST*/ ) { + pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; + } else { + pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; + LOG_W(PDCP,"unknown IP traffic type \n"); + } #else // OAI_NW_DRIVER_TYPE_ETHERNET NASMESH driver does not curreenlty support multicast traffic - pdcp_mode = PDCP_TRANSMISSION_MODE_DATA; -#endif - pdcp_data_req(&ctxt_cpy, - SRB_FLAG_NO, - rab_id % maxDRB, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - data_p->pdcp_read_header.data_size, - data_p->data, - pdcp_mode); - } else if (ctxt_cpy.enb_flag) { - /* rb_id = 0, thus interpreated as broadcast and transported as - * multiple unicast is a broadcast packet, we have to send this - * packet on all default RABS of all connected UEs - */ - LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID first_ue_local %u nb_ue_local %u\n", oai_emulation.info.first_ue_local, oai_emulation.info.nb_ue_local); - - for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { - if (pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { - LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id); - ctxt.module_id = ctxt_cpy.module_id; - ctxt.rnti = ctxt_cpy.pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ctxt_cpy.enb_flag; - - pdcp_data_req( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - data_p->pdcp_read_header.data_size, - data_p->data, - PDCP_TRANSMISSION_MODE_DATA); - } + pdcp_mode = PDCP_TRANSMISSION_MODE_DATA; +#endif + pdcp_data_req(&ctxt_cpy, + SRB_FLAG_NO, + rab_id % maxDRB, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + data_p->pdcp_read_header.data_size, + data_p->data, + pdcp_mode +#ifdef Rel14 + ,NULL, NULL +#endif + ); + } else if (ctxt_cpy.enb_flag) { + /* rb_id = 0, thus interpreated as broadcast and transported as + * multiple unicast is a broadcast packet, we have to send this + * packet on all default RABS of all connected UEs + */ + LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID first_ue_local %u nb_ue_local %u\n", oai_emulation.info.first_ue_local, oai_emulation.info.nb_ue_local); + + for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { + if (pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { + LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id); + ctxt.module_id = ctxt_cpy.module_id; + ctxt.rnti = ctxt_cpy.pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; + ctxt.frame = ctxt_cpy.frame; + ctxt.enb_flag = ctxt_cpy.enb_flag; + + pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + data_p->pdcp_read_header.data_size, + data_p->data, + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,NULL, NULL +#endif + ); + } + } + } else { + LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); + pdcp_data_req( + &ctxt_cpy, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + data_p->pdcp_read_header.data_size, + data_p->data, + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,NULL, NULL +#endif + ); } - } else { - LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - pdcp_data_req( - &ctxt_cpy, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - data_p->pdcp_read_header.data_size, - data_p->data, - PDCP_TRANSMISSION_MODE_DATA); - } - free(data_p->data); - free(data_p); - data_p = NULL; - } + free(data_p->data); + free(data_p); + data_p = NULL; + } - return 0; + return 0; # else /* PDCP_USE_NETLINK_QUEUES*/ - int len = 1; - int msg_len; - rb_id_t rab_id = 0; - int rlc_data_req_flag = 3; - - while ((len > 0) && (rlc_data_req_flag !=0)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); - len = recvmsg(nas_sock_fd, &nas_msg_rx, 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); + int len = 1; + int msg_len; + rb_id_t rab_id = 0; + int rlc_data_req_flag = 3; + + +//TTN for D2D (PC5S) +#ifdef Rel14 + prose_addr_len = sizeof(prose_pdcp_addr); + // receive a message from ProSe App + memset(receive_buf, 0, BUFSIZE); + bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0, + (struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len); + // if (bytes_received < 0){ + // LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n"); + // exit(EXIT_FAILURE); + // } + if (bytes_received > 0) { + pc5s_header = calloc(1, sizeof(pc5s_header_t)); + memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t)); + + if (pc5s_header->traffic_type == TRAFFIC_PC5S_SESSION_INIT){ + //send reply to ProSe app + LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n"); + memset(send_buf, 0, BUFSIZE); + sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element)); + sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT; + sl_pc5s_msg_send->pc5sPrimitive.status = 1; + + memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element)); + int prose_addr_len = sizeof(prose_pdcp_addr); + int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len); + if (bytes_sent < 0) { + LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } + } else if (pc5s_header->traffic_type == TRAFFIC_PC5S_SIGNALLING) { //if containing PC5-S message -> send to other UE + LOG_D(PDCP,"Received PC5-S message ... send to the other UE\n"); +#ifdef PDCP_DEBUG + LOG_D(PDCP,"Received PC5-S message, traffic_type: %d)\n", pc5s_header->traffic_type); + LOG_D(PDCP,"Received PC5-S message, rbid: %d)\n", pc5s_header->rb_id); + LOG_D(PDCP,"Received PC5-S message, data_size: %d)\n", pc5s_header->data_size); + LOG_D(PDCP,"Received PC5-S message, inst: %d)\n", pc5s_header->inst); + LOG_D(PDCP,"Received PC5-S message,sourceL2Id: 0x%08x\n)\n", pc5s_header->sourceL2Id); + LOG_D(PDCP,"Received PC5-S message,destinationL1Id: 0x%08x\n)\n", pc5s_header->destinationL2Id); - if (len<=0) { - // nothing in pdcp NAS socket - //LOG_D(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len); - } else { - - msg_len = len; - for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf; - NLMSG_OK (nas_nlh_rx, msg_len); - nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, msg_len)) { - - if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) { - LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n"); - //return; - } - - if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) { - LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n"); - } - - if (pdcp_read_state_g == 0) { - if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { - pdcp_read_state_g = 1; //get - memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); - LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d\n", - pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size); - } else { - LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n", - nas_nlh_rx->nlmsg_len); - } - } else { - pdcp_read_state_g = 0; - // print_active_requests() +#endif + +#ifdef OAI_EMU + + // overwrite function input parameters, because only one netlink socket for all instances + if (pc5s_header->inst < oai_emulation.info.nb_enb_local) { + ctxt.frame = ctxt_cpy.frame; + ctxt.enb_flag = ENB_FLAG_YES; + ctxt.module_id = pc5s_header.inst + oai_emulation.info.first_enb_local; + ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pc5s_header->rb_id / maxDRB + oai_emulation.info.first_ue_local]; + rab_id = pc5s_header->rb_id % maxDRB; + } else { + ctxt.frame = ctxt_cpy.frame; + ctxt.enb_flag = ENB_FLAG_NO; + ctxt.module_id = pc5s_header->inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; + ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; + rab_id = pc5s_header->rb_id % maxDRB; + } + + CHECK_CTXT_ARGS(&ctxt); + AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); + /*LGpdcp_read_header.inst = (pc5s_header.inst >= oai_emulation.info.nb_enb_local) ? \ + pc5s_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : + pc5s_header.inst + oai_emulation.info.first_enb_local;*/ +#else // OAI_EMU + /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ + // pc5s_header.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; + + LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id); + + if (ctxt_cpy.enb_flag) { + ctxt.module_id = 0; + rab_id = pc5s_header->rb_id % maxDRB; + ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index]; + } else { + ctxt.module_id = 0; + rab_id = pc5s_header->rb_id % maxDRB; + ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; + } +#endif + + //UE + if (!ctxt.enb_flag) { + if (rab_id != 0) { + if (rab_id == UE_IP_DEFAULT_RAB_ID) { + LOG_I(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } else { + rab_id = rab_id % maxDRB; + LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); + h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } + + if (h_rc == HASH_TABLE_OK) { + rab_id = pdcp_p->rb_id; #ifdef PDCP_DEBUG - LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n", - nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr)); + LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + ctxt.frame, + pc5s_header->inst, + bytes_received, + pc5s_header->rb_id); + + LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + ctxt.frame, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); +#endif + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pc5s_header.inst, + pc5s_header.rb_id, + rab_id, + pc5s_header.data_size); + + pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pc5s_header->data_size, + (unsigned char *)receive_buf, + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,&pc5s_header->sourceL2Id + ,&pc5s_header->destinationL2Id +#endif + ); + } else { + MSC_LOG_RX_DISCARDED_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pc5s_header.inst, + pc5s_header.rb_id, + rab_id, + pc5s_header.data_size); + LOG_D(PDCP, + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + ctxt.frame, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, + ctxt.module_id, + ctxt.rnti, + rab_id, + key); + } + } else { //if (rab_id == 0) + LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + ctxt.frame, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, + ctxt.module_id, + ctxt.rnti, + DEFAULT_RAB_ID); + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL,0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pc5s_header->inst, + pc5s_header->rb_id, + DEFAULT_RAB_ID, + pc5s_header->data_size); + + pdcp_data_req ( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pc5s_header->data_size, + (unsigned char *)receive_buf, + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,&pc5s_header->sourceL2Id + ,&pc5s_header->destinationL2Id #endif + ); + } + } + free (sl_pc5s_msg_recv); + free (sl_pc5s_msg_send); + } + } - /* 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; +#endif + while ((len > 0) && (rlc_data_req_flag !=0)) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); + len = recvmsg(nas_sock_fd, &nas_msg_rx, 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); + + if (len<=0) { + // nothing in pdcp NAS socket + //LOG_D(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len); + } else { + + msg_len = len; + for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf; + NLMSG_OK (nas_nlh_rx, msg_len); + nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, msg_len)) { + + if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) { + LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n"); + //return; + } + + if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) { + LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n"); + } + + if (pdcp_read_state_g == 0) { + if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { + pdcp_read_state_g = 1; //get + memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); + LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n", + pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size,pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id ); + } else { + LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n", + nas_nlh_rx->nlmsg_len); + } + } else { + pdcp_read_state_g = 0; + // print_active_requests() #ifdef PDCP_DEBUG - LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d\n", pdcp_read_header_g.rb_id); + LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n", + nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr)); #endif +#ifdef OAI_EMU + + + // overwrite function input parameters, because only one netlink socket for all instances + if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) { + ctxt.frame = ctxt_cpy.frame; + ctxt.enb_flag = ENB_FLAG_YES; + ctxt.module_id = pdcp_read_header_g.inst + oai_emulation.info.first_enb_local; + ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / maxDRB + oai_emulation.info.first_ue_local]; + rab_id = pdcp_read_header_g.rb_id % maxDRB; + } else { + ctxt.frame = ctxt_cpy.frame; + ctxt.enb_flag = ENB_FLAG_NO; + ctxt.module_id = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; + ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; + rab_id = pdcp_read_header_g.rb_id % maxDRB; + } + + CHECK_CTXT_ARGS(&ctxt); + AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); + /*LGpdcp_read_header.inst = (pdcp_read_header_g.inst >= oai_emulation.info.nb_enb_local) ? \ + 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 + /* 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; + +#ifdef PDCP_DEBUG + LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id); +#endif if (ctxt_cpy.enb_flag) { ctxt.module_id = 0; rab_id = pdcp_read_header_g.rb_id % maxDRB; @@ -562,225 +933,246 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; } +#endif + if (ctxt.enb_flag) { if (rab_id != 0) { rab_id = rab_id % maxDRB; key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - if (h_rc == HASH_TABLE_OK) { + + if (h_rc == HASH_TABLE_OK) { #ifdef PDCP_DEBUG - LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", - ctxt.frame, - pdcp_read_header_g.inst, - len, - nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), - pdcp_read_header_g.rb_id); -#endif - - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n", - ctxt_cpy.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id); - - pdcp_data_req(&ctxt, + LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", + ctxt.frame, + pdcp_read_header_g.inst, + len, + nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), + pdcp_read_header_g.rb_id); +#endif + + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + rab_id, + pdcp_read_header_g.data_size); + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n", + ctxt_cpy.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); + + pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA); - } else { - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id); - } - } else { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast - // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs -//#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES - for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { - if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - DEFAULT_RAB_ID); - pdcp_data_req ( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA); - } - } - } - } else { // enb_flag - if (rab_id != 0) { - if (rab_id == UE_IP_DEFAULT_RAB_ID) { - LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", - ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - } else { - rab_id = rab_id % maxDRB; - LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", - ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); - key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - } - - if (h_rc == HASH_TABLE_OK) { - rab_id = pdcp_p->rb_id; + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,NULL, NULL +#endif + ); + } else { + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); + } + } else { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast + // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs + //#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES + for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { + if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { + ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + DEFAULT_RAB_ID); + pdcp_data_req ( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,NULL, NULL +#endif + ); + } + } + } + } else { // enb_flag + if (rab_id != 0) { + if (rab_id == UE_IP_DEFAULT_RAB_ID) { + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } else { + rab_id = rab_id % maxDRB; + LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); + h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } + + if (h_rc == HASH_TABLE_OK) { + rab_id = pdcp_p->rb_id; #ifdef PDCP_DEBUG - LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", - ctxt.frame, - pdcp_read_header_g.inst, - len, - nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), - pdcp_read_header_g.rb_id); - - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id); -#endif - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - - pdcp_data_req( - &ctxt, - SRB_FLAG_NO, - rab_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA); - } else { - MSC_LOG_RX_DISCARDED_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id, - key); - } - } else { - LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - DEFAULT_RAB_ID); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL,0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - DEFAULT_RAB_ID, - pdcp_read_header_g.data_size); - - pdcp_data_req ( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA); - } - } + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", + ctxt.frame, + pdcp_read_header_g.inst, + len, + nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), + pdcp_read_header_g.rb_id); + + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); +#endif + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + rab_id, + pdcp_read_header_g.data_size); + + pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,&pdcp_read_header_g.sourceL2Id + ,&pdcp_read_header_g.destinationL2Id +#endif + ); + } else { + MSC_LOG_RX_DISCARDED_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + rab_id, + pdcp_read_header_g.data_size); + LOG_D(PDCP, + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id, + key); + } + } else { + LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + DEFAULT_RAB_ID); + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL,0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + DEFAULT_RAB_ID, + pdcp_read_header_g.data_size); + + pdcp_data_req ( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,&pdcp_read_header_g.sourceL2Id + ,&pdcp_read_header_g.destinationL2Id +#endif + ); + } + } - } + } + } } - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 ); - } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 ); + } - return len; + + return len; # endif #else // neither PDCP_USE_NETLINK nor PDCP_USE_RT_FIFO - return 0; + return 0; #endif // PDCP_USE_NETLINK +#endif /* #else UE_NAS_USE_TUN */ } void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) { - unsigned char *otg_pkt=NULL; + module_id_t dst_id; // dst for otg - rb_id_t rb_id; - unsigned int pkt_size=0; protocol_ctxt_t ctxt; // we need to add conditions to avoid transmitting data when the UE is not RRC connected. if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic - unsigned int ctime=0; - ctime = ctxt_pP->frame * 100; - /*if ((mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 0 ) > 2) && - (mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 1 ) > 2)) { */ PROTOCOL_CTXT_SET_BY_MODULE_ID( &ctxt, ctxt_pP->module_id, @@ -790,37 +1182,46 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) ctxt_pP->subframe, ctxt_pP->module_id); - for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) { + for (dst_id = 0; dst_id<MAX_MOBILES_PER_ENB; dst_id++) { ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id]; - - if (ctxt.rnti != NOT_A_RNTI) { - if (mac_eNB_get_rrc_status(ctxt.module_id, ctxt.rnti ) > 2 /*RRC_SI_RECEIVED*/) { - unsigned int temp = 0; - otg_pkt=packet_gen( - ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id), - UE_MODULE_ID_TO_INSTANCE(dst_id), - 0, - ctime, - &temp); - pkt_size = temp; - - if (otg_pkt != NULL) { - rb_id = dst_id * maxDRB + DTCH; - pdcp_data_req(&ctxt, - SRB_FLAG_NO, - rb_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pkt_size, - otg_pkt, - PDCP_TRANSMISSION_MODE_DATA); - LOG_I(OTG, - "send packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", - ctxt_pP->module_id, rb_id, ctxt_pP->module_id, dst_id, pkt_size); - free(otg_pkt); - } - } - } } } } + +//TTN for D2D (PC5S) +#ifdef Rel14 + +void +pdcp_pc5_socket_init() { + //pthread_attr_t attr; + //struct sched_param sched_param; + int optval; // flag value for setsockopt + //int n; // message byte size + + //create PDCP socket + pdcp_pc5_sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (pdcp_pc5_sockfd < 0){ + LOG_E(PDCP,"[pdcp_pc5_socket_init] Error opening socket %d (%d:%s)\n",pdcp_pc5_sockfd,errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + optval = 1; + setsockopt(pdcp_pc5_sockfd, SOL_SOCKET, SO_REUSEADDR, + (const void *)&optval , sizeof(int)); + + fcntl(pdcp_pc5_sockfd,F_SETFL,O_NONBLOCK); + + bzero((char *) &pdcp_sin, sizeof(pdcp_sin)); + pdcp_sin.sin_family = AF_INET; + pdcp_sin.sin_addr.s_addr = htonl(INADDR_ANY); + pdcp_sin.sin_port = htons(PDCP_SOCKET_PORT_NO); + // associate the parent socket with a port + if (bind(pdcp_pc5_sockfd, (struct sockaddr *) &pdcp_sin, + sizeof(pdcp_sin)) < 0) { + LOG_E(PDCP,"[pdcp_pc5_socket_init] ERROR: Failed on binding the socket\n"); + exit(1); + } + +} + +#endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c index 0df8e59e6d4536bd09654ac739d5651c11fc78d5..f0b15d9888d7d0268be4d43df309f89519e1c5f4 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c @@ -55,7 +55,7 @@ #include "UTIL/LOG/log.h" #include "UTIL/OCG/OCG.h" #include "UTIL/OCG/OCG_extern.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "pdcp.h" #include "pdcp_primitives.h" diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h index afcc2fdd0255dc0f11d15df8e670ee29dec8119f..a939543432674fabc3568ce499ec32095656c675 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h @@ -52,7 +52,12 @@ extern int reception_from_rohc_bs(void); #else extern BOOL pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t * sduP, uint8_t is_data_plane); extern BOOL pdcp_data_req (module_id_t module_id, uint32_t frame, uint8_t eNB_flag, rb_id_t rab_id, uint32_t muiP, uint32_t confirmP, sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer, - uint8_t is_data_pdu); + uint8_t is_data_pdu +#ifdef Rel14 + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + ); //extern BOOL pdcp_data_req (struct pdcp_entity *pdcpP, mem_block * sduP); extern void send_pdcp_control_primitive (struct pdcp_entity *pdcpP, mem_block * cprimitiveP); extern void control_pdcp (struct pdcp_entity *pdcpP); @@ -63,4 +68,7 @@ extern void pdcp_process_input_sdus_tr (struct pdcp_entity *pdcpP); extern void init_pdcp (struct pdcp_entity *pdcpP, struct rb_dispatcher *rbP, uint8_t rb_idP); extern void *pdcp_tx (void *argP); #endif + +extern void pdcp_pc5_socket_init(void); + #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index 2554eb145ab9de975100795e207efe6276e39978..2c29053297d67a5b5daf836a8a99fe60b7bd8b58 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -34,7 +34,7 @@ #include "UTIL/LOG/vcd_signal_dumper.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "pdcp.h" #include "msc.h" diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index a0610170d4664810282c323d925ff07241e75b88..7af03529645a1415d76c934919020bc8800ac4c1 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -37,7 +37,7 @@ #include "mac_primitives.h" #include "rlc_primitives.h" #include "list.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UL-AM-RLC.h" #include "DL-AM-RLC.h" @@ -240,7 +240,7 @@ config_req_rlc_am ( uint16_t pollPDU_tab[PollPDU_pInfinity+1]= {4,8,16,32,64,128,256,RLC_AM_POLL_PDU_INFINITE}; //PollPDU_pInfinity is chosen to 0xFFFF for now uint32_t maxRetxThreshold_tab[UL_AM_RLC__maxRetxThreshold_t32+1]= {1,2,3,4,6,8,16,32}; uint32_t pollByte_tab[PollByte_spare1]= {25000,50000,75000,100000,125000,250000,375000,500000,750000,1000000,1250000,1500000,2000000,3000000,RLC_AM_POLL_BYTE_INFINITE}; // PollByte_kBinfinity is chosen to 0xFFFFFFFF for now -#if defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t PollRetransmit_tab[T_PollRetransmit_spare5]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,2000,4000}; uint32_t am_t_Reordering_tab[32]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200,1600}; uint32_t t_StatusProhibit_tab[T_StatusProhibit_spare2]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,1200,1600,2000,2400}; @@ -271,7 +271,7 @@ void config_req_rlc_am_asn1 ( if ((config_am_pP->ul_AM_RLC.maxRetxThreshold <= UL_AM_RLC__maxRetxThreshold_t32) && (config_am_pP->ul_AM_RLC.pollPDU<=PollPDU_pInfinity) && (config_am_pP->ul_AM_RLC.pollByte<PollByte_spare1) && -#if defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (config_am_pP->ul_AM_RLC.t_PollRetransmit<T_PollRetransmit_spare5) && (config_am_pP->dl_AM_RLC.t_Reordering<32) && (config_am_pP->dl_AM_RLC.t_StatusProhibit<T_StatusProhibit_spare2) ) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h index 5130bde38b9f32f6a8d3b18c6d4d8e139c388c84..040145f7f03c1da8db15b77f979d0c155ef9e1cf 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h @@ -71,6 +71,7 @@ # include "rlc_am_reassembly.h" # include "rlc_am_init.h" # include "RLC-Config.h" +# include "assertions.h" //# include "rlc_am_test.h" diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c index 64e1847f90ac0223d927bad02ffba381f62dcac3..3159eccc0cdbc960232a656d4dd889847dc7fd9d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c @@ -30,7 +30,7 @@ #define RLC_AM_IN_SDU_C 1 //----------------------------------------------------------------------------- #include "rlc_am.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #define TRACE_RLC_AM_FREE_SDU 0 diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index 01a635656e24ce819f112c399f70f99ccf7a3e1a..0b0a55bd2b66ee32560704e02ef7b29766e64a47 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -24,7 +24,7 @@ #include <string.h> //----------------------------------------------------------------------------- #include "rlc_am.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" //----------------------------------------------------------------------------- void diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h index 2ee7d040ab36b65b0a617dacd8a24e69aa34d996..c69fd3766e4554e043598825f3f61ca68b3de987 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h @@ -55,7 +55,7 @@ //----------------------------------------------------------------------------- #include "platform_types.h" #include "platform_constants.h" -#include "PHY/defs.h" +//#include "PHY/defs.h" /*! \struct rlc_am_info_t diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index 469b3461c0e6bf0d0bfdfba34c6dd1e9f7b2e6e3..8b5776dfe7ebd89aaff51385f6442e65e86432d2 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -30,7 +30,7 @@ #include "rlc.h" #include "rlc_am.h" #include "list.h" -#include "LAYER2/MAC/extern.h" +//#include "LAYER2/MAC/extern.h" #include "UTIL/LOG/log.h" #include "msc.h" diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c index 06fc3a5416eb02ab3b07e89c2193b64e67b635ec..83dec8653a65cb9ec08da12ae966c383e28d9854 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c @@ -28,7 +28,7 @@ #include "rlc.h" #include "rlc_am.h" #include "list.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 4e477d45187776f00c400a84e0a6d1db0ec980d2..827bf1b627d8c5eacbd16c22d6862a025bd7a063 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -26,7 +26,7 @@ //----------------------------------------------------------------------------- #include "rlc_am.h" #include "rlc.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "msc.h" //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 5315548498729f1c52854faad97896dbee965284..301761c9e5c5e3c6e1f43ef2087ce8c3ab706438 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -27,7 +27,7 @@ #include "assertions.h" #include "list.h" #include "rlc_am.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h index d2f0740b33de9530a97e531f442f955562ba2d42..9dcc75223dc6d543f1be05dfdfc43af51473760b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h @@ -56,7 +56,7 @@ //----------------------------------------------------------------------------- #include "platform_types.h" #include "platform_constants.h" -#include "PHY/defs.h" +//#include "PHY/defs.h" //----------------------------------------------------------------------------- /*! \fn rlc_am_rx_pdu_status_t rlc_am_rx_list_check_duplicate_insert_pdu(const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* const rlc_pP,mem_block_t* const tb_pP) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index 3f62b05c55c2d1f039df53c9ed73a2bd5de2bdb6..03dd524a5caa6dbd5731e2d8f12f33135c9b7e9c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -29,7 +29,7 @@ #include "msc.h" #include "list.h" #include "rlc_am.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index d702de4aa6a1c5a29960557c87b896ecf9b2edf7..a9059df11c7b57eb485770497684a020ab58a661 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -32,7 +32,6 @@ #include "assertions.h" #include "list.h" #include "rlc_am.h" -#include "LAYER2/MAC/extern.h" #include "UTIL/LOG/log.h" # if ENABLE_ITTI diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h index e09189fcd6060c9b303c59b6b3a6a75cd98df10a..41f214d7c6cc54c87d4fcc6b5aefeece7ebd6efc 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h @@ -55,7 +55,7 @@ //----------------------------------------------------------------------------- #include "platform_types.h" #include "platform_constants.h" -#include "PHY/defs.h" +//#include "PHY/defs.h" //----------------------------------------------------------------------------- /*! \fn uint16_t rlc_am_read_bit_field (uint8_t** dataP, unsigned int* bit_posP, const signed int bits_to_readP) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c index 7069e099ebd641624be903c404e8628df1e42a30..cae015306236e9cf5dadce749d6eabc6dbac0531 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c @@ -27,7 +27,7 @@ #include "platform_constants.h" //----------------------------------------------------------------------------- #include "rlc_am.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "msc.h" //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c index 92bb3d61550fa31c62ddcdbd7fee4fe23a74f4b7..19b9b41ca67f40fe666a794afffad9723e5c8fe9 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c @@ -26,7 +26,7 @@ #include "platform_constants.h" //----------------------------------------------------------------------------- #include "rlc_am.h" -# include "LAYER2/MAC/extern.h" +# include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "msc.h" //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c index 13d4205c2800cd1f7de367f46547ce928e9efe53..84c0edbefd52730a8b73d4c36af1611bf8115062 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c @@ -26,7 +26,7 @@ #include "platform_constants.h" //----------------------------------------------------------------------------- #include "rlc_am.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "msc.h" //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c index ee2ff57c1eae1a9a48d9e4013a1abe76907ec9bc..23a4d0eb0478c9aab4e00880f9428d121fafe5e6 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c @@ -29,7 +29,7 @@ #include "mac_primitives.h" #include "rlc_primitives.h" #include "list.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" //----------------------------------------------------------------------------- void rlc_tm_send_sdu ( diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c index 972d40bb3f8662017e50f8956fc0387c706c2d24..78d7cc515f4ae713991cd7ec51c964242a232c10 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c @@ -23,7 +23,7 @@ #define RLC_TM_INIT_C 1 //----------------------------------------------------------------------------- #include "rlc_tm.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" //----------------------------------------------------------------------------- void config_req_rlc_tm ( const protocol_ctxt_t* const ctxt_pP, diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c index b1c455aee0e30a1676729737c18ad15ad84bfe79..d8f151a5ff8d59315c922cec65a0c3b09f106cc5 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c @@ -35,7 +35,7 @@ #include "list.h" #include "rlc_primitives.h" #include "mac_primitives.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c index 499cdc70804fc66a0d74cab28db8b8977933dfa9..f884bc3eaa52befe725e52f87772c5cc41bbc611 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c @@ -28,7 +28,7 @@ #include "rlc_primitives.h" #include "list.h" #include "rrm_config_structs.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "rlc_um_control_primitives.h" @@ -78,7 +78,7 @@ void config_req_rlc_um ( } } //----------------------------------------------------------------------------- -#if defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) const uint32_t t_Reordering_tab[32] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200,1600}; #else const uint32_t t_Reordering_tab[T_Reordering_spare1] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; @@ -93,7 +93,12 @@ void config_req_rlc_um_asn1 ( const UL_UM_RLC_t * const ul_rlc_pP, const DL_UM_RLC_t * const dl_rlc_pP, const rb_id_t rb_idP, - const logical_chan_id_t chan_idP) + const logical_chan_id_t chan_idP +#ifdef Rel14 + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) { uint32_t ul_sn_FieldLength = 0; uint32_t dl_sn_FieldLength = 0; @@ -103,7 +108,7 @@ void config_req_rlc_um_asn1 ( hash_key_t key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); hashtable_rc_t h_rc; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbms_flagP) { //AssertFatal(dl_rlc_pP, "No RLC UM DL config"); @@ -132,10 +137,14 @@ void config_req_rlc_um_asn1 ( } rlc_p = &rlc_union_p->rlc.um; + } + if ((sourceL2Id >0 ) && (destinationL2Id >0)){ + key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, sourceL2Id, destinationL2Id, srb_flagP); } else #endif { - key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); + key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); + } h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); //AssertFatal (h_rc == HASH_TABLE_OK, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %u, srb flag %u", // ctxt_pP->module_id, @@ -149,7 +158,6 @@ void config_req_rlc_um_asn1 ( return; } rlc_p = &rlc_union_p->rlc.um; - } //----------------------------------------------------------------------------- LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%dms sn_field_length= RB %u \n", @@ -218,7 +226,7 @@ void config_req_rlc_um_asn1 ( return; } -#if defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (dl_rlc_pP->t_Reordering<32) { #else if (dl_rlc_pP->t_Reordering<T_Reordering_spare1) { diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h index 5847a8bb13bbe08b445284efaed347331faf8740..fc64e95d995983184a55e99077f0ae474f7890b6 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h @@ -115,7 +115,12 @@ public_rlc_um_control_primitives( void config_req_rlc_um_asn1 ( const UL_UM_RLC_t * const ul_rlc_pP, const DL_UM_RLC_t * const dl_rlc_pP, const rb_id_t rb_idP, - const logical_chan_id_t chan_idP);) + const logical_chan_id_t chan_idP +#ifdef Rel14 + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + );) /*! \fn void rlc_um_init (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP) * \brief Initialize a RLC UM protocol instance, initialize all variables, lists, allocate buffers for making this instance ready to be configured with protocol configuration parameters. After this initialization the RLC UM protocol instance will be in RLC_NULL_STATE state. diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c index 0a6bf44dda5bdd106fa7bf94dcd163c74ab9cb9d..fa0bf4b288b2c6a1bc996d418b450e305b044f86 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c @@ -24,7 +24,7 @@ #include "platform_types.h" //----------------------------------------------------------------------------- #include "rlc_um.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c index 91e1ba66d1bfa662eb29f75cdd286260c48e5147..65aaadb9fa38106defed77ef211b9f497c327e5d 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c @@ -33,7 +33,7 @@ #include "rlc_um.h" #include "rlc_primitives.h" #include "list.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "msc.h" diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c index 6e5393f48a08e53c085fe915ac5e2ac98c203da0..91ae265f172d1c0c801c449c40372c121215f9c2 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c @@ -172,7 +172,7 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP test_pdu_remaining_size = 0; test_remaining_size_to_substract = 0; test_remaining_num_li_to_substract = 0; - pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3); + //pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3); } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) < test_pdu_remaining_size ) { test_num_li += 1; num_fill_sdu += 1; @@ -365,9 +365,9 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP sdu_mngt_p->sdu_remaining_size, pdu_remaining_size - sdu_mngt_p->sdu_remaining_size); #endif -#if !EXMIMO - assert(1!=1); -#endif +//#if !EXMIMO +// assert(1!=1); +//#endif memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size); // reduce the size of the PDU continue_fill_pdu_with_sdu = 0; diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index c40d3472e609e62ea0673d870fe8df247486914c..5e15884de822c7eec8c2e3bfbdcc802881fd2b11 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -29,7 +29,7 @@ #define RLC_C #include "rlc.h" #include "mem_block.h" -#include "../MAC/extern.h" +#include "../MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/OCG/OCG_vars.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -319,7 +319,12 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, const mui_t muiP, confirm_t confirmP, sdu_size_t sdu_sizeP, - mem_block_t *sdu_pP) + mem_block_t *sdu_pP +#ifdef Rel14 + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + ) { //----------------------------------------------------------------------------- mem_block_t *new_sdu_p = NULL; @@ -328,7 +333,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t log_ch_id = 0; #endif @@ -342,7 +347,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, sdu_sizeP, sdu_pP); #endif -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #else AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP); #endif @@ -378,13 +383,13 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, return RLC_OP_STATUS_BAD_PARAMETER; } -#if !defined(Rel10) && !defined(Rel14) +#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) DevCheck(MBMS_flagP == 0, MBMS_flagP, 0, 0); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -396,6 +401,10 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, } key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); + } + if (sourceL2Id && destinationL2Id){ + key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP); + //key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, *sourceL2Id, *destinationL2Id, srb_flagP); } else #endif { @@ -462,6 +471,15 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, break; case RLC_MODE_UM: + /* TODO: this is a hack, needs better solution. Let's not use too + * much memory and store at maximum 5 millions bytes. + */ + /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ + if (rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um) > 5000000) { + free_mem_block(sdu_pP, __func__); + return RLC_OP_STATUS_OUT_OF_RESSOURCES; + } + new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__); if (new_sdu_p != NULL) { @@ -516,7 +534,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) } else { /* MBMS_flag != 0 */ // LOG_I(RLC,"DUY rlc_data_req: mbms_rb_id in RLC instant is: %d\n", mbms_rb_id); if (sdu_pP != NULL) { @@ -638,8 +656,8 @@ rlc_module_init (void) return -1; } - for (module_id1=0; module_id1 < NUMBER_OF_UE_MAX; module_id1++) { -#if defined(Rel10) || defined(Rel14) + for (module_id1=0; module_id1 < MAX_MOBILES_PER_ENB; module_id1++) { +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (k=0; k < RLC_MAX_MBMS_LC; k++) { rlc_mbms_lcid2service_session_id_ue[module_id1][k].service_id = 0; @@ -654,7 +672,7 @@ rlc_module_init (void) } for (module_id1=0; module_id1 < NUMBER_OF_eNB_MAX; module_id1++) { -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (k=0; k < RLC_MAX_MBMS_LC; k++) { rlc_mbms_lcid2service_session_id_eNB[module_id1][k].service_id = 0; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index ffd963204eeba97839d93bf27cf393dedb9846c5..e3787d84178958c6101275b715f5156ba11f8dcd 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -47,7 +47,7 @@ # include "asn1_constants.h" # include "UTIL/LOG/log.h" # include "mem_block.h" -# include "PHY/defs.h" +//# include "PHY/defs.h" # include "RLC-Config.h" # include "DRB-ToAddMod.h" # include "DRB-ToAddModList.h" @@ -55,7 +55,7 @@ # include "SRB-ToAddModList.h" # include "DRB-ToReleaseList.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "PMCH-InfoList-r9.h" #endif @@ -174,7 +174,7 @@ typedef struct { //----------------------------------------------------------------------------- #define RLC_MAX_MBMS_LC (maxSessionPerPMCH * maxServiceCount) -#define RLC_MAX_LC ((max_val_DRB_Identity+1)* NUMBER_OF_UE_MAX) +#define RLC_MAX_LC ((max_val_DRB_Identity+1)* MAX_MOBILES_PER_ENB) protected_rlc(void (*rlc_rrc_data_ind)( const protocol_ctxt_t* const ctxtP, @@ -224,7 +224,7 @@ typedef struct rlc_mbms_id_s { mbms_session_id_t session_id; } rlc_mbms_id_t; -#if !defined(Rel10) && !defined(Rel14) +#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) # if !defined(maxServiceCount) //unused arrays rlc_mbms_array_ue rlc_mbms_array_eNB # define maxServiceCount 1 @@ -234,10 +234,10 @@ typedef struct rlc_mbms_id_s { # define maxSessionPerPMCH 1 # endif #endif -//public_rlc(rlc_mbms_t rlc_mbms_array_ue[NUMBER_OF_UE_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h +//public_rlc(rlc_mbms_t rlc_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h //public_rlc(rlc_mbms_t rlc_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h -public_rlc(rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[NUMBER_OF_UE_MAX][RLC_MAX_MBMS_LC];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h -public_rlc(rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[NUMBER_OF_eNB_MAX][RLC_MAX_MBMS_LC];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h +public_rlc(rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h +public_rlc(rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h #define rlc_mbms_enb_get_lcid_by_rb_id(Enb_mOD,rB_iD) rlc_mbms_rbid2lcid_eNB[Enb_mOD][rB_iD] ; @@ -253,8 +253,8 @@ public_rlc(rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[NUMBER_OF_e rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \ } while (0); -public_rlc(logical_chan_id_t rlc_mbms_rbid2lcid_ue [NUMBER_OF_UE_MAX][NB_RB_MBMS_MAX];) /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ -public_rlc(logical_chan_id_t rlc_mbms_rbid2lcid_eNB[NUMBER_OF_eNB_MAX][NB_RB_MBMS_MAX];) /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +public_rlc(logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX];) /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +public_rlc(logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];) /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ #define RLC_COLL_KEY_VALUE(eNB_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \ @@ -275,6 +275,23 @@ public_rlc(logical_chan_id_t rlc_mbms_rbid2lcid_eNB[NUMBER_OF_eNB_MAX][NB_RB_ (((hash_key_t)(iS_sRB)) << 33) | \ (((hash_key_t)(0x0a)) << 34)) +#define RLC_COLL_KEY_SOURCE_DEST_VALUE(eNB_iD, rNTI, iS_eNB, lC_iD, sOURCE_iD, dEST_iD, iS_sRB) \ + ((hash_key_t)eNB_iD | \ + (((hash_key_t)(rNTI)) << 8) | \ + (((hash_key_t)(iS_eNB)) << 24) | \ + (((hash_key_t)(lC_iD)) << 25) | \ + (((hash_key_t)(dEST_iD)) << 33) | \ + (((hash_key_t)(0x05)) << 57)) + +#define RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(eNB_iD, rNTI, iS_eNB, lC_iD, sOURCE_iD, dEST_iD, iS_sRB) \ + ((hash_key_t)eNB_iD | \ + (((hash_key_t)(rNTI)) << 8) | \ + (((hash_key_t)(iS_eNB)) << 24) | \ + (((hash_key_t)(lC_iD)) << 25) | \ + (((hash_key_t)(dEST_iD)) << 33) | \ + (((hash_key_t)(0x0a)) << 57)) + + // service id max val is maxServiceCount = 16 (asn1_constants.h) #define RLC_COLL_KEY_MBMS_VALUE(eNB_iD, rNTI, iS_eNB, sERVICE_ID, sESSION_ID) \ @@ -309,7 +326,7 @@ private_rlc_mac(struct mac_data_ind mac_rlc_deserialize_tb (char*, tb_size_t, //----------------------------------------------------------------------------- // PUBLIC INTERFACE WITH RRC //----------------------------------------------------------------------------- -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*! \fn rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, const SRB_ToAddMod_t* const srb2addmod, const DRB_ToAddModList_t* const drb2add_listP, const DRB_ToReleaseList_t* const drb2release_listP, const PMCH_InfoList_r9_t * const pmch_info_listP) * \brief Function for RRC to configure a Radio Bearer. * \param[in] ctxtP Running context. @@ -324,7 +341,9 @@ public_rlc_rrc( rlc_op_status_t rrc_rlc_config_asn1_req ( const SRB_ToAddModList_t* const , const DRB_ToAddModList_t* const , const DRB_ToReleaseList_t* const , - const PMCH_InfoList_r9_t * const pmch_info_listP);) + const PMCH_InfoList_r9_t * const pmch_info_listP , + const uint32_t , + const uint32_t );) #else /*! \fn rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t* const ctxtP, const SRB_ToAddModList_t* const srb2add_listP, const DRB_ToAddModList_t* const drb2add_listP, const DRB_ToReleaseList_t* const drb2release_listP) * \brief Function for RRC to configure a Radio Bearer. @@ -379,7 +398,12 @@ public_rlc_rrc(rlc_op_status_t rrc_rlc_remove_rlc (const protocol_ctxt_t* cons * \param[in] rlc_modeP Mode of RLC (AM, UM, TM). * \return A status about the processing, OK or error code. */ -private_rlc_rrc(rlc_union_t* rrc_rlc_add_rlc (const protocol_ctxt_t* const, const srb_flag_t, const MBMS_flag_t MBMS_flagP, const rb_id_t, logical_chan_id_t, rlc_mode_t);) +private_rlc_rrc(rlc_union_t* rrc_rlc_add_rlc (const protocol_ctxt_t* const, const srb_flag_t, const MBMS_flag_t MBMS_flagP, const rb_id_t, logical_chan_id_t, rlc_mode_t +#ifdef Rel14 + ,const uint32_t sourceL2Id, + const uint32_t destinationL2Id +#endif +);) /*! \fn rlc_op_status_t rrc_rlc_config_req ( const protocol_ctxt_t* const ctxtP, @@ -440,7 +464,12 @@ public_rlc_rrc(void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_d * \param [in,out] bufferP Memory area to fill with the bytes requested by MAC. * \return A status about the processing, OK or error code. */ -public_rlc_mac(tbs_size_t mac_rlc_data_req (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, const tb_size_t,char*);) +public_rlc_mac(tbs_size_t mac_rlc_data_req (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, const tb_size_t,char* +#ifdef Rel14 + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif +);) /*! \fn void mac_rlc_data_ind (const module_id_t mod_idP, const rnti_t rntiP, const frame_t frameP, const eNB_flag_t eNB_flagP, const MBMS_flag_t MBMS_flagP, logical_chan_id_t rb_idP, uint32_t frameP, char* bufferP, tb_size_t tb_sizeP, num_tb_t num_tbP, crc_t *crcs) * \brief Interface with MAC layer, deserialize the transport blocks sent by MAC, then map data indication to the RLC instance corresponding to the radio bearer identifier. @@ -470,7 +499,12 @@ public_rlc_mac(void mac_rlc_data_ind (const module_id_t, co * \param[in] tb_sizeP Size of a transport block set in bytes. * \return The maximum number of bytes that the RLC instance can send in the next transmission sequence. */ -public_rlc_mac(mac_rlc_status_resp_t mac_rlc_status_ind (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, tb_size_t );) +public_rlc_mac(mac_rlc_status_resp_t mac_rlc_status_ind (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, tb_size_t +#ifdef Rel14 + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + );) /*! \fn rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, const frame_t frameP, const sub_frame_t subframeP,const eNB_flag_t enb_flagP, const logical_chan_id_t channel_idP) * \brief Interface with MAC layer, UE only: request and get the number of bytes scheduled for transmission by the RLC instance corresponding to the radio bearer identifier. @@ -520,7 +554,12 @@ public_rlc(rlc_op_status_t rlc_data_req ( const mui_t , const confirm_t , const sdu_size_t , - mem_block_t * const);) + mem_block_t * const +#ifdef Rel14 + ,const uint32_t * const + ,const uint32_t * const +#endif + );) /*! \fn void rlc_data_ind (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, const sdu_size_t sdu_sizeP, mem_block_t* sduP) { * \brief Interface with higher layers, route SDUs coming from RLC protocol instances to upper layer instance. diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index cc15414913cd934550c577efcc8894dffe03a3dc..c56c9340677c98dd9113a8f39a785f4516d56fde 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -30,7 +30,7 @@ //----------------------------------------------------------------------------- #define RLC_MAC_C #include "rlc.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log.h" #include "UTIL/OCG/OCG_vars.h" #include "hashtable.h" @@ -126,7 +126,12 @@ tbs_size_t mac_rlc_data_req( const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, const tb_size_t tb_sizeP, - char *buffer_pP) + char *buffer_pP +#ifdef Rel14 + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) { //----------------------------------------------------------------------------- struct mac_data_req data_request; @@ -143,7 +148,7 @@ tbs_size_t mac_rlc_data_req( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,VCD_FUNCTION_IN); #ifdef DEBUG_MAC_INTERFACE - LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_REQ channel %d (%d) MAX RB %d, Num_tb %d\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_REQ channel %d (%d) MAX RB %d\n", PROTOCOL_CTXT_ARGS((&ctxt)), channel_idP, RLC_MAX_LC, @@ -174,6 +179,10 @@ tbs_size_t mac_rlc_data_req( } } else { key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag); +#ifdef Rel14 + if ((sourceL2Id > 0) && (destinationL2Id > 0)) + key = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(module_idP, rntiP, enb_flagP, channel_idP, sourceL2Id, destinationL2Id, srb_flag); +#endif } h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); @@ -199,7 +208,7 @@ tbs_size_t mac_rlc_data_req( break; case RLC_MODE_UM: - if (!enb_flagP) rlc_um_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.um,tb_sizeP); + if (!enb_flagP) rlc_um_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.um,tb_sizeP); data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um,enb_flagP); ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data); break; @@ -319,7 +328,12 @@ mac_rlc_status_resp_t mac_rlc_status_ind( const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, - const tb_size_t tb_sizeP) + const tb_size_t tb_sizeP +#ifdef Rel14 + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) { //----------------------------------------------------------------------------- mac_rlc_status_resp_t mac_rlc_status_resp; @@ -348,16 +362,26 @@ mac_rlc_status_resp_t mac_rlc_status_ind( key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id); } else { +#ifdef Rel14 + if ((sourceL2Id > 0) && (destinationL2Id > 0)) { + key = RLC_COLL_KEY_SOURCE_DEST_VALUE(module_idP, rntiP, enb_flagP, channel_idP, sourceL2Id, destinationL2Id, srb_flag); + } else +#endif + { + //LOG_I(RLC, "Panos-D mac_rlc_status_ind 1 enb_flagP: %d, channel_idP: %d, srb_flag: %d \n", enb_flagP, channel_idP, srb_flag); key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag); - } + } +} + //LOG_I(RLC, "Panos-D mac_rlc_status_ind 2 enb_flagP: %d, channel_idP: %d, srb_flag: %d \n", enb_flagP, channel_idP, srb_flag); h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); if (h_rc == HASH_TABLE_OK) { rlc_mode = rlc_union_p->mode; } else { rlc_mode = RLC_MODE_NONE; - //LOG_W(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP); + //LOG_D(RLC , "Panos-D: mac_rlc_status_ind() In RLC_MODE_NONE \n"); + //LOG_W(RLC , "[%s] RLC not configured lcid %u module %u!\n", __FUNCTION__, channel_idP, module_idP); //LOG_D(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP); } diff --git a/openair2/LAYER2/RLC/rlc_mpls.c b/openair2/LAYER2/RLC/rlc_mpls.c index 34e4f028aec13ccc4f6a234413cffca1791c0643..900741fe2672300f22522a07133b9ef280bed8de 100644 --- a/openair2/LAYER2/RLC/rlc_mpls.c +++ b/openair2/LAYER2/RLC/rlc_mpls.c @@ -40,6 +40,10 @@ rlc_op_status_t mpls_rlc_data_req ( { //----------------------------------------------------------------------------- // third arg should be set to 1 or 0 - return rlc_data_req(ctxtP, SRB_FLAG_NO, MBMS_FLAG_NO, rb_idP, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, sdu_sizeP, sduP); + return rlc_data_req(ctxtP, SRB_FLAG_NO, MBMS_FLAG_NO, rb_idP, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, sdu_sizeP, sduP +#ifdef Rel14 + ,NULL, NULL +#endif + ); } diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index f4acdb29df8c53aa32065a53e8e1c242f3a04f27..29bef668bd0e63f083ab204d1f5b01bb4ad142ad 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -39,19 +39,21 @@ #include "SRB-ToAddMod.h" #include "SRB-ToAddModList.h" #include "DL-UM-RLC.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "PMCH-InfoList-r9.h" #endif -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #include "assertions.h" //----------------------------------------------------------------------------- rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, const SRB_ToAddModList_t * const srb2add_listP, const DRB_ToAddModList_t * const drb2add_listP, const DRB_ToReleaseList_t * const drb2release_listP -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,const PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id #endif ) { @@ -66,7 +68,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP rlc_union_t *rlc_union_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) int i, j; MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; @@ -104,7 +106,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; case RLC_Config_PR_am: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_am_asn1 ( ctxt_pP, SRB_FLAG_YES, @@ -119,7 +126,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; case RLC_Config_PR_um_Bi_Directional: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_YES, @@ -128,7 +140,11 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP UNUSED_PARAM_MBMS_SERVICE_ID, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.ul_UM_RLC, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.dl_UM_RLC, - rb_id, lc_id); + rb_id, lc_id +#ifdef Rel14 + ,0, 0 +#endif + ); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), @@ -138,7 +154,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; case RLC_Config_PR_um_Uni_Directional_UL: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_YES, @@ -147,7 +168,11 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP UNUSED_PARAM_MBMS_SERVICE_ID, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_UL.ul_UM_RLC, NULL, - rb_id, lc_id); + rb_id, lc_id +#ifdef Rel14 + ,0, 0 +#endif + ); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), @@ -157,7 +182,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; case RLC_Config_PR_um_Uni_Directional_DL: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_YES, @@ -166,7 +196,11 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP UNUSED_PARAM_MBMS_SERVICE_ID, NULL, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_DL.dl_UM_RLC, - rb_id, lc_id); + rb_id, lc_id +#ifdef Rel14 + ,0, 0 +#endif + ); } else { LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", PROTOCOL_CTXT_ARGS(ctxt_pP), @@ -195,7 +229,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP config_am_pP->ul_AM_RLC.pollByte = PollByte_kBinfinity; config_am_pP->ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t4; - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_am_asn1 ( ctxt_pP, SRB_FLAG_YES, @@ -252,7 +291,6 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP LOG_D(RLC, "Adding DRB %ld, lc_id %d\n",drb_id,lc_id); - if (drb_toaddmod_p->rlc_Config) { switch (drb_toaddmod_p->rlc_Config->present) { @@ -260,7 +298,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; case RLC_Config_PR_am: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_AM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_AM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_am_asn1 ( ctxt_pP, SRB_FLAG_NO, @@ -271,7 +314,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; case RLC_Config_PR_um_Bi_Directional: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM +#ifdef Rel14 + ,sourceL2Id, + destinationL2Id +#endif + ) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_NO, @@ -280,13 +328,23 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP UNUSED_PARAM_MBMS_SERVICE_ID, &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.ul_UM_RLC, &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.dl_UM_RLC, - drb_id, lc_id); + drb_id, lc_id +#ifdef Rel14 + ,sourceL2Id, + destinationL2Id +#endif + ); } break; case RLC_Config_PR_um_Uni_Directional_UL: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_NO, @@ -295,13 +353,22 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP UNUSED_PARAM_MBMS_SERVICE_ID, &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_UL.ul_UM_RLC, NULL, - drb_id, lc_id); + drb_id, lc_id +#ifdef Rel14 + ,0, 0 +#endif + ); } break; case RLC_Config_PR_um_Uni_Directional_DL: - if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM) != NULL) { + if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { config_req_rlc_um_asn1( ctxt_pP, SRB_FLAG_NO, @@ -310,7 +377,11 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP UNUSED_PARAM_MBMS_SERVICE_ID, NULL, &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_DL.dl_UM_RLC, - drb_id, lc_id); + drb_id, lc_id +#ifdef Rel14 + ,0, 0 +#endif + ); } break; @@ -335,7 +406,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP } } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (pmch_InfoList_r9_pP != NULL) { for (i=0; i<pmch_InfoList_r9_pP->list.count; i++) { @@ -372,11 +443,11 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP MBMS_FLAG_YES, rb_id, lc_id, - RLC_MODE_UM); + RLC_MODE_UM, 0, 0); //AssertFatal(rlc_union_p != NULL, "ADD MBMS RLC UM FAILED"); - if(rlc_union_p == NULL){ - LOG_E(RLC, "ADD MBMS RLC UM FAILED\n"); - } + if(rlc_union_p == NULL){ + LOG_E(RLC, "ADD MBMS RLC UM FAILED\n"); + } } LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n", @@ -397,7 +468,11 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP mbms_service_id, NULL, &dl_um_rlc, - rb_id, lc_id); + rb_id, lc_id +#ifdef Rel14 + ,0, 0 +#endif + ); } } } @@ -481,14 +556,14 @@ rlc_op_status_t rrc_rlc_remove_rlc ( hash_key_t key_lcid = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_lcid_rc; rlc_union_t *rlc_union_p = NULL; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) rlc_mbms_id_t *mbms_id_p = NULL; #endif /* for no gcc warnings */ (void)lcid; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -578,19 +653,26 @@ rlc_union_t* rrc_rlc_add_rlc ( const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, const logical_chan_id_t chan_idP, - const rlc_mode_t rlc_modeP) + const rlc_mode_t rlc_modeP +#ifdef Rel14 + ,const uint32_t sourceL2Id, + const uint32_t destinationL2Id +#endif +) { + //----------------------------------------------------------------------------- hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; hash_key_t key_lcid = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_lcid_rc; rlc_union_t *rlc_union_p = NULL; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t lcid = 0; #endif + if (MBMS_flagP == FALSE) { //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); //AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); @@ -605,7 +687,7 @@ rlc_union_t* rrc_rlc_add_rlc ( } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -624,6 +706,10 @@ rlc_union_t* rrc_rlc_add_rlc ( } key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); + } + if ((sourceL2Id > 0) && (destinationL2Id > 0) ){ + key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, sourceL2Id, destinationL2Id, srb_flagP); + key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, sourceL2Id, destinationL2Id, srb_flagP); } else #endif { @@ -651,7 +737,7 @@ rlc_union_t* rrc_rlc_add_rlc ( h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p); if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { LOG_I(RLC, PROTOCOL_CTXT_FMT" RLC service id %u session id %u rrc_rlc_add_rlc\n", @@ -688,7 +774,6 @@ rlc_union_t* rrc_rlc_add_rlc ( rb_idP, (srb_flagP) ? "SRB" : "DRB"); } - return NULL; } //----------------------------------------------------------------------------- @@ -716,7 +801,12 @@ rlc_op_status_t rrc_rlc_config_req ( switch (actionP) { case CONFIG_ACTION_ADD: - if (rrc_rlc_add_rlc(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, rb_idP, rlc_infoP.rlc_mode) != NULL) { + if (rrc_rlc_add_rlc(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, rb_idP, rlc_infoP.rlc_mode +#ifdef Rel14 + ,0, + 0 +#endif + ) != NULL) { return RLC_OP_STATUS_INTERNAL_ERROR; } @@ -790,7 +880,11 @@ rlc_op_status_t rrc_rlc_data_req ( if (sdu != NULL) { memcpy (sdu->data, sduP, sdu_sizeP); - return rlc_data_req(ctxt_pP, SRB_FLAG_YES, MBMS_flagP, rb_idP, muiP, confirmP, sdu_sizeP, sdu); + return rlc_data_req(ctxt_pP, SRB_FLAG_YES, MBMS_flagP, rb_idP, muiP, confirmP, sdu_sizeP, sdu +#ifdef Rel14 + ,NULL, NULL +#endif + ); } else { return RLC_OP_STATUS_INTERNAL_ERROR; } diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index a3e8e2164a91dda95238a40076c0c962786aeb6d..0c884a806ce85d35b0d80fe0ee32e8598558de4c 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -32,8 +32,8 @@ #include <inttypes.h> #include "LAYER2/RLC/rlc.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "UTIL/LOG/log.h" #include "common/ran_context.h" @@ -217,18 +217,18 @@ int dump_eNB_l2_stats(char *buffer, int length) UE_list->eNB_UE_stats[CC_id][UE_id].num_errors_rx); len+= sprintf(&buffer[len],"[MAC] Received PHR PH = %d (db)\n", UE_list->UE_template[CC_id][UE_id].phr_info); - len+= sprintf(&buffer[len],"[MAC] Received BSR LCGID[0][1][2][3] = %u %u %u %u\n", - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID0], - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID1], - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID2], - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID3] + len+= sprintf(&buffer[len],"[MAC] Estimated size LCGID[0][1][2][3] = %u %u %u %u\n", + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID3] ); } PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, eNB_id, ENB_FLAG_YES, - UE_list->eNB_UE_stats[UE_PCCID(eNB_id,UE_id)][UE_id].crnti, + UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, eNB->frame, eNB->subframe, eNB_id); diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index 086ec3909ca225376d36cf520dca88f44aaf55d4..f8a420697a95d043d2f5870d2c55ca8279567ed5 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -241,7 +241,7 @@ int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -306,7 +306,7 @@ void nas_tx_timeout(struct net_device *dev) printk("TX_TIMEOUT: begin\n"); // (struct nas_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 netif_trans_update(dev); #else dev->trans_start = jiffies; diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 99712cc5d2fc7e749109280c01a59e808b1e28e1..e8ff5fc7ac66d9917f1624e0615a5ee94899e70a 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -248,6 +248,13 @@ ue_ip_common_ip2wireless( //--------------------------------------------------------------------------- struct pdcp_data_req_header_s pdcph; ue_ip_priv_t *priv_p=netdev_priv(ue_ip_dev[instP]); +#ifdef Rel14 + ipversion_t *ipv_p = NULL; + unsigned int hard_header_len = 0; + unsigned char *src_addr = 0; + unsigned char *dst_addr = 0; +#endif + #ifdef LOOPBACK_TEST int i; #endif @@ -278,6 +285,37 @@ ue_ip_common_ip2wireless( pdcph.inst = instP; + //pass source/destination IP addresses to PDCP header + hard_header_len = ue_ip_dev[instP]->hard_header_len; + ipv_p = (ipversion_t *)((void *)&(skb_pP->data[hard_header_len])); + + switch (ipv_p->version) { + case 6: + printk("[UE_IP_DRV][%s] receive IPv6 message\n",__FUNCTION__); + //TODO + break; + + case 4: + src_addr = (unsigned char *)&((struct iphdr *)&skb_pP->data[hard_header_len])->saddr; + if (src_addr) { + printk("[UE_IP_DRV][%s] Source %d.%d.%d.%d\n",__FUNCTION__, src_addr[0],src_addr[1],src_addr[2],src_addr[3]); + } + dst_addr = (unsigned char *)&((struct iphdr *)&skb_pP->data[hard_header_len])->daddr; + if (dst_addr) { + printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]); + } + + //get Ipv4 address and pass to PCDP header + printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id ); + printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id ); + pdcph.sourceL2Id = ntohl( ((struct iphdr *)&skb_pP->data[hard_header_len])->saddr) & 0x00FFFFFF; + pdcph.destinationL2Id = ntohl( ((struct iphdr *)&skb_pP->data[hard_header_len])->daddr) & 0x00FFFFFF; + break; + + default: + break; + } + bytes_wrote = ue_ip_netlink_send((char *)&pdcph,UE_IP_PDCPH_SIZE); #ifdef OAI_DRV_DEBUG_SEND diff --git a/openair2/NETWORK_DRIVER/UE_IP/constant.h b/openair2/NETWORK_DRIVER/UE_IP/constant.h index faff970dcdb3cb32e8ade1d2a3e8ee0cae1e3600..ccd992dd4ea63c7763cd56b61bace3be6961619b 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/constant.h +++ b/openair2/NETWORK_DRIVER/UE_IP/constant.h @@ -52,7 +52,7 @@ -#define UE_IP_NB_INSTANCES_MAX NUMBER_OF_UE_MAX +#define UE_IP_NB_INSTANCES_MAX NUMBER_OF_UE_MAX /*MAX_MOBILES_PER_ENB*/ #endif diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 29db4ae07a172f26e49dd14811420084f88816a7..36c6afe914bb3f16f8ab5367733d879d7b65f4c3 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -236,7 +236,7 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) // End debug information netif_stop_queue(dev_pP); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE >= 1796 netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; @@ -312,7 +312,7 @@ void ue_ip_tx_timeout(struct net_device *dev_pP) printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; (priv_p->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE >= 1796 netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; diff --git a/openair2/NETWORK_DRIVER/UE_IP/local.h b/openair2/NETWORK_DRIVER/UE_IP/local.h index ac3b0409954daab75466448b14a1727c94d76ada..976222967d326d885dc02288b12562e7bc953665 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/local.h +++ b/openair2/NETWORK_DRIVER/UE_IP/local.h @@ -89,6 +89,10 @@ typedef struct pdcp_data_req_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t traffic_type; +#ifdef Rel14 + uint32_t sourceL2Id; + uint32_t destinationL2Id; +#endif } pdcp_data_req_header_t; typedef struct pdcp_data_ind_header_s { @@ -96,6 +100,10 @@ typedef struct pdcp_data_ind_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t dummy_traffic_type; +#ifdef Rel14 + uint32_t sourceL2Id; + uint32_t destinationL2Id; +#endif } pdcp_data_ind_header_t; diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index 175fcb2e67f472463c66d65de42b14b56add155c..b8529d50369340127e2856de4b17a2db3711556d 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -1,8 +1,8 @@ -#include "openair1/PHY/defs.h" +#include "openair1/PHY/defs_eNB.h" #include "openair2/PHY_INTERFACE/IF_Module.h" -#include "openair1/PHY/extern.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/proto.h" +#include "openair1/PHY/phy_extern.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" #include "common/ran_context.h" #define MAX_IF_MODULES 100 @@ -33,13 +33,13 @@ void handle_rach(UL_IND_t *UL_info) { UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif ); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (UL_info->rach_ind_br.rach_indication_body.number_of_preambles>0) { AssertFatal(UL_info->rach_ind_br.rach_indication_body.number_of_preambles<5,"More than 4 preambles not supported\n"); diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 7baae6c3b6f8e09c9eef43a77a207ac3989f99c5..0390a9055179d236615b399b9717b6f021c369e4 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -3,7 +3,7 @@ * 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 + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -34,9 +34,10 @@ #include <stdint.h> -#include "openair1/PHY/LTE_TRANSPORT/defs.h" +//#include "openair1/PHY/LTE_TRANSPORT/transport_eNB.h" #include "nfapi_interface.h" - +#include "platform_constants.h" +#include "platform_types.h" #define MAX_NUM_DL_PDU 100 #define MAX_NUM_UL_PDU 100 @@ -75,7 +76,7 @@ typedef struct{ /// RACH indication list nfapi_rach_indication_t rach_ind; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// RACH indication list for BR UEs nfapi_rach_indication_t rach_ind_br; #endif diff --git a/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..479bd47d947d0c2fd79c96b84c72badf21557712 --- /dev/null +++ b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h @@ -0,0 +1,215 @@ + +/*This is the interface module between PHY +*Provided the FAPI style interface structures for P7. +*Provide the semi-FAPI style interface for P5 (configuration) +* +*/ + +#ifndef __IF_MODULE_NB_IoT__H__ +#define __IF_MODULE_NB_IoT__H__ + +#include "nfapi_interface.h" +//#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include "PhysicalConfigDedicated-NB-r13.h" +//#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "openair2/COMMON/platform_types.h" +//#include "openair1/SCHED/IF_Module_L1_primitives_NB_IoT.h" + +//#define SCH_PAYLOAD_SIZE_MAX 4096 +#define BCCH_PAYLOAD_SIZE_MAX_NB_IoT 128 + + + +// P5 FAPI-like configuration structures------------------------------------------------------------------------------- + +/*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS + * some of them may not needed because are used only at UE side + * some of them are not needed because not necessary at PHY level + * other have to be clarified since seems to be needed at PHY layer + * there is no UE_Config. request message carrying NB-IoT parameters??? + * + * */ +typedef struct{ + //nprach_config + uint16_t nprach_config_0_subcarrier_MSG3_range_start; + uint16_t nprach_config_1_subcarrier_MSG3_range_start; + uint16_t nprach_config_2_subcarrier_MSG3_range_start; + uint16_t nprach_config_0_max_num_preamble_attempt_CE; + uint16_t nprach_config_1_max_num_preamble_attempt_CE; + uint16_t nprach_config_2_max_num_preamble_attempt_CE; + uint16_t nprach_config_0_npdcch_num_repetitions_RA; //Rmax (see TS 36.213 ch 16.6) -->only this is managed at PHY layer + uint16_t nprach_config_1_npdcch_num_repetitions_RA; + uint16_t nprach_config_2_npdcch_num_repetitions_RA; + uint16_t nprach_config_0_npdcch_startSF_CSS_RA; //G (see TS 36.213 ch 16.6) + uint16_t nprach_config_1_npdcch_startSF_CSS_RA; + uint16_t nprach_config_2_npdcch_startSF_CSS_RA; + uint16_t nprach_config_0_npdcch_offset_RA; //Alfa_offset (see TS 36.213 ch 16.6) + uint16_t nprach_config_1_npdcch_offset_RA; + uint16_t nprach_config_2_npdcch_offset_RA; + + //configured through the phy_config_dedicated + //Higher layer parameter for NPDCCH UE-spec search space + uint16_t npdcch_NumRepetitions;//Rmax (see TS 36.213 ch 16.6) -->only this is managed at PHY layer + uint16_t npdcch_StartSF_USS; //G (see TS 36.213 ch 16.6) + uint16_t npdcch_Offset_USS; //Alfa_offset (see TS 36.213 ch 16.6) + + + ACK_NACK_NumRepetitions_NB_r13_t *ack_nack_numRepetitions_MSG4; //pointer to the first cell of a list of ack_nack_num_repetitions + + //ulPowerControlCommon (UE side) + uint16_t p0_nominal_npusch; + uint16_t alpha; + uint16_t delta_preamle_MSG3; + + + /*Dedicated configuration -->not supported by FAPI (may not needed) + * In OAI at least are needed when we manage the phy_procedures_eNB_TX in which we call the phy_config_dedicated_eNB_step2 + * that use the physicalConfigDedicated info previously stored in the PHY_VARS_eNB_NB_IoT structure through the phy_config_dedicated procedure + */ + //PhysicalConfigDedicated_NB_r13_t *phy_config_dedicated; + + + + +}extra_phyConfig_t; + +typedef struct{ + + /*OAI config. parameters*/ + module_id_t mod_id; + int CC_id; + uint16_t rnti; + int get_MIB; //should be different from 0 only when the mib!= null (NB_rrc_mac_config_req_eNB_IoT) + int get_COMMON; + int get_DEDICATED; + + //ID of the Resource Block dedicated to NB-IoT + //For Nb-IoT only a restricted values of PRB indexes are allowed (see Rhode&Shwartz pag9) + //unsigned short NB_IoT_RB_ID; (should coincide with PRB index) + + + + + /*FAPI useful config. parameters used in the code + * + * -nfapi_uplink_reference_signal_config_t uplink_reference_signal_config + * -nfapi_subframe_config_t subframe_config; + * -nfapi_rf_config_t rf_config; + * -nfapi_sch_config_t sch_config; + * -nfapi_nb_iot_config_t config_NB_IoT; + * -nfapi_l23_config_t l23_config; + * -nfapi_config --> EARFCN (for the transport of the dl_CarrierFreq + * */ + + //XXX where allocate memory?? + nfapi_config_request_t* cfg; + + /*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS (may non needed)*/ + extra_phyConfig_t extra_phy_parms; + +}PHY_Config_NB_IoT_t; + + + +// uplink subframe P7--------------------------------------------------------------------------------- + + +/*UL_IND_t: +* A structure handles all the uplink information. +* Corresponding to the NRACH.indicaiton, UL_Config_indication, RX_ULSCH.indication, CRC.inidcation, NB_HARQ.indication in FAPI +*/ +typedef struct{ + + /*Start at the common part*/ + + int test; + + //Module ID + module_id_t module_id; + //CC ID + int CC_id; + //frame + frame_t frame; + //subframe + sub_frame_t subframe; + //Hyper frame for NB-IoT implementation + uint32_t hypersfn; + + /*preamble part*/ + + nfapi_nrach_indication_body_t NRACH; + + /*Uplink data part*/ + + /*indication of the harq feedback*/ + nfapi_nb_harq_indication_t nb_harq_ind; + /*indication of the uplink data PDU*/ + nfapi_rx_indication_body_t RX_NPUSCH; + /*crc_indication*/ + nfapi_crc_indication_body_t crc_ind; + + }UL_IND_NB_IoT_t; + + // Downlink subframe P7 + + +typedef struct{ + + /*Start at the common part*/ + + //Module ID + module_id_t module_id; + //CC ID + int CC_id; + // hyper subframe + uint32_t hypersfn; + //frame + frame_t frame; + //subframe + sub_frame_t subframe; + + /// nFAPI DL Config Request + nfapi_dl_config_request_t *DL_req; + /// nFAPI UL Config Request + nfapi_ul_config_request_t *UL_req; + /// nFAPI HI_DCI Request + nfapi_hi_dci0_request_t *HI_DCI0_req; + /// nFAPI TX Request + nfapi_tx_request_t *TX_req; + /// Pointers to DL SDUs + //uint8_t **sdu; + +}Sched_Rsp_NB_IoT_t; + + +/*IF_Module_t a group for gathering the Interface +It should be allocated at the main () in lte-softmodem.c*/ +typedef struct IF_Module_NB_IoT_s{ + //define the function pointer + void (*UL_indication)(UL_IND_NB_IoT_t *UL_INFO); + void (*schedule_response)(Sched_Rsp_NB_IoT_t *Sched_INFO); + void (*PHY_config_req)(PHY_Config_NB_IoT_t* config_INFO); +}IF_Module_NB_IoT_t; + +/*Initial */ + +/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ +void schedule_response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO); + +/*Interface for PHY Configuration + * Trigger the phy_config_xxx functions using parameters from the shared PHY_Config structure + * */ +void PHY_config_req_NB_IoT(PHY_Config_NB_IoT_t* config_INFO); + +//int IF_Module_init(IF_Module_t *if_inst); + +/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ +//void Schedule_Response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO); + +/*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler) +*/ +void UL_indication_NB_IoT(UL_IND_NB_IoT_t *UL_INFO); + +IF_Module_NB_IoT_t *IF_Module_init_NB_IoT(int Mod_id); + +#endif diff --git a/openair2/PHY_INTERFACE/UE_MAC_interface.h b/openair2/PHY_INTERFACE/UE_MAC_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..0e4777d0b028cf0e5af141fc23a538e77448503f --- /dev/null +++ b/openair2/PHY_INTERFACE/UE_MAC_interface.h @@ -0,0 +1,498 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +/* This is the interface module between PHY + * Provided the FAPI style interface structures for P7. + */ + +/*! \file openair2/PHY_INTERFACE/IF_Module.h +* \brief data structures for PHY/MAC interface modules +* \author EURECOM/NTUST +* \date 2017 +* \version 0.1 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr +* \note +* \warning +*/ +#ifndef __UE_MAC_INTERFACE__H__ +#define __UE_MAC_INTERFACE__H__ + +#include "nfapi_interface.h" +#include "openair1/PHY/impl_defs_lte.h" +#include "targets/COMMON/openairinterface5g_limits.h" + + + +#define MAX_NUM_DL_PDU 100 +#define MAX_NUM_UL_PDU 100 +#define MAX_NUM_HI_DCI0_PDU 100 +#define MAX_NUM_TX_REQUEST_PDU 100 + +#define MAX_NUM_HARQ_IND 100 +#define MAX_NUM_CRC_IND 100 +#define MAX_NUM_SR_IND 100 +#define MAX_NUM_CQI_IND 100 +#define MAX_NUM_RACH_IND 100 +#define MAX_NUM_SRS_IND 100 + + +// UE_MAC enums +typedef enum { + UE_MAC_DL_IND_PDSCH_PDU_TYPE =0, + UE_MAC_DL_IND_SI_PDSCH_PDU_TYPE, + UE_MAC_DL_IND_P_PDSCH_PDU_TYPE, + UE_MAC_DL_IND_DLSCH_RAR_PDU_TYPE +} UE_MAC_dl_ind_pdu_type_e; + +// UE_MAC enums +typedef enum { + UE_MAC_Tx_IND_Msg1_TYPE =0, + UE_MAC_Tx_IND_Msg3_TYPE +} UE_MAC_Tx_ind_type_e; + + + +// *** UE_UL_Config.request related structures + + +typedef struct{ + //module_id_t module_idP; + //int CC_id; + //frame_t frameP; + uint8_t eNB_id; + //uint16_t rnti; + //sub_frame_t subframe_tx; + uint32_t SR_payload; //0 or 1 +}UE_MAC_ul_config_SR; + + + +typedef struct{ + //module_id_t module_idP; + //int CC_id; + //frame_t frameP; + uint8_t eNB_indexP; + //sub_frame_t subframeP; + + uint8_t ra_RACH_MaskIndex; + int8_t ra_PREAMBLE_RECEIVED_TARGET_POWER; + uint8_t ra_TDD_map_index; + uint16_t ra_RNTI; + uint8_t *Msg3; +}UE_MAC_ul_config_rach; + +typedef struct { + union { + UE_MAC_ul_config_rach ue_rach_config; + //UE_MAC_ul_config_ULSCH ue_ULSCH_pdu; + UE_MAC_ul_config_SR ue_SR_config; + }; +} UE_MAC_ul_config_request_list; + +typedef struct { + nfapi_tl_t tl; + uint16_t length_list; + UE_MAC_ul_config_request_list* ue_ul_config_list; +} UE_MAC_ul_config_request_body_t; + +typedef struct { + //nfapi_p7_message_header_t header; + uint16_t sfn_sf; + UE_MAC_ul_config_request_body_t ue_ul_config_request_body; //nfapi_dl_config_request_body_t +} UE_MAC_ul_config_request_t; + + + + + + + + + +// *** UE_Tx.request related structures + +typedef struct { + uint16_t pdu_length; + uint16_t pdu_index; + uint8_t num_segments; + struct { + uint32_t segment_length; + uint8_t* segment_data; + } segments[NFAPI_TX_MAX_SEGMENTS]; +} UE_MAC_tx_request_pdu_t; + + +typedef struct { + nfapi_tl_t tl; + uint16_t number_of_pdus; + UE_MAC_tx_request_pdu_t* ue_tx_pdu_list; +} UE_MAC_tx_request_body_t; + + +typedef struct { + //nfapi_p7_message_header_t header; + uint16_t sfn_sf; + UE_MAC_tx_request_body_t ue_tx_request_body; +} UE_MAC_tx_request_t; + + +typedef struct{ + + +}UE_MAC_sl_config_request_Tx_t; + +typedef struct{ + + +}UE_MAC_sl_config_request_Rx_t; + + +typedef struct{ + + +}UE_MAC_sl_tx_request_t; + + + + + + +// *** UE_DL.indication related structures + +typedef struct{ + unsigned char eNB_index; + uint8_t first_sync; //boolean 0 or 1 + uint8_t sync; // boolean 0 or 1 to indicate whether rrc_out_of_sync_ind() or dl_phy_sync_success() + // should be called from the handler function of the interface respectively. +}UE_MAC_bch_indication_pdu_t; + + +typedef struct{ + nfapi_tl_t tl; + UE_MAC_bch_indication_pdu_t* bch_ind_list; +}UE_MAC_BCH_indication_body_t; + + +// Panos: Corresponding to inputs of MAC functions: ue_send_sdu(), ue_decode_si(), ue_decode_p(). +typedef struct{ + uint8_t* data; + uint16_t data_len; +}UE_MAC_dlsch_pdu; + + +// Panos: Corresponding to inputs of MAC function: process_rar(). +typedef struct{ + rnti_t ra_rnti; + uint8_t* rar_input_buffer; // Originating from PHY + rnti_t* t_crnti; + uint8_t preamble_index; + uint8_t* rar_output_buffer; //should be returned to PHY: dlsch0->harq_processes[0]->b +}UE_MAC_dlsch_rar_pdu; + + +typedef struct{ + uint8_t pdu_type; + uint8_t eNB_index; + union{ + UE_MAC_dlsch_pdu dlsch_pdu_ind; + UE_MAC_dlsch_rar_pdu dlsch_rar_pdu_ind; + }; +}UE_MAC_dlsch_indication_pdu_t; + + +typedef struct{ + nfapi_tl_t tl; + uint16_t number_of_pdus; + UE_MAC_dlsch_indication_pdu_t* dlsch_ind_list; +}UE_MAC_DLSCH_indication_body_t; + + + + + + +// *** UE_SL.indication related structures + +typedef struct{ + +}ue_sci_indication_body_t; + + +typedef struct{ + +}ue_SLSCH_indication_body_t; + + +typedef struct{ + +}ue_SLDCH_indication_body_t; + +typedef struct{ + +}ue_SLBCH_indication_body_t; + + +// *** UE_Config_common.request related structures + +typedef struct { + uint8_t subframeAssignment; + uint8_t specialSubframePatterns; +}UE_PHY_tdd_frame_structure_t; + + +typedef struct { + uint16_t rootSequenceIndex; + uint8_t prach_Config_enabled; + uint8_t prach_ConfigIndex; + uint8_t highSpeedFlag; + uint8_t zeroCorrelationZoneConfig; + uint8_t prach_FreqOffset; +}UE_PHY_prach_config_t; + +typedef struct { + uint8_t deltaPUCCH_Shift; + uint8_t nRB_CQI; + uint8_t nCS_AN; + uint16_t n1PUCCH_AN; +}UE_PHY_pucch_config_t; + + +typedef struct { + int8_t referenceSignalPower; + uint8_t p_b; +}UE_PHY_pdsch_config_t; + + +typedef struct { + uint8_t n_SB; + PUSCH_HOPPING_t hoppingMode; + uint8_t pusch_HoppingOffset; + uint8_t enable64QAM; + uint8_t groupHoppingEnabled; + uint8_t groupAssignmentPUSCH; + uint8_t sequenceHoppingEnabled; + uint8_t cyclicShift; +}UE_PHY_pusch_config_t; + + +typedef struct{ + uint8_t enabled_flag; + uint8_t srs_BandwidthConfig; + uint8_t srs_SubframeConfig; + uint8_t ackNackSRS_SimultaneousTransmission; + uint8_t srs_MaxUpPts; +}UE_PHY_SRS_config_t; + +typedef struct{ + int8_t p0_NominalPUSCH; + PUSCH_alpha_t alpha; + int8_t p0_NominalPUCCH; + int8_t deltaPreambleMsg3; + long deltaF_PUCCH_Format1; + long deltaF_PUCCH_Format1b; + long deltaF_PUCCH_Format2; + long deltaF_PUCCH_Format2a; + long deltaF_PUCCH_Format2b; +}UE_PHY_UL_power_control_config_t; + + +typedef struct{ + uint8_t maxHARQ_Msg3Tx; +}UE_PHY_HARQ_Msg3_config_t; + +typedef struct{ + uint8_t nb_antennas_tx; +}UE_PHY_antenna_config_t; + +typedef struct{ + PHICH_RESOURCE_t phich_resource; + PHICH_DURATION_t phich_duration; +}UE_PHY_phich_config_t; + + +typedef struct { + UE_PHY_tdd_frame_structure_t ue_tdd_frame_structure_config; + UE_PHY_prach_config_t ue_prach_config; + UE_PHY_pucch_config_t ue_pucch_config; + UE_PHY_pdsch_config_t ue_pdsch_config; + UE_PHY_pusch_config_t ue_pusch_config; + UE_PHY_SRS_config_t ue_srs_config; + UE_PHY_UL_power_control_config_t ue_ul_pow_cntl_config; + UE_PHY_HARQ_Msg3_config_t ue_harq_msg3_config; + /* Where can we find the types and values of the configuration for the PCH? + UE_MAC_pusch_config_t ue_pch_config + radioResourceConfigCommon->pcch_Config.defaultPagingCycle, radioResourceConfigCommon->pcch_Config.nB*/ + UE_PHY_antenna_config_t ue_ant_config; + UE_PHY_phich_config_t ue_phich_config; + /* MBSFN?*/ +}UE_PHY_config_common_request_t; + + + + + + + +// *** UE_Config_dedicated. request related structures + +typedef struct{ + PA_t p_a; +}UE_PHY_pdsch_config_dedicated_t; + + +typedef struct{ + uint8_t ackNackRepetition; + ANFBmode_t tdd_AckNackFeedbackMode; + //ACKNAKREP_t repetitionFactor; + //uint16_t n1PUCCH_AN_Rep; +}UE_PHY_pucch_config_dedicated_t; + + +typedef struct{ + uint16_t betaOffset_ACK_Index; + uint16_t betaOffset_RI_Index; + uint16_t betaOffset_CQI_Index; +}UE_PHY_pusch_config_dedicated_t; + + +typedef struct{ + int8_t p0_UE_PUSCH; + uint8_t deltaMCS_Enabled; + uint8_t accumulationEnabled; + int8_t p0_UE_PUCCH; + int8_t pSRS_Offset; + uint8_t filterCoefficient; +}UE_PHY_ul_power_control_config_dedicated_t; + + +typedef struct{ + uint16_t sr_PUCCH_ResourceIndex; + uint8_t sr_ConfigIndex; + DSR_TRANSMAX_t dsr_TransMax; +}UE_PHY_SR_config_dedicated_t; + + +typedef struct{ + uint8_t srsConfigDedicatedSetup; + uint8_t duration; + uint8_t cyclicShift; + uint8_t freqDomainPosition; + uint8_t srs_Bandwidth; + uint16_t srs_ConfigIndex; + uint8_t srs_HoppingBandwidth; + uint8_t transmissionComb; + //uint8_t srsCellSubframe; + //uint8_t srsUeSubframe; +}UE_PHY_srs_ul_config_dedicated_t; + + +typedef struct{ + CQI_REPORTMODEAPERIODIC cqi_ReportModeAperiodic; + CQI_REPORTPERIODIC CQI_ReportPeriodic; + //int8_t nomPDSCH_RS_EPRE_Offset; +}UE_PHY_cqi_report_config_dedicated_t; + + + +typedef struct{ + uint8_t transmission_mode [NUMBER_OF_CONNECTED_eNB_MAX]; + UE_PHY_pdsch_config_dedicated_t ue_pdsch_config; + UE_PHY_pucch_config_dedicated_t ue_pucch_config; + UE_PHY_pusch_config_dedicated_t ue_pusch_config; + UE_PHY_ul_power_control_config_dedicated_t ue_ul_pow_cntrl_config; + UE_PHY_SR_config_dedicated_t ue_SR_config; + UE_PHY_srs_ul_config_dedicated_t ue_srs_ul_config; + UE_PHY_cqi_report_config_dedicated_t ue_cqi_report_config; +}UE_PHY_config_dedicated_request_t; + +#endif + + + + + + + + + + + + + + + + + + + +/* +typedef struct { + nfapi_p4_p5_message_header_t header; + uint8_t num_tlv; + nfapi_subframe_config_t subframe_config; + nfapi_rf_config_t rf_config; + nfapi_phich_config_t phich_config; + nfapi_sch_config_t sch_config; + nfapi_prach_config_t prach_config; + nfapi_pusch_config_t pusch_config; + nfapi_pucch_config_t pucch_config; + nfapi_srs_config_t srs_config; + nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; + nfapi_laa_config_t laa_config; + nfapi_emtc_config_t emtc_config; + nfapi_tdd_frame_structure_t tdd_frame_structure_config; + nfapi_l23_config_t l23_config; + nfapi_nb_iot_config_t nb_iot_config; + + // addition nfapi tlvs as per table 2-16 in idle or configure + nfapi_nfapi_t nfapi_config; + + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_config_request_t; + + + + + +typedef struct { + nfapi_tl_t tl; + uint8_t dci_format; + uint8_t cce_index; + uint8_t aggregation_level; + uint16_t rnti; + uint8_t resource_block_start; + uint8_t number_of_resource_block; + uint8_t mcs_1; + uint8_t cyclic_shift_2_for_drms; + uint8_t frequency_hopping_enabled_flag; + uint8_t frequency_hopping_bits; + uint8_t new_data_indication_1; + uint8_t ue_tx_antenna_seleciton; + uint8_t tpc; + uint8_t cqi_csi_request; + uint8_t ul_index; + uint8_t dl_assignment_index; + uint32_t tpc_bitmap; + uint16_t transmission_power; +} nfapi_hi_dci0_dci_pdu_rel8_t; + +*/ diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h deleted file mode 100644 index deb07443f18fcddf3a1555821fece15ca0acd7c4..0000000000000000000000000000000000000000 --- a/openair2/PHY_INTERFACE/defs.h +++ /dev/null @@ -1,373 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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_INTERFACE/defs.h -* \brief mac phy interface primitives -* \author Raymond Knopp and Navid Nikaein -* \date 2011 -* \version 0.5 -* \mail navid.nikaein@eurecom.fr or openair_tech@eurecom.fr -*/ - -#ifndef __MAC_PHY_PRIMITIVES_H__ -# define __MAC_PHY_PRIMITIVES_H__ - -#include "LAYER2/MAC/defs.h" - - -#define MAX_NUMBER_OF_MAC_INSTANCES 16 - -#define NULL_PDU 255 -#define DCI 0 -#define DLSCH 1 -#define ULSCH 2 - -#define mac_exit_wrapper(sTRING) \ -do { \ - char temp[300]; \ - snprintf(temp, sizeof(temp), "%s in file "__FILE__" at line %d\n", sTRING, __LINE__); \ - mac_xface->macphy_exit(temp); \ -} while(0) - -/** @defgroup _phy_if MAC-PHY interface - * @ingroup _oai2 - * @{ - */ -/*! \brief MACPHY Interface */ -/* -typedef struct { - /// Pointer function that initializes L2 - int (*macphy_init)(int eMBMS_active, char *uecap_xer, uint8_t CBA_active,uint8_t HO_active); - - /// Pointer function that stops the low-level scheduler due an exit condition - void (*macphy_exit)(const char *); - - // eNB functions - /// Invoke dlsch/ulsch scheduling procedure for new subframe - void (*eNB_dlsch_ulsch_scheduler)(module_id_t Mod_id,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP);//, int calibration_flag); - - /// Fill random access response sdu, passing timing advance - uint16_t (*fill_rar)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t N_RB_UL, uint8_t input_buffer_length); - - /// Initiate the RA procedure upon reception (hypothetical) of a valid preamble - void (*initiate_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t preamble,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id); - - /// cancel an ongoing RA procedure - void (*cancel_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t preamble); - - /// Inform MAC layer that an uplink is scheduled for Msg3 in given subframe. - /// This is used so that the MAC scheduler marks as busy the RBs used by the Msg3. - void (*set_msg3_subframe)(module_id_t Mod_id, - int CC_id, - int frame, - int subframe, - int rnti, - int Msg3_frame, - int Msg3_subframe); - - /// Get DCI for current subframe from MAC - DCI_PDU* (*get_dci_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe); - - /// Get DLSCH sdu for particular RNTI and Transport block index - uint8_t* (*get_dlsch_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TB_index); - - /// Send ULSCH sdu to MAC for given rnti - void (*rx_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP, sub_frame_t sub_frameP,rnti_t rnti, uint8_t *sdu,uint16_t sdu_len, int harq_pid,uint8_t *msg3_flag); - - /// Indicate failure to synch to external source - void (*mrbch_phy_sync_failure) (module_id_t Mod_id,frame_t frameP, uint8_t free_eNB_index); - - /// Indicate Scheduling Request from UE - void (*SR_indication)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe); - /// Indicate UL Failure to eNodeB MAC - void (*UL_failure_indication)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe); - - /// Configure Common PHY parameters from SIB1 - void (*phy_config_mib_eNB)(module_id_t Mod_id,int CC_id, - int eutra_band, - int N_RB_DL, - PHICH_Config_t *phich_Config, - int Nid_cell, - int Ncp, - int p_eNB, - uint32_t dl_CarrierFreq, - uint32_t ul_CarrierFreq); - - /// Configure Common PHY parameters from SIB1 - void (*phy_config_sib1_eNB)(module_id_t Mod_id,int CC_id, - TDD_Config_t *tdd_config, - uint8_t SIwindowsize, - uint16_t SIperiod); - - /// Configure Common PHY parameters from SIB2 - void (*phy_config_sib2_eNB)(module_id_t Mod_id, int CC_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CArrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); - -#if defined(Rel10) || defined(Rel14) - /// Configure Common PHY parameters from SIB13 - void (*phy_config_sib13_eNB)(module_id_t Mod_id,int CC_id, int mbsfn_Area_idx, - long mbsfn_AreaId_r9); - - void (*phy_config_dedicated_scell_eNB)(uint8_t Mod_id, - uint16_t rnti, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id); -#endif - - /// PHY-Config-Dedicated eNB - void (*phy_config_dedicated_eNB)(module_id_t Mod_id,int CC_id,rnti_t rnti, - struct PhysicalConfigDedicated *physicalConfigDedicated); - -#if defined(Rel10) || defined(Rel14) - /// Get MCH sdu and corresponding MCS for particular MBSFN subframe - MCH_PDU* (*get_mch_sdu)(module_id_t Mod_id, int CC_id, frame_t frameP,sub_frame_t subframe); -#endif - // configure the cba rnti at the physical layer - void (*phy_config_cba_rnti)(module_id_t Mod_id,int CC_id,eNB_flag_t eNB_flag, uint8_t index, uint16_t cba_rnti, uint8_t cba_group_id, uint8_t num_active_cba_groups); - /// get delta mcs for fast UL AMC - int16_t (*estimate_ue_tx_power)(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs); - - int (*mac_phy_remove_ue)(module_id_t Mod_idP,rnti_t rntiP); - /// UE functions - - /// reset the ue phy - void (*phy_reset_ue)(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); - - /// Indicate loss of synchronization of PBCH for this eNB to MAC layer - void (*out_of_sync_ind)(module_id_t Mod_id,frame_t frameP,uint16_t eNB_index); - - /// Send a received SI sdu - void (*ue_decode_si)(module_id_t Mod_id,int CC_id,frame_t frameP, uint8_t CH_index, void *pdu, uint16_t len); - - /// Send a received Paging sdu - void (*ue_decode_p)(module_id_t Mod_id,int CC_id,frame_t frameP, uint8_t CH_index, void *pdu, uint16_t len); - - /// Send a received DLSCH sdu to MAC - void (*ue_send_sdu)(module_id_t Mod_id,uint8_t CC_id,frame_t frameP,sub_frame_t subframe,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); - -#if defined(Rel10) || defined(Rel14) - /// Send a received MCH sdu to MAC - void (*ue_send_mch_sdu)(module_id_t Mod_id,uint8_t CC_id, frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t eNB_index,uint8_t sync_area); - - /// Function to check if UE PHY needs to decode MCH for MAC - /// get the sync area id, and return MCS value if need to decode, otherwise -1 - int (*ue_query_mch)(module_id_t Mod_id, uint8_t CC_id,frame_t frameP,sub_frame_t subframe,uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active); -#endif - - /// Retrieve ULSCH sdu from MAC - void (*ue_get_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe, uint8_t CH_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode); - - /// Retrieve RRCConnectionReq from MAC - PRACH_RESOURCES_t* (*ue_get_rach)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t Msg3_flag,sub_frame_t subframe); - - /// Process Random-Access Response - uint16_t (*ue_process_rar)(module_id_t Mod_id,int CC_id,frame_t frameP, uint16_t ra_rnti, uint8_t *dlsch_buffer, uint16_t *t_crnti,uint8_t preamble_index, uint8_t* selected_rar_buffer); - - /// Get SR payload (0,1) from UE MAC - uint32_t (*ue_get_SR)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe); - - /// Indicate synchronization with valid PBCH - void (*dl_phy_sync_success) (module_id_t Mod_id,frame_t frameP, uint8_t CH_index,uint8_t first_sync); - - /// Only calls the PDCP for now - UE_L2_STATE_t (*ue_scheduler)(module_id_t Mod_id, frame_t rxFrameP,sub_frame_t rxSubframe, frame_t txFrameP,sub_frame_t txSubframe, lte_subframe_t direction, uint8_t eNB_id, int CC_id); - - /// PHY-Config-Dedicated UE - void (*phy_config_dedicated_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index, - struct PhysicalConfigDedicated *physicalConfigDedicated); - - /// PHY-Config-harq UE - void (*phy_config_harq_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index, - uint16_t max_harq_tx); - /// Configure Common PHY parameters from SIB1 - void (*phy_config_sib1_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index, - TDD_Config_t *tdd_config, - uint8_t SIwindowsize, - uint16_t SIperiod); - - /// Configure Common PHY parameters from SIB2 - void (*phy_config_sib2_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CArrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); - -#if defined(Rel10) || defined(Rel14) - /// Configure Common PHY parameters from SIB13 - void (*phy_config_sib13_ue)(uint8_t Mod_id,int CC_id, uint8_t eNB_index,int mbsfn_Area_idx, - long mbsfn_AreaId_r9); - - void (*phy_config_dedicated_scell_ue)(uint8_t Mod_id, - uint8_t eNB_index, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id); -#endif - /// Configure Common PHY parameters from mobilityControlInfo - void (*phy_config_afterHO_ue)(module_id_t Mod_id,uint8_t CC_id,uint8_t CH_index, - MobilityControlInfo_t *mobilityControlInfo, - uint8_t ho_failed); - - /// Function to indicate failure of contention resolution or RA procedure - void (*ra_failed)(module_id_t Mod_id, uint8_t CC_id,uint8_t eNB_index); - - /// Function to indicate success of contention resolution or RA procedure - void (*ra_succeeded)(module_id_t Mod_id,uint8_t CC_id, uint8_t eNB_index); - - /// Function to indicate the transmission of msg1/rach to MAC - void (*Msg1_transmitted)(module_id_t Mod_id,uint8_t CC_id,frame_t frameP,uint8_t eNB_id); - - /// Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer - void (*Msg3_transmitted)(module_id_t Mod_id,uint8_t CC_id,frame_t frameP,uint8_t eNB_id); - - /// Function to pass inter-cell measurement parameters to PHY (cell Ids) - void (*phy_config_meas_ue)(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,uint32_t *adj_cell_id); - - // PHY Helper Functions - - /// RIV computation from PHY - uint16_t (*computeRIV)(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); - - /// Downlink TBS table lookup from PHY - uint32_t (*get_TBS_DL)(uint8_t mcs, uint16_t nb_rb); - - /// Uplink TBS table lookup from PHY - uint32_t (*get_TBS_UL)(uint8_t mcs, uint16_t nb_rb); - - /// Function to retrieve the HARQ round index for a particular UL/DLSCH and harq_pid - int (*get_ue_active_harq_pid)(module_id_t Mod_id, uint8_t CC_id,rnti_t rnti, int frame, uint8_t subframe, uint8_t *harq_pid, uint8_t *round, uint8_t ul_flag); - - /// Function to retrieve number of CCE - uint16_t (*get_nCCE_max)(module_id_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe); - - - int (*get_nCCE_offset)(int *CCE_table, - const unsigned char L, - const int nCCE, - const int common_dci, - const unsigned short rnti, - const unsigned char subframe); - - /// Function to retrieve number of PRB in an rb_alloc - uint32_t (*get_nb_rb)(uint8_t ra_header, uint32_t rb_alloc, int n_rb_dl); - - /// Function to convert VRB to PRB for distributed allocation - uint32_t (*get_prb)(int N_RB_DL,int odd_slot,int vrb,int Ngap); - - /// Function to retrieve transmission mode for UE - uint8_t (*get_transmission_mode)(module_id_t Mod_id,uint8_t CC_id,rnti_t rnti); - - /// Function to retrieve rb_alloc bitmap from dci rballoc field and VRB type - uint32_t (*get_rballoc)(vrb_t vrb_type, uint16_t rb_alloc_dci); - - /// Function for UE MAC to retrieve current PHY connectivity mode (PRACH,RA_RESPONSE,PUSCH) - UE_MODE_t (*get_ue_mode)(module_id_t Mod_id, uint8_t CC_id,uint8_t eNB_index); - - /// Function for UE MAC to retrieve measured Path Loss - int16_t (*get_PL)(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); - - /// Function for UE MAC to retrieve the rssi - uint32_t (*get_RSSI)(uint8_t Mod_id,uint8_t CC_id); - - /// Function for UE MAC to retrieve the total gain - uint32_t (*get_rx_total_gain_dB)(uint8_t Mod_id,uint8_t CC_id); - - /// Function for UE MAC to retrieve the number of adjustent cells - uint8_t (*get_n_adj_cells)(uint8_t Mod_id,uint8_t CC_id); - - /// Function for UE MAC to retrieve RSRP/RSRQ measurements - uint32_t (*get_RSRP)(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); - - /// Function for UE MAC to retrieve RSRP/RSRQ measurements - uint32_t (*get_RSRQ)(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); - - /// Function for UE MAC to set the layer3 filtered RSRP/RSRQ measurements - uint8_t (*set_RSRP_filtered)(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrp); - - /// Function for UE MAC to set the layer3 filtered RSRP/RSRQ measurements - uint8_t (*set_RSRQ_filtered)(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrp); - - /// Function for UE/eNB MAC to retrieve number of PRACH in TDD - uint8_t (*get_num_prach_tdd)(LTE_DL_FRAME_PARMS *frame_parms); - - /// Function for UE/eNB MAC to retrieve f_id of particular PRACH resource in TDD - uint8_t (*get_fid_prach_tdd)(LTE_DL_FRAME_PARMS *frame_parms,uint8_t tdd_map_index); - - /// Function for eNB MAC to retrieve subframe direction - lte_subframe_t (*get_subframe_direction)(module_id_t Mod_id, uint8_t CC_id, uint8_t subframe); - - // MAC Helper functions - /// Function for UE/PHY to compute PUSCH transmit power in power-control procedure (Po_NOMINAL_PUSCH parameter) - int8_t (*get_Po_NOMINAL_PUSCH)(module_id_t Mod_id,uint8_t CC_id); - - /// Function for UE/PHY to compute PUSCH transmit power in power-control procedure (deltaP_rampup parameter) - int8_t (*get_deltaP_rampup)(module_id_t Mod_id,uint8_t CC_id); - - /// Function for UE/PHY to compute PHR - int8_t (*get_PHR)(module_id_t Mod_id, uint8_t CC_id,uint8_t eNB_index); - - /// Function for UE to process the timing advance command - void (*process_timing_advance)(module_id_t Mod_id,uint8_t CC_id, int16_t timing_advance); - - /// Function for MAC to get the UE stats from the PHY - LTE_eNB_UE_stats* (*get_eNB_UE_stats)(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti); - - /// get the frame parameters from the PHY - LTE_DL_FRAME_PARMS* (*get_lte_frame_parms)(module_id_t Mod_id, uint8_t CC_id); - - /// get the Multiuser mimo mode - MU_MIMO_mode* (*get_mu_mimo_mode) (module_id_t Mod_id, uint8_t CC_id, rnti_t rnti); - - /// get the delta TF for Uplink Power Control Calculation - int16_t (*get_hundred_times_delta_TF) (module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid); - /// get target PUSCH received power - int16_t (*get_target_pusch_rx_power) (module_id_t module_idP, uint8_t CC_id); - /// get target PUSCH received power - int16_t (*get_target_pucch_rx_power) (module_id_t module_idP, uint8_t CC_id); - - unsigned char is_cluster_head; - unsigned char is_primary_cluster_head; - unsigned char is_secondary_cluster_head; - unsigned char cluster_head_index; - - /// PHY Frame Configuration - LTE_DL_FRAME_PARMS *frame_parms; - - uint8_t (*get_prach_prb_offset)(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf); - - int (*is_prach_subframe)(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t subframe); - - /// ICIC algos - uint8_t (*get_SB_size)(uint8_t n_rb_dl); - ///end ALU's algo - -} MAC_xface; - -*/ - -#endif - - -/** @} */ diff --git a/openair2/PHY_INTERFACE/phy_interface.h b/openair2/PHY_INTERFACE/phy_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..f275e91ec1b619059f81be20977c215c6345d922 --- /dev/null +++ b/openair2/PHY_INTERFACE/phy_interface.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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_INTERFACE/defs.h +* \brief mac phy interface primitives +* \author Raymond Knopp and Navid Nikaein +* \date 2011 +* \version 0.5 +* \mail navid.nikaein@eurecom.fr or openair_tech@eurecom.fr +*/ + +#ifndef __PHY_INTERFACE_H__ +# define __PHY_INTERFACE_H__ + +#include "LAYER2/MAC/mac.h" + + +#define MAX_NUMBER_OF_MAC_INSTANCES 16 + +#define NULL_PDU 255 +#define DCI 0 +#define DLSCH 1 +#define ULSCH 2 + +#define mac_exit_wrapper(sTRING) \ +do { \ + char temp[300]; \ + snprintf(temp, sizeof(temp), "%s in file "__FILE__" at line %d\n", sTRING, __LINE__); \ + mac_xface->macphy_exit(temp); \ +} while(0) + + + +#endif + + +/** @} */ diff --git a/openair2/PHY_INTERFACE/extern.h b/openair2/PHY_INTERFACE/phy_interface_extern.h similarity index 100% rename from openair2/PHY_INTERFACE/extern.h rename to openair2/PHY_INTERFACE/phy_interface_extern.h diff --git a/openair2/PHY_INTERFACE/vars.h b/openair2/PHY_INTERFACE/phy_interface_vars.h similarity index 98% rename from openair2/PHY_INTERFACE/vars.h rename to openair2/PHY_INTERFACE/phy_interface_vars.h index 566f4347b6e5e264ff19a5a28193b1c96258ab97..5f205d302443ddc84274a7cb33e6dc9f8477c197 100644 --- a/openair2/PHY_INTERFACE/vars.h +++ b/openair2/PHY_INTERFACE/phy_interface_vars.h @@ -23,7 +23,7 @@ #define __PHY_INTERFACE_VARS_H__ //#include "SIMULATION/PHY_EMULATION/spec_defs.h" -#include "defs.h" +#include "phy_interface.h" #ifdef PHY_EMUL #include "SIMULATION/PHY_EMULATION/DEVICE_DRIVER/defs.h" diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c new file mode 100644 index 0000000000000000000000000000000000000000..588cde5231d917d1db71b172563c13ab1eee3a26 --- /dev/null +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -0,0 +1,1022 @@ + +//#include "openair1/PHY/defs.h" +//#include "openair2/PHY_INTERFACE/IF_Module.h" +//#include "openair1/PHY/extern.h" +#include "openair2/LAYER2/MAC/mac_extern.h" +#include "openair2/LAYER2/MAC/mac.h" +#include "openair2/LAYER2/MAC/mac_proto.h" +//#include "openair2/LAYER2/MAC/vars.h" +#include "openair1/SCHED_UE/sched_UE.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" +//#include "common/ran_context.h" +#include "openair2/PHY_INTERFACE/phy_stub_UE.h" +#include "openair2/ENB_APP/L1_paramdef.h" +#include "openair2/ENB_APP/enb_paramdef.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "common/config/config_load_configmodule.h" +#include "common/config/config_userapi.h" + +//#define DEADLINE_SCHEDULER 1 + + +extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); +extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); +extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); +void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); + + + + +//extern uint8_t nfapi_pnf; +//UL_IND_t *UL_INFO; +extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10]; +//extern int timer_subframe; +//extern int timer_frame; + +extern uint16_t sf_ahead; + +void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); +void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); + + + +void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t* UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index) +{ + nfapi_rx_indication_pdu_t *pdu; + + int timing_advance_update; + + + pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + + + UL_INFO->rx_ind.sfn_sf = frame<<4| subframe; + UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + UL_INFO->rx_ind.vendor_extension = ul_config_req->vendor_extension; + + + pdu = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus]; + //pdu = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[index]; + + // pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; + pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; + //pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; + pdu->rx_indication_rel8.length = buflen; + pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation + pdu->data = ulsch_buffer; + // estimate timing advance for MAC + //sync_pos = lte_est_timing_advance_pusch(eNB,UE_id); + timing_advance_update = 0; //Panos: Don't know what to put here + pdu->rx_indication_rel8.timing_advance = timing_advance_update; + + int SNRtimes10 = 640; + + if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0; + else if (SNRtimes10 > 635) pdu->rx_indication_rel8.ul_cqi=255; + else pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5; + + + UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; + UL_INFO->rx_ind.sfn_sf = frame<<4 | subframe; + pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + + +} + +void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti) { + + + pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + + nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind; + nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; + nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; + UL_INFO->sr_ind.vendor_extension = ul_config_req->vendor_extension; + + //nfapi_sr_indication_pdu_t *pdu = &UL_INFO->sr_ind.sr_indication_body.sr_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus]; + + sr_ind->sfn_sf = frame<<4|subframe; + sr_ind->header.message_id = NFAPI_RX_SR_INDICATION; + + sr_ind_body->tl.tag = NFAPI_SR_INDICATION_BODY_TAG; + + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; //UE_mac_inst[Mod_id].crnti;; //Panos: Is this the right RNTI? + + + // Panos dependency from PHY not sure how to substitute this. Should we hardcode it? + //int SNRtimes10 = dB_fixed_times10(stat) - 200;//(10*eNB->measurements.n0_power_dB[0]); + int SNRtimes10 = 640; + + pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + + + if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; + else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255; + else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5; + pdu->ul_cqi_information.channel = 0; + + //UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; + sr_ind_body->number_of_srs++; + pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); +} + + +void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti) { + + pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + + //Panos: REMEMBER HAVE EXCHANGED THE FOLLOWING TWO LINES HERE! + nfapi_crc_indication_pdu_t *pdu = &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs]; + + UL_INFO->crc_ind.sfn_sf = frame<<4| subframe; + UL_INFO->crc_ind.vendor_extension = ul_config_req->vendor_extension; + UL_INFO->crc_ind.header.message_id = NFAPI_CRC_INDICATION; + UL_INFO->crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; + + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + + //pdu->rx_ue_information.rnti = UE_mac_inst[Mod_id].crnti; + pdu->rx_ue_information.rnti = rnti; + pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; + pdu->crc_indication_rel8.crc_flag = crc_flag; + + UL_INFO->crc_ind.crc_indication_body.number_of_crcs++; + + LOG_D(PHY, "%s() rnti:%04x pdus:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + + pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); +} + +void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) { + + LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n"); + pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); + + UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1; + + //eNB->UL_INFO.rach_ind.preamble_list = &eNB->preamble_list[0]; + UL_INFO->rach_ind.header.message_id = NFAPI_RACH_INDICATION; + UL_INFO->rach_ind.sfn_sf = frame<<4 | subframe; + UL_INFO->rach_ind.vendor_extension = NULL; + + UL_INFO->rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; + + + UL_INFO->rach_ind.rach_indication_body.preamble_list = (nfapi_preamble_pdu_t*)malloc(UL_INFO->rach_ind.rach_indication_body.number_of_preambles*sizeof(nfapi_preamble_pdu_t)); + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance = 0; //Panos: Not sure about that + + //Panos: The two following should get extracted from the call to get_prach_resources(). + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble = ra_PreambleIndex; + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti = ra_RNTI; + //UL_INFO->rach_ind.rach_indication_body.number_of_preambles++; + + + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel13.rach_resource_type = 0; + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].instance_length = 0; + + + LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n"); + LOG_E(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti, + UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel13.rach_resource_type); + + //Panos: This function is currently defined only in the nfapi-RU-RAU-split so we should call it when we merge + // with that branch. + oai_nfapi_rach_ind(&UL_INFO->rach_ind); + free(UL_INFO->rach_ind.rach_indication_body.preamble_list); + free(UL_INFO); + + //} + pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + +} + +void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) { + + pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_pdu_list[UL_INFO->cqi_ind.number_of_cqis]; + nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_raw_pdu_list[UL_INFO->cqi_ind.number_of_cqis]; + + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; + //Panos: Since we assume that CRC flag is always 0 (ACK) I guess that data_offset should always be 0. + pdu->cqi_indication_rel9.data_offset = 0; + + // by default set O to rank 1 value + //pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0); + // Panos: Not useful field for our case + pdu->cqi_indication_rel9.tl.tag = NFAPI_CQI_INDICATION_REL9_TAG; + pdu->cqi_indication_rel9.length = 0; + pdu->cqi_indication_rel9.ri[0] = 0; + + + pdu->cqi_indication_rel9.timing_advance = 0; + pdu->cqi_indication_rel9.number_of_cc_reported = 1; + pdu->ul_cqi_information.channel = 1; // PUSCH + + //Panos: Not sure how to substitute this. This should be the actual CQI value? So can + // we hardcode it to a specific value? + //memcpy((void*)raw_pdu->pdu,ulsch_harq->o,pdu->cqi_indication_rel9.length); + raw_pdu->pdu[0] = 7; + + + + UL_INFO->cqi_ind.number_of_cqis++; + pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + +} + +void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti) +{ + + pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; + int i; + + UL_INFO->harq_ind.header.message_id = NFAPI_HARQ_INDICATION; + UL_INFO->harq_ind.sfn_sf = frame<<4|subframe; + UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension; + + UL_INFO->harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = rnti; + + //Panos: For now we consider only FDD + //if (eNB->frame_parms.frame_type == FDD) { + pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; + pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = harq_information->harq_information_rel10.harq_size; + + //Panos: Could this be wrong? Is the number_of_ack_nack field equivalent to O_ACK? + //pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; + + for (i=0;i<harq_information->harq_information_rel10.harq_size;i++) { + + pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 1; //Panos: Assuming always an ACK (No NACK or DTX) + + } + + UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; + pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); +} + + +void fill_uci_harq_indication_UE_MAC(int Mod_id, + int frame, + int subframe, + UL_IND_t *UL_INFO, + nfapi_ul_config_harq_information *harq_information, + uint16_t rnti + /*uint8_t tdd_mapping_mode, + uint16_t tdd_multiplexing_mask*/) { + + + pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + nfapi_harq_indication_t *ind = &UL_INFO->harq_ind; + nfapi_harq_indication_body_t *body = &ind->harq_indication_body; + nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; + + UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension; + + ind->sfn_sf = frame<<4|subframe; + ind->header.message_id = NFAPI_HARQ_INDICATION; + + body->tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.rnti = rnti; + + pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + + int SNRtimes10 = 640; + + + if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; + else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255; + else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5; + pdu->ul_cqi_information.channel = 0; + if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && + (harq_information->harq_information_rel9_fdd.harq_size == 1)) { + + pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; + pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1; + + //AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); + pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; //Panos: Assuming always an ACK (No NACK or DTX) + + + } + else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && + (harq_information->harq_information_rel9_fdd.harq_size == 2)) { + pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; + pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2; + pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; //Panos: Assuming always an ACK (No NACK or DTX) + pdu->harq_indication_fdd_rel13.harq_tb_n[1] = 1; //Panos: Assuming always an ACK (No NACK or DTX) + + } + else AssertFatal(1==0,"only format 1a/b for now, received \n"); + + + UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; + LOG_D(PHY,"Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.harq_indication_body.number_of_harqs); + pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + +} + + +void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, + nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint16_t frame,uint8_t subframe,uint8_t srs_present, int index) +{ + nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8; + + if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { + LOG_D(PHY,"Applying UL config for UE, rnti %x for frame %d, subframe %d\n", + rel8->rnti,frame,subframe); + uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); + uint16_t buflen = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size; + + uint16_t rnti = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti; + uint8_t access_mode=SCHEDULED_ACCESS; + if(buflen>0){ + if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case + LOG_D(MAC, "handle_nfapi_ul_pdu_UE_MAC 2.2, Mod_id:%d, SFN/SF: %d/%d \n", Mod_id, frame, subframe); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); + Msg3_transmitted(Mod_id, 0, frame, 0); + // Panos: Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + + // Panos: This should be done after the reception of the respective hi_dci0 + //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } + else { + //LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 2.3 \n"); + ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); + } + } + } + + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) { + + //AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, + // "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); + uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); + uint16_t buflen = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.size; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; + uint16_t rnti = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + uint8_t access_mode=SCHEDULED_ACCESS; + if(buflen>0){ + if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); + Msg3_transmitted(Mod_id, 0, frame, 0); + //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + // Panos: Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } + else { + //LOG_I(MAC, "Panos-D: handle_nfapi_ul_pdu_UE_MAC 3.1 \n"); + ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); + } + + } + if(ulsch_harq_information!=NULL) + fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) { + uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); + uint16_t buflen = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size; + + uint16_t rnti = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + uint8_t access_mode=SCHEDULED_ACCESS; + if(buflen>0){ + if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); + Msg3_transmitted(Mod_id, 0, frame, 0); + //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + // Panos: Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } + else { + ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); + } + } + fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { + + uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32))); + uint16_t buflen = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; + + uint16_t rnti = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + uint8_t access_mode=SCHEDULED_ACCESS; + if(buflen>0){ + if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index); + Msg3_transmitted(Mod_id, 0, frame, 0); + //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + // Panos: Modification + UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } + else { + ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index); + } + } + + if(ulsch_harq_information!=NULL) + fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { + + uint16_t rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti; + + nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_harq_pdu.harq_information; + if(ulsch_harq_information != NULL) + fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti); + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { + AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n"); + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { + AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n"); + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { + AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n"); + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { + + uint16_t rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti; + + if (ue_get_SR(Mod_id ,0,frame, 0, rnti, subframe)) + fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { + //AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, + // "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti); + + uint16_t rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti; + + // We fill the sr_indication only if ue_get_sr() would normally instruct PHY to send a SR. + if (ue_get_SR(Mod_id ,0,frame, 0, rnti, subframe)) + fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,rnti); + + nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; + if (ulsch_harq_information != NULL) + fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti); + + } + +} + + + + + + +int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int timer_subframe, module_id_t Mod_id) +{ + //if (req!=NULL){ // && req->ul_config_request_body.ul_config_pdu_list !=NULL){ + LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->ul_config_request_body.number_of_pdus, + req->ul_config_request_body.rach_prach_frequency_resources, + req->ul_config_request_body.srs_present + ); + + int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + int sf = NFAPI_SFNSF2SF(req->sfn_sf); + + + LOG_D(MAC, "ul_config_req_UE_MAC() TOTAL NUMBER OF UL_CONFIG PDUs: %d, SFN/SF: %d/%d \n", req->ul_config_request_body.number_of_pdus, timer_frame, timer_subframe); + + + + for (int i=0;i<req->ul_config_request_body.number_of_pdus;i++) + { + + if ( + (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || + (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || + (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || + (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) || + (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) || + (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) || + (req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) + ) + { + + handle_nfapi_ul_pdu_UE_MAC(Mod_id,&req->ul_config_request_body.ul_config_pdu_list[i],sfn,sf,req->ul_config_request_body.srs_present, i); + + } + else + { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_config_pdu_list[i].pdu_type); + } + } + +// } + + return 0; +} + + + +int tx_req_UE_MAC(nfapi_tx_request_t* req) +{ + uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf); + + LOG_D(PHY,"%s() SFN/SF:%d/%d PDUs:%d\n", __FUNCTION__, sfn, sf, req->tx_request_body.number_of_pdus); + + + for (int i=0; i<req->tx_request_body.number_of_pdus; i++) + { + LOG_D(PHY,"%s() SFN/SF:%d/%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n", + __FUNCTION__, + sfn, sf, + req->tx_request_body.number_of_pdus, + i, + req->tx_request_body.tx_pdu_list[i].pdu_length, + req->tx_request_body.tx_pdu_list[i].pdu_index, + req->tx_request_body.tx_pdu_list[i].num_segments + ); + + } + + return 0; +} + + +int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, nfapi_tx_request_pdu_t* tx_request_pdu_list) +{ + //if (req!=NULL && tx_request_pdu_list!=NULL){ + int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + int sf = NFAPI_SFNSF2SF(req->sfn_sf); + //Mod_id = 0; // Currently static (only for one UE) but this should change. + + /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];*/ + nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; + nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp; + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d sfn_sf:%d DCI:%d PDU:%d\n", __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2DEC(req->sfn_sf), req->dl_config_request_body.number_dci, req->dl_config_request_body.number_pdu); + + + + //LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%d%d dl_pdu:%d tx_req:%d hi_dci0:%d ul_cfg:%d num_pdcch_symbols:%d\n", + // frame,subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu, eNB->pdcch_vars[subframe&1].num_pdcch_symbols); + + for (int i=0;i<req->dl_config_request_body.number_pdu;i++) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size); + //LOG_E(MAC, "dl_config_req_UE_MAC 2 Received real ones: sfn/sf:%d.%d PDU[%d] size:%d\n", sfn, sf, i, dl_config_pdu_list[i].pdu_size); + + if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + { + if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1) { + // C-RNTI (Normal DLSCH case) + dl_config_pdu_tmp = &dl_config_pdu_list[i+1]; + if (dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && UE_mac_inst[Mod_id].crnti == dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti){ + + /*nfapi_tx_request_pdu_t *ptr = tx_request_pdu_list; + ptr += dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index*(sizeof(nfapi_tx_request_pdu_t)); + nfapi_tx_request_pdu_t temp; + memset(&temp, 0, sizeof(nfapi_tx_request_pdu_t)); + //if (!memcmp(&temp, ptr, sizeof(temp)) ... + if( *(char*)ptr != 0){ + //if(tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data!= NULL && tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length >0){ + */ + + if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){ + //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ + + LOG_E(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems); + + ue_send_sdu(Mod_id, 0, sfn, sf, + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length, + 0); + i++; + } + else{ + LOG_E(MAC,"dl_config_req_UE_MAC 2: Problem with receiving data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index); + i++; + } + } + else { + LOG_E(MAC,"[UE %d] Frame %d, subframe %d : DLSCH PDU from NFAPI not for this UE \n",Mod_id, sfn,sf); + i++; + } + } + else if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 2) { + dl_config_pdu_tmp = &dl_config_pdu_list[i+1]; + if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFF && UE_mac_inst[Mod_id].UE_mode[0] != NOT_SYNCHED){ //&& UE_mac_inst[Mod_id].UE_mode[0] != NOT_SYNCHED + + if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){ + //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ + ue_decode_si(Mod_id, 0, sfn, 0, + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length); + i++; + } + else{ + LOG_E(MAC,"dl_config_req_UE_MAC 3: Problem with receiving SI: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index); + i++; + } + } + else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFE){ + // P_RNTI case + //pdu = Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data; + + if (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){ + //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ + ue_decode_p(Mod_id, 0, sfn, 0, + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length); + i++; + } + else{ + LOG_E(MAC,"dl_config_req_UE_MAC: Problem with receiving Paging: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index); + i++; + } + } + else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) { + // RA-RNTI case + LOG_E(MAC,"dl_config_req_UE_MAC 4 Received RAR? \n"); + // RNTI parameter not actually used. Provided only to comply with existing function definition. + // Not sure about parameters to fill the preamble index. + //rnti_t c_rnti = UE_mac_inst[Mod_id].crnti; + rnti_t ra_rnti = UE_mac_inst[Mod_id].RA_prach_resources.ra_RNTI; + if ((UE_mac_inst[Mod_id].UE_mode[0] != PUSCH) && + (UE_mac_inst[Mod_id].RA_prach_resources.Msg3!=NULL) && (ra_rnti== dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) && + //(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL)) { + (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)) { + LOG_E(MAC,"dl_config_req_UE_MAC 5 Received RAR, PreambleIndex: %d \n", UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex); + ue_process_rar(Mod_id, 0, sfn, + ra_rnti, //RA-RNTI + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + &dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //t-crnti + UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex, + tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data); + UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; + UE_mac_inst[Mod_id].first_ULSCH_Tx = 1; //Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first ULSCH Txon for the UE) + } + i++; + } + else { + LOG_E(MAC,"[UE %d] Frame %d, subframe %d : Cannot extract DLSCH PDU from NFAPI 2\n",Mod_id, sfn, sf); + i++; + } + + } + } + else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) + { + // BCH case + // Last parameter is 1 if first time synchronization and zero otherwise. Not sure which value to put + // for our case. + //LOG_E(MAC,"dl_config_req_UE_MAC 4 Received MIB: sfn/sf: %d.%d \n", sfn, sf); + if(UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){ + dl_phy_sync_success(Mod_id,sfn,0, 1); + LOG_E(MAC,"dl_config_req_UE_MAC 5 Received MIB: UE_mode: %d, sfn/sf: %d.%d\n", UE_mac_inst[Mod_id].UE_mode[0], sfn, sf); + UE_mac_inst[Mod_id].UE_mode[0]=PRACH; + } + else + dl_phy_sync_success(Mod_id,sfn,0, 0); + + } + + else + { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_config_pdu_list[i].pdu_type); + } + } + + return 0; + +} + + +int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id) +{ + if (req!=NULL && req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ + LOG_D(PHY,"[UE-PHY_STUB] hi dci0 request sfn_sf:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi); + + + + for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) + { + LOG_D(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + + if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) + { + LOG_D(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE not used \n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + + } + else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) + { + //LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + + nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = &req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + + // This is meaningful only after ACKnowledging the first ULSCH Txon (i.e. Msg3) + if(hi_dci0_req_pdu->hi_pdu.hi_pdu_rel8.hi_value == 1 && UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ + //LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ 2 sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + //UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; + //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; + } + + } + else + { + LOG_E(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); + } + } + + } + + + return 0; +} + + + + + +// The following set of memcpy functions should be getting called as callback functions from +// pnf_p7_subframe_ind. +int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) +{ + + //module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change. + + //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++){ + + dl_config_req = (nfapi_dl_config_request_t*)malloc(sizeof(nfapi_dl_config_request_t)); + //LOG_I(MAC, "Panos-D: memcpy_dl_config_req 1, Mod_id:%d \n", Mod_id); + + + //UE_mac_inst[Mod_id].dl_config_req->header = req->header; + dl_config_req->sfn_sf = req->sfn_sf; + + dl_config_req->vendor_extension = req->vendor_extension; + + dl_config_req->dl_config_request_body.number_dci = req->dl_config_request_body.number_dci; + dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols; + dl_config_req->dl_config_request_body.number_pdsch_rnti = req->dl_config_request_body.number_pdsch_rnti; + dl_config_req->dl_config_request_body.number_pdu = req->dl_config_request_body.number_pdu; + + dl_config_req->dl_config_request_body.tl.tag = req->dl_config_request_body.tl.tag; + dl_config_req->dl_config_request_body.tl.length = req->dl_config_request_body.tl.length; + + dl_config_req->dl_config_request_body.dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*) calloc(req->dl_config_request_body.number_pdu, sizeof(nfapi_dl_config_request_pdu_t)); + for(int i=0; i<dl_config_req->dl_config_request_body.number_pdu; i++) { + dl_config_req->dl_config_request_body.dl_config_pdu_list[i] = req->dl_config_request_body.dl_config_pdu_list[i]; + } + + //} + + return 0; + +} + +int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) +{ + //LOG_D(MAC, "Panos-D: memcpy_ul_config_req 1 \n"); + + //module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change. + + + //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++){ + + ul_config_req = (nfapi_ul_config_request_t*)malloc(sizeof(nfapi_ul_config_request_t)); + + ul_config_req->sfn_sf = req->sfn_sf; + ul_config_req->vendor_extension = req->vendor_extension; + + + ul_config_req->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus; + ul_config_req->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources; + ul_config_req->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present; + + ul_config_req->ul_config_request_body.tl.tag = req->ul_config_request_body.tl.tag; + ul_config_req->ul_config_request_body.tl.length = req->ul_config_request_body.tl.length; + + //LOG_D(MAC, "memcpy_ul_config_req 1 #ofULPDUs: %d \n", UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.number_of_pdus); //req->ul_config_request_body.number_of_pdus); + ul_config_req->ul_config_request_body.ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*) malloc(req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); + for(int i=0; i<ul_config_req->ul_config_request_body.number_of_pdus; i++) { + ul_config_req->ul_config_request_body.ul_config_pdu_list[i] = req->ul_config_request_body.ul_config_pdu_list[i]; + } + //} + + return 0; +} + + + + +int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) +{ + //module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change. + + + tx_req_num_elems = req->tx_request_body.number_of_pdus; + tx_request_pdu_list = (nfapi_tx_request_pdu_t*) calloc(tx_req_num_elems, sizeof(nfapi_tx_request_pdu_t)); + for (int i=0; i<tx_req_num_elems; i++) { + tx_request_pdu_list[i].num_segments = req->tx_request_body.tx_pdu_list[i].num_segments; + tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index; + tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length; + for (int j=0; j<req->tx_request_body.tx_pdu_list[i].num_segments; j++){ + //*tx_request_pdu_list[i].segments[j].segment_data = *req->tx_request_body.tx_pdu_list[i].segments[j].segment_data; + tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length; + if(tx_request_pdu_list[i].segments[j].segment_length > 0){ + tx_request_pdu_list[i].segments[j].segment_data = (uint8_t*)malloc(tx_request_pdu_list[i].segments[j].segment_length*sizeof (uint8_t)); + memcpy(tx_request_pdu_list[i].segments[j].segment_data, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, tx_request_pdu_list[i].segments[j].segment_length); + } + } + + } + + return 0; +} + +int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) +{ + + //if(req!=0){ + //module_id_t Mod_id = 0; //Panos: Currently static (only for one UE) but this should change. + + //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++){ + hi_dci0_req = (nfapi_hi_dci0_request_t*)malloc(sizeof(nfapi_hi_dci0_request_t)); + + hi_dci0_req->sfn_sf = req->sfn_sf; + hi_dci0_req->vendor_extension = req->vendor_extension; + + hi_dci0_req->hi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci; + hi_dci0_req->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi; + hi_dci0_req->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf; + + //UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.tl = req->hi_dci0_request_body.tl; + hi_dci0_req->hi_dci0_request_body.tl.tag = req->hi_dci0_request_body.tl.tag; + hi_dci0_req->hi_dci0_request_body.tl.length = req->hi_dci0_request_body.tl.length; + + int total_pdus = hi_dci0_req->hi_dci0_request_body.number_of_dci + hi_dci0_req->hi_dci0_request_body.number_of_hi; + + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*) malloc(total_pdus*sizeof(nfapi_hi_dci0_request_pdu_t)); + + for(int i=0; i<total_pdus; i++){ + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + //LOG_I(MAC, "Original hi_dci0 req. type:%d, Copy type: %d \n",req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type, UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); + } + + //} + return 0; +} + + + +void UE_config_stub_pnf(void) { + int j; + paramdef_t L1_Params[] = L1PARAMS_DESC; + paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0}; + + config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); + if (L1_ParamList.numelt > 0) { + for (j=0; j<L1_ParamList.numelt; j++){ + //nb_L1_CC = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); // Number of component carriers is of no use for the + // phy_stub mode UE pnf. Maybe we can completely skip it. + + if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { + sf_ahead = 4; // Need 4 subframe gap between RX and TX + } + // Panos: Right now that we have only one UE (thread) it is ok to put the eth_params in the UE_mac_inst. + // Later I think we have to change that to attribute eth_params to a global element for all the UEs. + else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { + stub_eth_params.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + stub_eth_params.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + stub_eth_params.remote_addr = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + stub_eth_params.my_portc = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + stub_eth_params.remote_portc = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + stub_eth_params.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + stub_eth_params.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + stub_eth_params.transp_preference = ETH_UDP_MODE; + + sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 + //configure_nfapi_pnf(UE_mac_inst[0].eth_params_n.remote_addr, UE_mac_inst[0].eth_params_n.remote_portc, UE_mac_inst[0].eth_params_n.my_addr, UE_mac_inst[0].eth_params_n.my_portd, UE_mac_inst[0].eth_params_n.remote_portd); + configure_nfapi_pnf(stub_eth_params.remote_addr, stub_eth_params.remote_portc, stub_eth_params.my_addr, stub_eth_params.my_portd, stub_eth_params.remote_portd); + } + else { // other midhaul + } + } + } + else { + + } +} + + +/* Dummy functions*/ + +void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) +{ + +} + + +void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) +{ + +} + + +void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, + int frame, int subframe, + eNB_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu) +{ + +} + + +void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t *sdu) +{ + +} + + +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t codeword_index, + uint8_t *sdu) +{ + +} + + +void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, + nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint16_t frame,uint8_t subframe,uint8_t srs_present) +{ + +} + +void phy_config_request(PHY_Config_t *phy_config) { + +} + +uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { return(0);} + +int32_t get_uldl_offset(int eutra_bandP) { return(0);} + +int l1_north_init_eNB(void) { +return 0; +} + +void init_eNB_afterRU(void) { + +} + diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h new file mode 100644 index 0000000000000000000000000000000000000000..9865be3eebb2eab81fd10acde8b97bafe6fe2846 --- /dev/null +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -0,0 +1,118 @@ +/* + * phy_stub_UE.h + * + * Created on: Sep 14, 2017 + * Author: montre + */ + + +#ifndef __PHY_STUB_UE__H__ +#define __PHY_STUB_UE__H__ + +#include <stdint.h> +#include "openair2/PHY_INTERFACE/IF_Module.h" +#include "nfapi_interface.h" +#include "nfapi_pnf_interface.h" +//#include "openair1/PHY/LTE_TRANSPORT/defs.h" +//#include "openair1/PHY/defs.h" +//#include "openair1/PHY/LTE_TRANSPORT/defs.h" + +UL_IND_t *UL_INFO; + +nfapi_tx_request_pdu_t* tx_request_pdu_list; +// New +/// Panos: Pointers to config_request types. Used from nfapi callback functions. +nfapi_dl_config_request_t* dl_config_req; +nfapi_ul_config_request_t* ul_config_req; +nfapi_hi_dci0_request_t* hi_dci0_req; + +int tx_req_num_elems; + +int next_ra_frame; +module_id_t next_Mod_id; +eth_params_t stub_eth_params; + + + + +// Panos: This function should return all the sched_response config messages which concern a specific UE. Inside this +// function we should somehow make the translation of config message's rnti to Mod_ID. +Sched_Rsp_t get_nfapi_sched_response(uint8_t Mod_id); + +// This function will be processing DL_config and Tx.requests and trigger all the MAC Rx related calls at the UE side, +// namely:ue_send_sdu(), or ue_decode_si(), or ue_decode_p(), or ue_process_rar() based on the rnti type. +//void handle_nfapi_UE_Rx(uint8_t Mod_id, Sched_Rsp_t *Sched_INFO, int eNB_id); + +int pnf_ul_config_req_UE_MAC(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req); + +// This function will be processing UL and HI_DCI0 config requests to trigger all the MAC Tx related calls +// at the UE side, namely: ue_get_SR(), ue_get_rach(), ue_get_sdu() based on the pdu configuration type. +// The output of these calls will be put to an UL_IND_t structure which will then be the input to +// send_nfapi_UL_indications(). +UL_IND_t generate_nfapi_UL_indications(Sched_Rsp_t sched_response); + +// This function should pass the UL indication messages to the eNB side through the socket interface. +void send_nfapi_UL_indications(UL_IND_t UL_INFO); + +// This function should be filling the nfapi ULSCH indications at the MAC level of the UE in a similar manner +// as fill_rx_indication() does. It should get called from ue_get_SDU() + +//void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe); + +void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index); + + +// This function should be indicating directly to the eNB when there is a planned scheduling request at the MAC layer +// of the UE. It should get called from ue_get_SR() +void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti); + +// In our case the this function will be always indicating ACK to the MAC of the eNB (i.e. always assuming) +// successful decoding. +void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti); + + +void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI); + + +void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti); + + +void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti); + +void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO,nfapi_ul_config_harq_information *harq_information, uint16_t rnti + /*uint8_t tdd_mapping_mode, + uint16_t tdd_multiplexing_mask*/); + +int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int frame, int subframe, module_id_t Mod_id); + +void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, + nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint16_t frame,uint8_t subframe,uint8_t srs_present, int index); + +//int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, nfapi_tx_request_pdu_t* tx_request_pdu_list); +int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id); + +int tx_req_UE_MAC(nfapi_tx_request_t* req); + + +int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id); + +// The following set of memcpy functions should be getting called as callback functions from +// pnf_p7_subframe_ind. + +int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req); + + +int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req); + + +int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req); + + +int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req); + +void UE_config_stub_pnf(void); + + + +#endif /* PHY_STUB_UE_H_ */ diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h index b13d72f980bcdc6eb21872bbe1fb1b5775adb96b..4b651761de57a7c1cf7438afe33956cef1a3cdec 100644 --- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h +++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h @@ -41,8 +41,6 @@ mac_rrc_data_req( const rb_id_t srb_idP, const uint8_t nb_tbP, uint8_t* const buffer_pP, - const eNB_flag_t eNB_flagP, - const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP ); @@ -56,7 +54,31 @@ mac_rrc_data_ind( const rb_id_t srb_idP, const uint8_t *sduP, const sdu_size_t sdu_lenP, - const eNB_flag_t eNB_flagP, + const uint8_t mbsfn_sync_area +); + +int8_t +mac_rrc_data_req_ue( + const module_id_t module_idP, + const int CC_idP, + const frame_t frameP, + const rb_id_t srb_idP, + const uint8_t nb_tbP, + uint8_t* const buffer_pP, + const mac_enb_index_t eNB_indexP, + const uint8_t mbsfn_sync_areaP +); + +int8_t +mac_rrc_data_ind_ue( + const module_id_t module_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t sub_frameP, + const rnti_t rntiP, + const rb_id_t srb_idP, + const uint8_t *sduP, + const sdu_size_t sdu_lenP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_area ); diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c deleted file mode 100644 index 75ce529ac7dd0736bc2b3bccfcaadedde6422648..0000000000000000000000000000000000000000 --- a/openair2/RRC/LITE/rrc_common.c +++ /dev/null @@ -1,649 +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.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * 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 rrc_common.c - * \brief rrc common procedures for eNB and UE - * \author Navid Nikaein and Raymond Knopp - * \date 2011 - 2014 - * \version 1.0 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr - */ - -#include "defs.h" -#include "extern.h" -#include "LAYER2/MAC/extern.h" -#include "COMMON/openair_defs.h" -#include "COMMON/platform_types.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#include "LAYER2/RLC/rlc.h" -#include "COMMON/mac_rrc_primitives.h" -#include "UTIL/LOG/log.h" -#include "asn1_msg.h" -#include "pdcp.h" -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "rrc_eNB_UE_context.h" -#include "common/ran_context.h" - -#if defined(ENABLE_USE_MME) -# include "rrc_eNB_S1AP.h" -#endif - -#ifdef LOCALIZATION -#include <sys/time.h> -#endif - -#define DEBUG_RRC 1 -extern RAN_CONTEXT_t RC; -extern UE_MAC_INST *UE_mac_inst; - -extern mui_t rrc_eNB_mui; - -//configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs -//----------------------------------------------------------------------------- -void -openair_rrc_on( - const protocol_ctxt_t* const ctxt_pP -) -//----------------------------------------------------------------------------- -{ - unsigned short i; - int CC_id; - - if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1; - rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0, CCCH, 1); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1; - } - } else { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - - for (i = 0; i < NB_eNB_INST; i++) { - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" Activating CCCH (eNB %d)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), i); - UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Srb_id = CCCH; - memcpy (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Lchan_desc[0], &CCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - memcpy (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Lchan_desc[1], &CCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - rrc_config_buffer (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i], CCCH, 1); - UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Active = 1; - } - } -} - -//----------------------------------------------------------------------------- -int -rrc_init_global_param( - void -) -//----------------------------------------------------------------------------- -{ - - // Rrc_xface = (RRC_XFACE*)malloc16(sizeof(RRC_XFACE)); - - // Rrc_xface->openair_rrc_top_init = openair_rrc_top_init; - // Rrc_xface->openair_rrc_eNB_init = openair_rrc_eNB_init; - // Rrc_xface->openair_rrc_UE_init = openair_rrc_ue_init; - // Rrc_xface->mac_rrc_data_ind = mac_rrc_data_ind; - //Rrc_xface->mac_rrc_data_req = mac_rrc_data_req; - // Rrc_xface->rrc_data_indP = (void *)rlcrrc_data_ind; - // Rrc_xface->rrc_rx_tx = rrc_rx_tx; - // Rrc_xface->mac_rrc_meas_ind = mac_rrc_meas_ind; - // Rrc_xface->get_rrc_status = get_rrc_status; - - //Rrc_xface->rrc_get_status = ... - - // Mac_rlc_xface->mac_out_of_sync_ind=mac_out_of_sync_ind; - -#ifndef NO_RRM - // Rrc_xface->fn_rrc=fn_rrc; -#endif - // LOG_D(RRC, "[RRC]INIT_GLOBAL_PARAM: Mac_rlc_xface %p, rrc_rlc_register %p,rlcrrc_data_ind%p\n",Mac_rlc_xface,Mac_rlc_xface->rrc_rlc_register_rrc,rlcrrc_data_ind); - /* - if((Mac_rlc_xface==NULL) || (Mac_rlc_xface->rrc_rlc_register_rrc==NULL) || - (rlcrrc_data_ind==NULL)) { - LOG_E(RRC,"Data structured is not initialized \n"); - return -1; - } - */ - rrc_rlc_register_rrc (rrc_data_ind, NULL); //register with rlc - - DCCH_LCHAN_DESC.transport_block_size = 4; - DCCH_LCHAN_DESC.max_transport_blocks = 16; - DCCH_LCHAN_DESC.Delay_class = 1; - DTCH_DL_LCHAN_DESC.transport_block_size = 52; - DTCH_DL_LCHAN_DESC.max_transport_blocks = 20; - DTCH_DL_LCHAN_DESC.Delay_class = 1; - DTCH_UL_LCHAN_DESC.transport_block_size = 52; - DTCH_UL_LCHAN_DESC.max_transport_blocks = 20; - DTCH_UL_LCHAN_DESC.Delay_class = 1; - - Rlc_info_um.rlc_mode = RLC_MODE_UM; - Rlc_info_um.rlc.rlc_um_info.timer_reordering = 5; - Rlc_info_um.rlc.rlc_um_info.sn_field_length = 10; - Rlc_info_um.rlc.rlc_um_info.is_mXch = 0; - //Rlc_info_um.rlc.rlc_um_info.sdu_discard_mode=16; - - Rlc_info_am_config.rlc_mode = RLC_MODE_AM; - Rlc_info_am_config.rlc.rlc_am_info.max_retx_threshold = 50; - Rlc_info_am_config.rlc.rlc_am_info.poll_pdu = 8; - Rlc_info_am_config.rlc.rlc_am_info.poll_byte = 1000; - Rlc_info_am_config.rlc.rlc_am_info.t_poll_retransmit = 15; - Rlc_info_am_config.rlc.rlc_am_info.t_reordering = 50; - Rlc_info_am_config.rlc.rlc_am_info.t_status_prohibit = 10; - - return 0; -} - -//----------------------------------------------------------------------------- -void -rrc_config_buffer( - SRB_INFO* Srb_info, - uint8_t Lchan_type, - uint8_t Role -) -//----------------------------------------------------------------------------- -{ - - Srb_info->Rx_buffer.payload_size = 0; - Srb_info->Tx_buffer.payload_size = 0; -} - - -//----------------------------------------------------------------------------- -void -rrc_t310_expiration( - const protocol_ctxt_t* const ctxt_pP, - const uint8_t eNB_index -) -//----------------------------------------------------------------------------- -{ - - if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State != RRC_CONNECTED) { - LOG_D(RRC, "Timer 310 expired, going to RRC_IDLE\n"); - UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_IDLE; - UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].UE_index = 0xffff; - UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Rx_buffer.payload_size = 0; - UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size = 0; - UE_rrc_inst[ctxt_pP->module_id].Srb1[eNB_index].Srb_info.Rx_buffer.payload_size = 0; - UE_rrc_inst[ctxt_pP->module_id].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size = 0; - - if (UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active == 1) { - msg ("[RRC Inst %d] eNB_index %d, Remove RB %d\n ", ctxt_pP->module_id, eNB_index, - UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id); - rrc_pdcp_config_req (ctxt_pP, - SRB_FLAG_YES, - CONFIG_ACTION_REMOVE, - UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id, - 0); - rrc_rlc_config_req (ctxt_pP, - SRB_FLAG_YES, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id, - Rlc_info_um); - UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active = 0; - UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Status = IDLE; - UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Next_check_frame = 0; - } - } else { // Restablishment procedure - LOG_D(RRC, "Timer 310 expired, trying RRCRestablishment ...\n"); - } -} - -//----------------------------------------------------------------------------- -RRC_status_t -rrc_rx_tx( - protocol_ctxt_t* const ctxt_pP, - const uint8_t enb_indexP, - const int CC_id -) -//----------------------------------------------------------------------------- -{ - //uint8_t UE_id; - int32_t current_timestamp_ms, ref_timestamp_ms; - struct timeval ts; - struct rrc_eNB_ue_context_s *ue_context_p = NULL,*ue_to_be_removed = NULL; - -#ifdef LOCALIZATION - double estimated_distance; - protocol_ctxt_t ctxt; -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_IN); - - if(ctxt_pP->enb_flag == ENB_FLAG_NO) { - // check timers - - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_active == 1) { - if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt % 10) == 0) - LOG_D(RRC, - "[UE %d][RAPROC] Frame %d T300 Count %d ms\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt); - - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt - == T300[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.t300]) { - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_active = 0; - // ALLOW CCCH to be used - UE_rrc_inst[ctxt_pP->module_id].Srb0[enb_indexP].Tx_buffer.payload_size = 0; - rrc_ue_generate_RRCConnectionRequest (ctxt_pP, enb_indexP); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - return (RRC_ConnSetup_failed); - } - - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt++; - } - - if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].SIStatus&2)>0) { - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt - == N310[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.n310]) { - LOG_I(RRC,"Activating T310\n"); - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 1; - } - } else { // in case we have not received SIB2 yet - /* if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt == 100) { - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt = 0; - - }*/ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - return RRC_OK; - } - - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active == 1) { - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N311_cnt - == N311[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.n311]) { - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0; - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N311_cnt = 0; - } - - if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt % 10) == 0) { - LOG_D(RRC, "[UE %d] Frame %d T310 Count %d ms\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt); - } - - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt == T310[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.t310]) { - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0; - rrc_t310_expiration (ctxt_pP, enb_indexP); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - LOG_I(RRC,"Returning RRC_PHY_RESYNCH: T310 expired\n"); - return RRC_PHY_RESYNCH; - } - - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt++; - } - - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_active==1) { - if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt % 10) == 0) - LOG_D(RRC,"[UE %d][RAPROC] Frame %d T304 Count %d ms\n",ctxt_pP->module_id,ctxt_pP->frame, - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt); - - if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt == 0) { - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_active = 0; - UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1; - LOG_E(RRC,"[UE %d] Handover failure..initiating connection re-establishment procedure... \n", - ctxt_pP->module_id); - //Implement 36.331, section 5.3.5.6 here - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - return(RRC_Handover_failed); - } - - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt--; - } - - // Layer 3 filtering of RRC measurements - if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0] != NULL) { - ue_meas_filtering(ctxt_pP,enb_indexP); - } - - ue_measurement_report_triggering(ctxt_pP,enb_indexP); - - if (UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget > 0) { - LOG_I(RRC,"[UE %d] Frame %d : RRC handover initiated\n", ctxt_pP->module_id, ctxt_pP->frame); - } - - if((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].State == RRC_HO_EXECUTION) && - (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId != 0xFF)) { - UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].State= RRC_IDLE; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - return(RRC_HO_STARTED); - } - - } else { // eNB - check_handovers(ctxt_pP); - // counetr, and get the value and aggregate - - // check for UL failure - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt_pP->rnti = ue_context_p->ue_id_rnti; - if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { - LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.ul_failure_timer); - } - else { - LOG_I(RRC,"UE rnti %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ul_failure_timer); - } - } - if (ue_context_p->ue_context.ul_failure_timer>0) { - ue_context_p->ue_context.ul_failure_timer++; - if (ue_context_p->ue_context.ul_failure_timer >= 20000) { - // remove UE after 20 seconds after MAC has indicated UL failure - LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; - break; - } - } - if (ue_context_p->ue_context.ue_release_timer_s1>0) { - ue_context_p->ue_context.ue_release_timer_s1++; - if (ue_context_p->ue_context.ue_release_timer_s1 >= - ue_context_p->ue_context.ue_release_timer_thres_s1) { - LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", - ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1); -// ue_context_p->ue_context.ue_release_timer_s1 = 0; -#if defined(ENABLE_USE_MME) -#if defined(ENABLE_ITTI) - rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); -#if 0 - { - int e_rab; - MessageDef *msg_delete_tunnels_p = NULL; - uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - // do not wait response - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = - ue_context_p->ue_context.enb_gtp_ebi[e_rab]; - // erase data - ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); - ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; - } - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_S1AP_ENB, - NULL,0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", - eNB_ue_s1ap_id); - - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids( - RC.rrc[ctxt_pP->module_id], - 0, - eNB_ue_s1ap_id); - if (NULL != rrc_ue_s1ap_ids) { - rrc_eNB_S1AP_remove_ue_ids( - RC.rrc[ctxt_pP->module_id], - rrc_ue_s1ap_ids); - } - } -#endif -#endif -#else - ue_to_be_removed = ue_context_p; -#endif - ue_context_p->ue_context.ue_release_timer_s1 = 0; - break; - } - } - - if (ue_context_p->ue_context.ue_release_timer_rrc>0) { - ue_context_p->ue_context.ue_release_timer_rrc++; - if (ue_context_p->ue_context.ue_release_timer_rrc >= - ue_context_p->ue_context.ue_release_timer_thres_rrc) { - LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_release_timer_rrc = 0; - break; - } - } - pthread_mutex_lock(&rrc_release_freelist); - if(rrc_release_info.num_UEs > 0){ - uint16_t release_total = 0; - for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ - release_total++; - } - if( (rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && - (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)){ - ue_context_p->ue_context.ue_release_timer_rrc = 1; - ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; -#if defined(ENABLE_USE_MME) -#if defined(ENABLE_ITTI) - int e_rab; - MessageDef *msg_complete_p = NULL; - MessageDef *msg_delete_tunnels_p = NULL; - uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 4){ - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_S1AP_ENB, - NULL,0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", - eNB_ue_s1ap_id); - msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); - S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); - } - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - // do not wait response - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = - ue_context_p->ue_context.enb_gtp_ebi[e_rab]; - // erase data - ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); - ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; - } - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids( - RC.rrc[ctxt_pP->module_id], - 0, - eNB_ue_s1ap_id); - if (NULL != rrc_ue_s1ap_ids) { - rrc_eNB_S1AP_remove_ue_ids( - RC.rrc[ctxt_pP->module_id], - rrc_ue_s1ap_ids); - } -#endif -#endif - rrc_release_info.RRC_release_ctrl[release_num].flag = 0; - rrc_release_info.num_UEs--; - break; - } - if(release_total >= rrc_release_info.num_UEs) - break; - } - } - pthread_mutex_unlock(&rrc_release_freelist); - - if (ue_context_p->ue_context.ue_reestablishment_timer>0) { - ue_context_p->ue_context.ue_reestablishment_timer++; - if (ue_context_p->ue_context.ue_reestablishment_timer >= - ue_context_p->ue_context.ue_reestablishment_timer_thres) { - LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ul_failure_timer = 20000; - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - break; - } - } - - if (ue_context_p->ue_context.ue_release_timer>0) { - ue_context_p->ue_context.ue_release_timer++; - if (ue_context_p->ue_context.ue_release_timer >= - ue_context_p->ue_context.ue_release_timer_thres) { - LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_release_timer = 0; - break; - } - } - } - if (ue_to_be_removed) { - if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { - ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; - ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 200; - ue_to_be_removed->ue_context.ue_release_timer = 0; - ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; - } - rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed); - if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000){ - ue_to_be_removed->ue_context.ul_failure_timer = 0; - } - } -#ifdef RRC_LOCALIZATION - - /* for the localization, only primary CC_id might be relevant*/ - gettimeofday(&ts, NULL); - current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; - ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt = *ctxt_pP; - ctxt.rnti = ue_context_p->ue_context.rnti; - estimated_distance = rrc_get_estimated_ue_distance( - &ctxt, - CC_id, - RC.rrc[ctxt_pP->module_id]->loc_type); - - if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && - estimated_distance != -1) { - LOG_D(LOCALIZE, " RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", - ctxt.rnti, - ctxt_pP->module_id, - current_timestamp_ms, - ctxt_pP->frame, - estimated_distance); - LOG_D(LOCALIZE, " RRC status %d\n", ue_context_p->ue_context.Status); - push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, - estimated_distance); - RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; - } - } - -#endif - (void)ts; /* remove gcc warning "unused variable" */ - (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ - (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - return (RRC_OK); -} - -//----------------------------------------------------------------------------- -long -binary_search_int( - int elements[], - long numElem, - int value -) -//----------------------------------------------------------------------------- -{ - long first, last, middle, search = -1; - first = 0; - last = numElem-1; - middle = (first+last)/2; - - if(value < elements[0]) { - return first; - } - - if(value > elements[last]) { - return last; - } - - while (first <= last) { - if (elements[middle] < value) { - first = middle+1; - } else if (elements[middle] == value) { - search = middle+1; - break; - } else { - last = middle -1; - } - - middle = (first+last)/2; - } - - if (first > last) { - LOG_E(RRC,"Error in binary search!"); - } - - return search; -} - -/* This is a binary search routine which operates on an array of floating - point numbers and returns the index of the range the value lies in - Used for RSRP and RSRQ measurement mapping. Can potentially be used for other things -*/ -//----------------------------------------------------------------------------- -long -binary_search_float( - float elements[], - long numElem, - float value -) -//----------------------------------------------------------------------------- -{ - long first, last, middle; - first = 0; - last = numElem-1; - middle = (first+last)/2; - - if(value <= elements[0]) { - return first; - } - - if(value >= elements[last]) { - return last; - } - - while (last - first > 1) { - if (elements[middle] > value) { - last = middle; - } else { - first = middle; - } - - middle = (first+last)/2; - } - - if (first < 0 || first >= numElem) { - LOG_E(RRC,"\n Error in binary search float!"); - } - - return first; -} - diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c similarity index 53% rename from openair2/RRC/LITE/L2_interface.c rename to openair2/RRC/LTE/L2_interface.c index 90c447c763bf438ac8437666b4d7a2a6f57783e5..d0e185ca9dc70faad3b94b87caf0119472b66986 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -29,34 +29,23 @@ */ #include "platform_types.h" -//#include "openair_defs.h" -//#include "openair_proto.h" -#include "defs.h" -#include "extern.h" -//#include "mac_lchan_interface.h" -//#include "openair_rrc_utils.h" -//#include "openair_rrc_main.h" +#include "rrc_defs.h" +#include "rrc_extern.h" #include "UTIL/LOG/log.h" #include "rrc_eNB_UE_context.h" #include "pdcp.h" #include "msc.h" #include "common/ran_context.h" -#ifdef PHY_EMUL -#include "SIMULATION/simulation_defs.h" -extern EMULATION_VARS *Emul_vars; -extern eNB_MAC_INST *eNB_mac_inst; -extern UE_MAC_INST *UE_mac_inst; -#endif - #if defined(ENABLE_ITTI) # include "intertask_interface.h" #endif +#include "flexran_agent_extern.h" + //#define RRC_DATA_REQ_DEBUG //#define DEBUG_RRC 1 -mui_t mui=0; extern RAN_CONTEXT_t RC; @@ -69,8 +58,6 @@ mac_rrc_data_req( const rb_id_t Srb_id, const uint8_t Nb_tb, uint8_t* const buffer_pP, - const eNB_flag_t enb_flagP, - const uint8_t eNB_index, const uint8_t mbsfn_sync_area ) //-------------------------------------------------------------------------- @@ -90,7 +77,6 @@ mac_rrc_data_req( rrc_eNB_carrier_data_t *carrier; BCCH_BCH_Message_t *mib; - if( enb_flagP == ENB_FLAG_YES) { rrc = RC.rrc[Mod_idP]; carrier = &rrc->carrier[0]; @@ -287,7 +273,7 @@ mac_rrc_data_req( return (Sdu_size); } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if((Srb_id & RAB_OFFSET) == MCCH) { if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) { @@ -340,9 +326,9 @@ mac_rrc_data_req( //return(0); } -#endif //Rel10 || Rel14 +#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR){ memcpy(&buffer_pP[0], RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR, @@ -359,48 +345,6 @@ mac_rrc_data_req( #endif - } else { //This is an UE - - - LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); - LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); - - - if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; - int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); - - if (ccch_size > sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); - ccch_size = sdu_size; - } - - message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ); - RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP; - RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size; - memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload, ccch_size); - RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index; - - itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); - } -#endif - - memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); - uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; - // UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0; - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active = 1; - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_cnt = 0; - // msg("[RRC][UE %d] Sending rach\n",Mod_id); - return(Ret_size); - } else { - return 0; - } - } return(0); } @@ -416,8 +360,6 @@ mac_rrc_data_ind( const rb_id_t srb_idP, const uint8_t* sduP, const sdu_size_t sdu_lenP, - const eNB_flag_t eNB_flagP, - const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP ) //-------------------------------------------------------------------------- @@ -432,114 +374,8 @@ mac_rrc_data_ind( /* int si_window; */ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, eNB_flagP, rntiP, frameP, sub_frameP,eNB_indexP); - - if(eNB_flagP == ENB_FLAG_NO) { - if(srb_idP == BCCH) { - LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu); - - if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); - sdu_size = msg_sdu_size; - } else { - sdu_size = sdu_lenP; - } - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND); - memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); - RRC_MAC_BCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; - memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size); - RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_BCCH_DATA_IND (message_p).rsrq = 30 /* TODO change phy to report rspq */; - RRC_MAC_BCCH_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; - - itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); - } -#else - decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP, 0, 0); -#endif - } - - if(srb_idP == PCCH) { - LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); - decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP); - } - if((srb_idP & RAB_OFFSET) == CCCH) { - if (sdu_lenP>0) { - LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0); -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int msg_sdu_size = CCCH_SDU_SIZE; - - if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } else { - sdu_size = sdu_lenP; - } - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND); - memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); - RRC_MAC_CCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; - RRC_MAC_CCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_CCCH_DATA_IND (message_p).rnti = rntiP; - itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); - } -#else - Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; - memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); - Srb_info->Rx_buffer.payload_size = sdu_lenP; - rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP); -#endif - } - } - -#if defined(Rel10) || defined(Rel14) - - if ((srb_idP & RAB_OFFSET) == MCCH) { - LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", - module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); - - if (sdu_size > msg_sdu_size) { - LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND); - RRC_MAC_MCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_MCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_MCCH_DATA_IND (message_p).sdu_size = sdu_lenP; - memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE); - memcpy (RRC_MAC_MCCH_DATA_IND (message_p).sdu, sduP, sdu_lenP); - RRC_MAC_MCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP; - itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); - } -#else - decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP); -#endif - } - -#endif // Rel10 || Rel14 - - } else { // This is an eNB if((srb_idP & RAB_OFFSET) == CCCH) { Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0; LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id); @@ -587,210 +423,11 @@ mac_rrc_data_ind( } } #endif - } return(0); } -//-------------------------------------------------------------------------------------------// -// this function is Not USED anymore -void mac_sync_ind(module_id_t Mod_idP,uint8_t Status) -{ - //-------------------------------------------------------------------------------------------// -} - -//------------------------------------------------------------------------------ -uint8_t -rrc_data_req( - const protocol_ctxt_t* const ctxt_pP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, - const pdcp_transmission_mode_t modeP -) -//------------------------------------------------------------------------------ -{ - if(sdu_sizeP == 255) - { - LOG_I(RRC,"sdu_sizeP == 255"); - return FALSE; - } - MSC_LOG_TX_MESSAGE( - ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE, - ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE, - buffer_pP, - sdu_sizeP, - MSC_AS_TIME_FMT"RRC_DCCH_DATA_REQ UE %x MUI %d size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt_pP->rnti, - muiP, - sdu_sizeP); - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). - uint8_t *message_buffer; - - message_buffer = itti_malloc ( - ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, - ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, - sdu_sizeP); - - memcpy (message_buffer, buffer_pP, sdu_sizeP); - - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); - RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; - RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; - RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; - RRC_DCCH_DATA_REQ (message_p).muip = muiP; - RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; - RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; - RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; - RRC_DCCH_DATA_REQ (message_p).mode = modeP; - RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; - RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; - RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; - - itti_send_msg_to_task ( - ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, - ctxt_pP->instance, - message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. - - } -#else - return pdcp_data_req ( - ctxt_pP, - SRB_FLAG_YES, - rb_idP, - muiP, - confirmP, - sdu_sizeP, - buffer_pP, - modeP); -#endif -} - -//------------------------------------------------------------------------------ -void -rrc_data_ind( - const protocol_ctxt_t* const ctxt_pP, - const rb_id_t Srb_id, - const sdu_size_t sdu_sizeP, - const uint8_t* const buffer_pP -) -//------------------------------------------------------------------------------ -{ - rb_id_t DCCH_index = Srb_id; - - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - LOG_N(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", - ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); - } else { - LOG_N(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n", - ctxt_pP->module_id, - ctxt_pP->frame, - DCCH_index, - Srb_id, - sdu_sizeP, - ctxt_pP->rnti); - } - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). - uint8_t *message_buffer; - - message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); - memcpy (message_buffer, buffer_pP, sdu_sizeP); - - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); - RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; - RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; - RRC_DCCH_DATA_IND (message_p).sdu_size = sdu_sizeP; - RRC_DCCH_DATA_IND (message_p).sdu_p = message_buffer; - RRC_DCCH_DATA_IND (message_p).rnti = ctxt_pP->rnti; - RRC_DCCH_DATA_IND (message_p).module_id = ctxt_pP->module_id; - RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; - - itti_send_msg_to_task (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->instance, message_p); - } -#else - - if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - rrc_eNB_decode_dcch( - ctxt_pP, - DCCH_index, - buffer_pP, - sdu_sizeP); - } else { -//#warning "LG put 0 to arg4 that is eNB index" - rrc_ue_decode_dcch( - ctxt_pP, - DCCH_index, - buffer_pP, - 0); - } - -#endif -} - -//-------------------------------------------------------------------------------------------// -void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) -{ - //-------------------------------------------------------------------------------------------// -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - //LOG_I(RRC,"sending a message to task_mac_ue\n"); - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_IN_SYNC_IND); - RRC_MAC_IN_SYNC_IND (message_p).frame = frameP; - RRC_MAC_IN_SYNC_IND (message_p).enb_index = eNB_index; - - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); - } -#else - UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt=0; - - if (UE_rrc_inst[Mod_idP].Info[eNB_index].T310_active==1) { - UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt++; - } - -#endif -} - -//-------------------------------------------------------------------------------------------// -void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) -{ - //-------------------------------------------------------------------------------------------// - if (UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt>10) - LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ", - Mod_idP,frameP,eNB_index, - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active, - UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt, - UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt, - UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt); - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_OUT_OF_SYNC_IND); - RRC_MAC_OUT_OF_SYNC_IND (message_p).frame = frameP; - RRC_MAC_OUT_OF_SYNC_IND (message_p).enb_index = eNB_index; - - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); - } -#else - UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt++; -#endif -} - //------------------------------------------------------------------------------ int mac_eNB_get_rrc_status( @@ -830,6 +467,11 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, else { LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); } + if (rrc_agent_registered[Mod_instP]) { + agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP, + rntiP, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } // rrc_mac_remove_ue(Mod_instP,rntiP); } @@ -874,36 +516,3 @@ void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, frameP, subframeP, rntiP); } } -//------------------------------------------------------------------------------ -int -mac_UE_get_rrc_status( - const module_id_t Mod_idP, - const uint8_t indexP -) -//------------------------------------------------------------------------------ -{ - if (UE_rrc_inst) - return(UE_rrc_inst[Mod_idP].Info[indexP].State); - else - return(-1); -} - -//-------------------------------------------------------------------------------------------// -int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) -{ - //-------------------------------------------------------------------------------------------// -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_CNF); - RRC_MAC_CCCH_DATA_CNF (message_p).enb_index = eNB_index; - - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); - } -#else - // reset the tx buffer to indicate RRC that ccch was successfully transmitted (for example if contention resolution succeeds) - UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size=0; -#endif - return 0; -} diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c new file mode 100644 index 0000000000000000000000000000000000000000..155c0ebb90e10e58c83bef13daaa138c2dfc198a --- /dev/null +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -0,0 +1,176 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 l2_interface.c + * \brief layer 2 interface, used to support different RRC sublayer + * \author Raymond Knopp and Navid Nikaein + * \date 2010-2014 + * \version 1.0 + * \company Eurecom + * \email: raymond.knopp@eurecom.fr + */ + +#include "platform_types.h" +#include "rrc_defs.h" +#include "rrc_extern.h" +#include "UTIL/LOG/log.h" +#include "rrc_eNB_UE_context.h" +#include "pdcp.h" +#include "msc.h" +#include "common/ran_context.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +//#define RRC_DATA_REQ_DEBUG +//#define DEBUG_RRC 1 + +//------------------------------------------------------------------------------ +uint8_t +rrc_data_req( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP +) +//------------------------------------------------------------------------------ +{ + if(sdu_sizeP == 255) + { + LOG_I(RRC,"sdu_sizeP == 255"); + return FALSE; + } + MSC_LOG_TX_MESSAGE( + ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE, + ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE, + buffer_pP, + sdu_sizeP, + MSC_AS_TIME_FMT"RRC_DCCH_DATA_REQ UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->rnti, + muiP, + sdu_sizeP); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + + message_buffer = itti_malloc ( + ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + sdu_sizeP); + + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); + RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; + RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; + RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; + RRC_DCCH_DATA_REQ (message_p).muip = muiP; + RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; + RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; + RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; + RRC_DCCH_DATA_REQ (message_p).mode = modeP; + RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; + RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; + RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task ( + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + ctxt_pP->instance, + message_p); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + + } +#else + return pdcp_data_req ( + ctxt_pP, + SRB_FLAG_YES, + rb_idP, + muiP, + confirmP, + sdu_sizeP, + buffer_pP, + modeP); +#endif +} + +//------------------------------------------------------------------------------ +void +rrc_data_ind( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t Srb_id, + const sdu_size_t sdu_sizeP, + const uint8_t* const buffer_pP +) +//------------------------------------------------------------------------------ +{ + rb_id_t DCCH_index = Srb_id; + + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + LOG_N(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", + ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); + } else { + LOG_N(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n", + ctxt_pP->module_id, + ctxt_pP->frame, + DCCH_index, + Srb_id, + sdu_sizeP, + ctxt_pP->rnti); + } + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + + message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); + RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; + RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; + RRC_DCCH_DATA_IND (message_p).sdu_size = sdu_sizeP; + RRC_DCCH_DATA_IND (message_p).sdu_p = message_buffer; + RRC_DCCH_DATA_IND (message_p).rnti = ctxt_pP->rnti; + RRC_DCCH_DATA_IND (message_p).module_id = ctxt_pP->module_id; + RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->instance, message_p); + } +#else + + rrc_eNB_decode_dcch( + ctxt_pP, + DCCH_index, + buffer_pP, + sdu_sizeP); + +#endif +} diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..569e2f008b13dcc0db29f65e42f266efcb176ba3 --- /dev/null +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -0,0 +1,472 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 l2_interface.c + * \brief layer 2 interface, used to support different RRC sublayer + * \author Raymond Knopp and Navid Nikaein + * \date 2010-2014 + * \version 1.0 + * \company Eurecom + * \email: raymond.knopp@eurecom.fr + */ + +#include "platform_types.h" +#include "rrc_defs.h" +#include "rrc_extern.h" +#include "UTIL/LOG/log.h" +#include "rrc_eNB_UE_context.h" +#include "pdcp.h" +#include "msc.h" + + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +//#define RRC_DATA_REQ_DEBUG +//#define DEBUG_RRC 1 + + + +//------------------------------------------------------------------------------ +int8_t +mac_rrc_data_req_ue( + const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const rb_id_t Srb_id, + const uint8_t Nb_tb, + uint8_t* const buffer_pP, + const uint8_t eNB_index, + const uint8_t mbsfn_sync_area +) +//-------------------------------------------------------------------------- +{ + +#ifdef DEBUG_RRC + int i; + LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); +#endif + + +#ifdef Rel14 + LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id); + LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); + + //TTN (for D2D) + if (Srb_id == SL_DISCOVERY && UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size > 0){ + memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); + uint8_t Ret_size=UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size; + LOG_I(RRC,"[UE %d] Sending SL_Discovery, size %d bytes\n",Mod_idP,Ret_size); + UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size = 0; + return(Ret_size); + } +#endif + + LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); + LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); + + if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; + int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); + + if (ccch_size > sdu_size) { + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); + ccch_size = sdu_size; + } + + message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ); + RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP; + RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size; + memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload, ccch_size); + RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index; + + itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); + } +#endif + + memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); + uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; + // UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0; + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active = 1; + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_cnt = 0; + // msg("[RRC][UE %d] Sending rach\n",Mod_id); + return(Ret_size); + } else { + return 0; + } + + return(0); +} + +//------------------------------------------------------------------------------ +int8_t +mac_rrc_data_ind_ue( + const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const rnti_t rntiP, + const rb_id_t srb_idP, + const uint8_t* sduP, + const sdu_size_t sdu_lenP, + const mac_enb_index_t eNB_indexP, + const uint8_t mbsfn_sync_areaP +) +//-------------------------------------------------------------------------- +{ + protocol_ctxt_t ctxt; + sdu_size_t sdu_size = 0; + + /* for no gcc warnings */ + (void)sdu_size; + + /* + int si_window; + */ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, 0, rntiP, frameP, sub_frameP,eNB_indexP); + + if(srb_idP == BCCH) { + LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu); + + if (sdu_lenP > msg_sdu_size) { + LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = sdu_lenP; + } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND); + memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); + RRC_MAC_BCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; + memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size); + RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_BCCH_DATA_IND (message_p).rsrq = 30 /* TODO change phy to report rspq */; + RRC_MAC_BCCH_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; + + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } +#else + decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP, 0, 0); +#endif + } + + if(srb_idP == PCCH) { + LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP); + } + if((srb_idP & RAB_OFFSET) == CCCH) { + if (sdu_lenP>0) { + LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + int msg_sdu_size = CCCH_SDU_SIZE; + + if (sdu_lenP > msg_sdu_size) { + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = sdu_lenP; + } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND); + memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); + RRC_MAC_CCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; + RRC_MAC_CCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_CCCH_DATA_IND (message_p).rnti = rntiP; + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } +#else + SRB_INFO *Srb_info; + Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; + memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); + Srb_info->Rx_buffer.payload_size = sdu_lenP; + rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP); +#endif + } + } + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + if ((srb_idP & RAB_OFFSET) == MCCH) { + LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", + module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); + + if (sdu_size > msg_sdu_size) { + LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; + } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND); + RRC_MAC_MCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_MCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_MCCH_DATA_IND (message_p).sdu_size = sdu_lenP; + memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE); + memcpy (RRC_MAC_MCCH_DATA_IND (message_p).sdu, sduP, sdu_lenP); + RRC_MAC_MCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP; + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } +#else + decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP); +#endif + } + //TTN (for D2D) + if(srb_idP == SL_DISCOVERY) { + LOG_I(RRC,"[UE %d] Received SDU (%d bytes) for SL_DISCOVERY on SRB %d from eNB %d\n",module_idP, sdu_lenP, srb_idP,eNB_indexP); + decode_SL_Discovery_Message(&ctxt, eNB_indexP, sduP, sdu_lenP); + } + +#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + return(0); + +} + + +//------------------------------------------------------------------------------ +uint8_t +rrc_data_req_ue( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP +) +//------------------------------------------------------------------------------ +{ + MSC_LOG_TX_MESSAGE( + ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE, + ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE, + buffer_pP, + sdu_sizeP, + MSC_AS_TIME_FMT"RRC_DCCH_DATA_REQ UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->rnti, + muiP, + sdu_sizeP); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + + message_buffer = itti_malloc ( + ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + sdu_sizeP); + + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); + RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; + RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; + RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; + RRC_DCCH_DATA_REQ (message_p).muip = muiP; + RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; + RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; + RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; + RRC_DCCH_DATA_REQ (message_p).mode = modeP; + RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; + RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; + RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task ( + TASK_PDCP_UE, + ctxt_pP->instance, + message_p); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + + } +#else + return pdcp_data_req ( + ctxt_pP, + SRB_FLAG_YES, + rb_idP, + muiP, + confirmP, + sdu_sizeP, + buffer_pP, + modeP +#ifdef Rel14 + ,NULL, NULL +#endif + ); +#endif +} + +//------------------------------------------------------------------------------ +void +rrc_data_ind_ue( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t Srb_id, + const sdu_size_t sdu_sizeP, + const uint8_t* const buffer_pP +) +//------------------------------------------------------------------------------ +{ + rb_id_t DCCH_index = Srb_id; + + LOG_N(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", + ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + + message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); + RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; + RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; + RRC_DCCH_DATA_IND (message_p).sdu_size = sdu_sizeP; + RRC_DCCH_DATA_IND (message_p).sdu_p = message_buffer; + RRC_DCCH_DATA_IND (message_p).rnti = ctxt_pP->rnti; + RRC_DCCH_DATA_IND (message_p).module_id = ctxt_pP->module_id; + RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task (TASK_RRC_UE, ctxt_pP->instance, message_p); + } +#else + +//#warning "LG put 0 to arg4 that is eNB index" + rrc_ue_decode_dcch( + ctxt_pP, + DCCH_index, + buffer_pP, + 0); + +#endif +} + +//-------------------------------------------------------------------------------------------// +void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) +{ + //-------------------------------------------------------------------------------------------// +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + //LOG_I(RRC,"sending a message to task_mac_ue\n"); + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_IN_SYNC_IND); + RRC_MAC_IN_SYNC_IND (message_p).frame = frameP; + RRC_MAC_IN_SYNC_IND (message_p).enb_index = eNB_index; + + itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); + } +#else + UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt=0; + + if (UE_rrc_inst[Mod_idP].Info[eNB_index].T310_active==1) { + LOG_D(RRC, "Panos-D: rrc_in_sync_ind 1 \n"); + UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt++; + } + +#endif +} + +//-------------------------------------------------------------------------------------------// +void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) +{ + //-------------------------------------------------------------------------------------------// + if (UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt>10) + LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ", + Mod_idP,frameP,eNB_index, + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active, + UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt, + UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt, + UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_OUT_OF_SYNC_IND); + RRC_MAC_OUT_OF_SYNC_IND (message_p).frame = frameP; + RRC_MAC_OUT_OF_SYNC_IND (message_p).enb_index = eNB_index; + + itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); + } +#else + UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt++; +#endif +} + +//------------------------------------------------------------------------------ +int +mac_UE_get_rrc_status( + const module_id_t Mod_idP, + const uint8_t indexP +) +//------------------------------------------------------------------------------ +{ + if (UE_rrc_inst) + return(UE_rrc_inst[Mod_idP].Info[indexP].State); + else + return(-1); +} + +//-------------------------------------------------------------------------------------------// +int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) +{ + //-------------------------------------------------------------------------------------------// +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_CNF); + RRC_MAC_CCCH_DATA_CNF (message_p).enb_index = eNB_index; + + itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); + } +#else + // reset the tx buffer to indicate RRC that ccch was successfully transmitted (for example if contention resolution succeeds) + UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size=0; +#endif + return 0; +} diff --git a/openair2/RRC/LITE/MESSAGES/Makefile.inc b/openair2/RRC/LTE/MESSAGES/Makefile.inc similarity index 100% rename from openair2/RRC/LITE/MESSAGES/Makefile.inc rename to openair2/RRC/LTE/MESSAGES/Makefile.inc diff --git a/openair2/RRC/LITE/MESSAGES/README.txt b/openair2/RRC/LTE/MESSAGES/README.txt similarity index 100% rename from openair2/RRC/LITE/MESSAGES/README.txt rename to openair2/RRC/LTE/MESSAGES/README.txt diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c similarity index 73% rename from openair2/RRC/LITE/MESSAGES/asn1_msg.c rename to openair2/RRC/LTE/MESSAGES/asn1_msg.c index 934df18fbca060189526d425cf672a5b0b4e03ed..77af49775ac67f3d5ebdb89414c8b4c9ab0fe762 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -52,13 +52,13 @@ #include "RRCConnectionSetup.h" #include "SRB-ToAddModList.h" #include "DRB-ToAddModList.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "MCCH-Message.h" //#define MRB1 1 #endif -#include "RRC/LITE/defs.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_defs.h" +#include "RRC/LTE/rrc_extern.h" #include "RRCConnectionSetupComplete.h" #include "RRCConnectionReconfigurationComplete.h" #include "RRCConnectionReconfiguration.h" @@ -70,8 +70,10 @@ #include "SIB-Type.h" #include "BCCH-DL-SCH-Message.h" +#include "SBCCH-SL-BCH-MessageType.h" +#include "SBCCH-SL-BCH-Message.h" -#include "PHY/defs.h" +//#include "PHY/defs.h" #include "MeasObjectToAddModList.h" #include "ReportConfigToAddModList.h" @@ -229,7 +231,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich mib->message.systemFrameNumber.size = 1; mib->message.systemFrameNumber.bits_unused=0; mib->message.spare.buf = (uint8_t *)spare; -#ifndef Rel14 +#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) mib->message.spare.size = 2; mib->message.spare.bits_unused = 6; // This makes a spare of 10 bits #else @@ -272,6 +274,67 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich return((enc_rval.encoded+7)/8); } +//TTN for D2D +// 3GPP 36.331 (Section 5.10.7.4) +uint8_t do_MIB_SL(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, uint32_t frame, uint8_t subframe, uint8_t in_coverage, uint8_t mode) +{ + + asn_enc_rval_t enc_rval; + SBCCH_SL_BCH_MessageType_t *mib_sl = &UE_rrc_inst[ctxt_pP->module_id].mib_sl[eNB_index]; + uint8_t sfn = (uint8_t)((frame>>2)&0xff); + UE_rrc_inst[ctxt_pP->module_id].MIB = (uint8_t*) malloc16(4); + + if (in_coverage > 0 ){ + //in coverage + mib_sl->inCoverage_r12 = TRUE; + mib_sl->sl_Bandwidth_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth; + if (UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config) { + mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config->subframeAssignment; + } else { + mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; + } + //if triggered by sl communication + if (UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12){ + mib_sl->reserved_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12; + } + //if triggered by sl discovery + if (UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12){ + mib_sl->reserved_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12; + } + //Todo - if triggered by v2x + } else { + //Todo - out of coverage for V2X + // Todo - UE has a selected SyncRef UE + mib_sl->inCoverage_r12 = FALSE; + //set sl-Bandwidth, subframeAssignmentSL and reserved from the pre-configured parameters + } + + //set FrameNumber, subFrameNumber + mib_sl->directFrameNumber_r12.buf = &sfn; + mib_sl->directFrameNumber_r12.size = 1; + mib_sl->directFrameNumber_r12.bits_unused=0; + mib_sl->directSubframeNumber_r12 = subframe; + + + LOG_I(RRC,"[MIB-SL] sfn %x, subframe %x\n", (uint32_t)sfn, (uint8_t)subframe); + + + enc_rval = uper_encode_to_buffer(&asn_DEF_SBCCH_SL_BCH_Message, + (void*)mib_sl, + UE_rrc_inst[ctxt_pP->module_id].MIB, + 24); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + + uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, int Mod_id,int CC_id #if defined(ENABLE_ITTI) @@ -414,6 +477,22 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,&sib_type); ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo); +#if 0 + /* TODO: this is disabled for the moment because OAI UE does + * not connect to OAI eNB with the current software. + * See also TODO comment in do_SIB23. + */ + //TTN - This is for SIB18 + sib_type=SIB_Type_sibType18_v1250; + ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,&sib_type); + ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo); + + //TTN - This is for SIB19 + sib_type=SIB_Type_sibType19_v1250; + ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,&sib_type); + ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo); +#endif + // ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,NULL); #if defined(ENABLE_ITTI) @@ -487,8 +566,22 @@ uint8_t do_SIB23(uint8_t Mod_id, #endif ) { + struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; -#if defined(Rel10) || defined(Rel14) + +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + //TTN - for D2D + struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib18_part, *sib19_part, *sib21_part; + SL_CommRxPoolList_r12_t *SL_CommRxPoolList; //for SIB18 + struct SL_CommResourcePool_r12 *SL_CommResourcePool; //for SIB18 + SL_DiscRxPoolList_r12_t *SL_DiscRxPoolList; //for SIB19 (discRxPool) + struct SL_DiscResourcePool_r12 *SL_DiscResourcePool; //for SIB19 (discRxPool) + //SL_DiscRxPoolList_r12_t *SL_DiscRxPoolPSList; //for SIB19 (discRxPoolPS) + //struct SL_DiscResourcePool_r12 *SL_DiscResourcePoolPS; //for SIB19 (discRxPoolPS) + //struct SL_V2X_ConfigCommon_r14 *SL_V2X_ConfigCommon; +#endif + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part; MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList; MBSFN_AreaInfoList_r9_t *MBSFNArea_list; @@ -500,11 +593,18 @@ uint8_t do_SIB23(uint8_t Mod_id, BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; SystemInformationBlockType2_t **sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; SystemInformationBlockType3_t **sib3 = &RC.rrc[Mod_id]->carrier[CC_id].sib3; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; uint8_t MBMS_flag = RC.rrc[Mod_id]->carrier[CC_id].MBMS_flag; #endif +#if defined(Rel10) || defined(Rel14) + //TTN - for D2D + SystemInformationBlockType18_r12_t **sib18 = &RC.rrc[Mod_id]->carrier[CC_id].sib18; + SystemInformationBlockType19_r12_t **sib19 = &RC.rrc[Mod_id]->carrier[CC_id].sib19; + SystemInformationBlockType21_r14_t **sib21 = &RC.rrc[Mod_id]->carrier[CC_id].sib21; +#endif + if (bcch_message) { memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_t)); } else { @@ -522,7 +622,7 @@ uint8_t do_SIB23(uint8_t Mod_id, exit(-1); } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[eNB %d] Configuration SIB2/3, MBMS = %d\n", Mod_id, MBMS_flag); #else LOG_I(RRC,"[eNB %d] Configuration SIB2/3\n", Mod_id); @@ -538,7 +638,7 @@ uint8_t do_SIB23(uint8_t Mod_id, *sib2 = &sib2_part->choice.sib2; *sib3 = &sib3_part->choice.sib3; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { sib13_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); @@ -549,10 +649,30 @@ uint8_t do_SIB23(uint8_t Mod_id, #endif +#if defined(Rel10) || defined(Rel14) + //TTN - for D2D + sib18_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib19_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib21_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib18_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib19_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib21_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + + sib18_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250; + sib19_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250; + sib21_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430; + + *sib18 = &sib18_part->choice.sib18_v1250; + *sib19 = &sib19_part->choice.sib19_v1250; + *sib21 = &sib21_part->choice.sib21_v1430; + +#endif + + // sib2 (*sib2)->ac_BarringInfo = NULL; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #if 0 (*sib2)->ssac_BarringForMMTEL_Voice_r9 = NULL; (*sib2)->ssac_BarringForMMTEL_Video_r9 = NULL; @@ -641,7 +761,7 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->pucch_nRB_CQI[CC_id]; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN = configuration->pucch_nCS_AN[CC_id]; -//#if !defined(Rel10) && !defined(Rel14) +//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN = configuration->pucch_n1_AN[CC_id]; //#endif @@ -799,7 +919,7 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->freqInfo.ul_Bandwidth = NULL; // (*sib2)->mbsfn_SubframeConfigList = NULL; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2\n"); @@ -848,7 +968,7 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->timeAlignmentTimerCommon=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; /// (*SIB3) -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (*sib3)->ext1 = NULL; #if 0 (*sib3)->s_IntraSearch_v920=NULL; @@ -876,14 +996,14 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib3)->intraFreqCellReselectionInfo.presenceAntennaPort1 = 0; (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf = CALLOC(8,1); (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.size = 1; - (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf[0] = 1; + (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf[0] = 1 << 6; (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.bits_unused = 6; (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA = 1; (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF = (struct SpeedStateScaleFactors *)NULL; // SIB13 // fill in all elements of SIB13 if present -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0 ) { // Notification for mcch change @@ -942,6 +1062,298 @@ uint8_t do_SIB23(uint8_t Mod_id, #endif + +#if defined(Rel10) || defined(Rel14) + //TTN - for D2D + // SIB18 + //commRxPool_r12 + (*sib18)->commConfig_r12 = CALLOC (1, sizeof(*(*sib18)->commConfig_r12)); + SL_CommRxPoolList= &(*sib18)->commConfig_r12->commRxPool_r12; + memset(SL_CommRxPoolList,0,sizeof(*SL_CommRxPoolList)); + + SL_CommResourcePool = CALLOC(1, sizeof(*SL_CommResourcePool)); + memset(SL_CommResourcePool,0,sizeof(*SL_CommResourcePool)); + + SL_CommResourcePool->sc_CP_Len_r12 = configuration->rxPool_sc_CP_Len[CC_id]; + SL_CommResourcePool->sc_Period_r12 = configuration->rxPool_sc_Period[CC_id]; + SL_CommResourcePool->data_CP_Len_r12 = configuration->rxPool_data_CP_Len[CC_id]; + //sc_TF_ResourceConfig_r12 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.prb_Num_r12 = configuration->rxPool_ResourceConfig_prb_Num[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.prb_Start_r12 = configuration->rxPool_ResourceConfig_prb_Start[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.prb_End_r12 = configuration->rxPool_ResourceConfig_prb_End[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = configuration->rxPool_ResourceConfig_offsetIndicator_present[CC_id]; + + if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_small_r12 ) { + SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_large_r12 ){ + SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + } + + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = configuration->rxPool_ResourceConfig_subframeBitmap_present[CC_id]; + if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs4_r12){ + //for BS4 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs8_r12){ + //for BS8 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs12_r12){ + //for BS12 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs16_r12){ + //for BS16 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs30_r12){ + //for BS30 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs40_r12){ + //for BS40 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs42_r12){ + //for BS42 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } + + //dataHoppingConfig_r12 + SL_CommResourcePool->dataHoppingConfig_r12.hoppingParameter_r12 = 0; + SL_CommResourcePool->dataHoppingConfig_r12.numSubbands_r12 = SL_HoppingConfigComm_r12__numSubbands_r12_ns1; + SL_CommResourcePool->dataHoppingConfig_r12.rb_Offset_r12 = 0; + + //ue_SelectedResourceConfig_r12 + SL_CommResourcePool->ue_SelectedResourceConfig_r12 = CALLOC (1, sizeof (*SL_CommResourcePool->ue_SelectedResourceConfig_r12)); + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_End_r12 = 44; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0 ; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = 5; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = CALLOC(1,5); + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = 0; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[0] = 0xF0; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[1] = 0xFF; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[2] = 0xFF; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[3] = 0xFF; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[4] = 0xFF; + //SL_CommResourcePool->ue_SelectedResourceConfig_r12->trpt_Subset_r12 = CALLOC (1, sizeof(*SL_CommResourcePool->ue_SelectedResourceConfig_r12->trpt_Subset_r12)); + //rxParametersNCell_r12 + SL_CommResourcePool->rxParametersNCell_r12 = CALLOC (1, sizeof (*SL_CommResourcePool->rxParametersNCell_r12)); + SL_CommResourcePool->rxParametersNCell_r12->tdd_Config_r12 = CALLOC (1, sizeof (*SL_CommResourcePool->rxParametersNCell_r12->tdd_Config_r12)); + SL_CommResourcePool->rxParametersNCell_r12->tdd_Config_r12->subframeAssignment = 0 ; + SL_CommResourcePool->rxParametersNCell_r12->tdd_Config_r12->specialSubframePatterns = 0; + SL_CommResourcePool->rxParametersNCell_r12->syncConfigIndex_r12 = 0; + //txParameters_r12 + SL_CommResourcePool->txParameters_r12 = CALLOC (1, sizeof (*SL_CommResourcePool->txParameters_r12)); + SL_CommResourcePool->txParameters_r12->sc_TxParameters_r12.alpha_r12 = Alpha_r12_al0; + SL_CommResourcePool->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0; + + SL_CommResourcePool->ext1 = NULL ; + //end SL_CommResourcePool + //add SL_CommResourcePool to SL_CommRxPoolList + ASN_SEQUENCE_ADD(&SL_CommRxPoolList->list,SL_CommResourcePool); + //end commRxPool_r12 + + //TODO: commTxPoolNormalCommon_r12, similar to commRxPool_r12 + //TODO: commTxPoolExceptional_r12 + //TODO: commSyncConfig_r12 + // may add commTxResourceUC-ReqAllowed with Ext1 + (*sib18)->ext1 = NULL; + (*sib18)->lateNonCriticalExtension = NULL; + // end SIB18 + + // SIB19 + // fill in all elements of SIB19 if present + + //discConfig_r12 + (*sib19)->discConfig_r12 = CALLOC (1, sizeof(*(*sib19)->discConfig_r12)); + SL_DiscRxPoolList = &(*sib19)->discConfig_r12->discRxPool_r12; + memset(SL_DiscRxPoolList,0,sizeof(*SL_DiscRxPoolList)); + //fill SL_DiscResourcePool + SL_DiscResourcePool = CALLOC(1, sizeof(*SL_DiscResourcePool)); + + SL_DiscResourcePool->cp_Len_r12 = configuration->discRxPool_cp_Len[CC_id]; + SL_DiscResourcePool->discPeriod_r12 = configuration->discRxPool_discPeriod[CC_id]; + //sc_TF_ResourceConfig_r12 + SL_DiscResourcePool->numRetx_r12 = configuration->discRxPool_numRetx[CC_id]; + SL_DiscResourcePool->numRepetition_r12 = configuration->discRxPool_numRepetition[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.prb_Num_r12 = configuration->discRxPool_ResourceConfig_prb_Num[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.prb_Start_r12 = configuration->discRxPool_ResourceConfig_prb_Start[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.prb_End_r12 = configuration->discRxPool_ResourceConfig_prb_End[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present = configuration->discRxPool_ResourceConfig_offsetIndicator_present[CC_id]; + if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_small_r12 ) { + SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_large_r12 ){ + SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + } + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present = configuration->discRxPool_ResourceConfig_subframeBitmap_present[CC_id]; + if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs4_r12){ + //for BS4 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs8_r12){ + //for BS8 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs12_r12){ + //for BS12 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs16_r12){ + //for BS16 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs30_r12){ + //for BS30 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs40_r12){ + //for BS40 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs42_r12){ + //for BS42 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } + + //add SL_DiscResourcePool to SL_DiscRxPoolList + ASN_SEQUENCE_ADD(&SL_DiscRxPoolList->list,SL_DiscResourcePool); + +/* + //for DiscRxPoolPS + (*sib19)->ext1 = CALLOC (1, sizeof(*(*sib19)->ext1)); + (*sib19)->ext1->discConfigPS_13 = CALLOC (1, sizeof(*((*sib19)->ext1->discConfigPS_13))); + + SL_DiscRxPoolPSList = &(*sib19)->ext1->discConfigPS_13->discRxPoolPS_r13; + memset(SL_DiscRxPoolPSList,0,sizeof(*SL_DiscRxPoolPSList)); + //fill SL_DiscResourcePool + SL_DiscResourcePoolPS = CALLOC(1, sizeof(*SL_DiscResourcePoolPS)); + + SL_DiscResourcePoolPS->cp_Len_r12 = configuration->discRxPoolPS_cp_Len[CC_id]; + SL_DiscResourcePoolPS->discPeriod_r12 = configuration->discRxPoolPS_discPeriod[CC_id]; + //sc_TF_ResourceConfig_r12 + SL_DiscResourcePoolPS->numRetx_r12 = configuration->discRxPoolPS_numRetx[CC_id]; + SL_DiscResourcePoolPS->numRepetition_r12 = configuration->discRxPoolPS_numRepetition[CC_id]; + + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_Num_r12 = configuration->discRxPoolPS_ResourceConfig_prb_Num[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_Start_r12 = configuration->discRxPoolPS_ResourceConfig_prb_Start[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_End_r12 = configuration->discRxPoolPS_ResourceConfig_prb_End[CC_id]; + + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_present[CC_id]; + if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_small_r12 ) { + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_choice[CC_id] ; + } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_large_r12 ){ + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_choice[CC_id] ; + } + + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_present[CC_id]; + if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs4_r12){ + //for BS4 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs8_r12){ + //for BS8 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs12_r12){ + //for BS12 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs16_r12){ + //for BS16 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs30_r12){ + //for BS30 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs40_r12){ + //for BS40 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs42_r12){ + //for BS42 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } + + //add SL_DiscResourcePool to SL_DiscRxPoolList + ASN_SEQUENCE_ADD(&SL_DiscRxPoolPSList->list,SL_DiscResourcePoolPS); +*/ + + (*sib19)->lateNonCriticalExtension = NULL; + //end SIB19 + + //SIB21 + (*sib21)->sl_V2X_ConfigCommon_r14 = CALLOC (1, sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14)); + //SL_V2X_ConfigCommon= (*sib21)->sl_V2X_ConfigCommon_r14; + memset((*sib21)->sl_V2X_ConfigCommon_r14,0,sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14)); + + struct SL_CommRxPoolListV2X_r14 *SL_CommRxPoolListV2X; + struct SL_CommResourcePoolV2X_r14 *SL_CommResourcePoolV2X; + (*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 = CALLOC(1, sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14)); + SL_CommRxPoolListV2X = (*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14; + + SL_CommResourcePoolV2X = CALLOC(1, sizeof(*SL_CommResourcePoolV2X)); + memset(SL_CommResourcePoolV2X,0,sizeof(*SL_CommResourcePoolV2X)); + + SL_CommResourcePoolV2X->sl_OffsetIndicator_r14 = CALLOC(1, sizeof(*SL_CommResourcePoolV2X->sl_OffsetIndicator_r14)); + SL_CommResourcePoolV2X->sl_OffsetIndicator_r14->present = SL_OffsetIndicator_r12_PR_small_r12; + SL_CommResourcePoolV2X->sl_OffsetIndicator_r14->choice.small_r12 = 0; + SL_CommResourcePoolV2X->sl_Subframe_r14.present = SubframeBitmapSL_r14_PR_bs40_r14; + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.size = 5; + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf = CALLOC(1,5); + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.bits_unused = 0; + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[0] = 0xF0; + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[1] = 0xFF; + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[2] = 0xFF; + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[3] = 0xFF; + SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[4] = 0xFF; + + SL_CommResourcePoolV2X->adjacencyPSCCH_PSSCH_r14 = 1; + SL_CommResourcePoolV2X->sizeSubchannel_r14 = 10; + SL_CommResourcePoolV2X->numSubchannel_r14 = 5; + SL_CommResourcePoolV2X->startRB_Subchannel_r14 = 10; + + //rxParametersNCell_r12 + SL_CommResourcePoolV2X->rxParametersNCell_r14 = CALLOC (1, sizeof (*SL_CommResourcePoolV2X->rxParametersNCell_r14)); + SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14 = CALLOC (1, sizeof (*SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14)); + SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14->subframeAssignment = 0 ; + SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14->specialSubframePatterns = 0; + SL_CommResourcePoolV2X->rxParametersNCell_r14->syncConfigIndex_r14 = 0; + + ASN_SEQUENCE_ADD(&SL_CommRxPoolListV2X->list,SL_CommResourcePoolV2X); + //end SIB21 +#endif + + bcch_message->message.present = BCCH_DL_SCH_MessageType_PR_c1; bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType__c1_PR_systemInformation; @@ -950,7 +1362,6 @@ uint8_t do_SIB23(uint8_t Mod_id, sizeof(SystemInformation_t));*/ bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.present = SystemInformation__criticalExtensions_PR_systemInformation_r8; - bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count=0; // asn_set_empty(&systemInformation->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list);//.size=0; @@ -959,14 +1370,26 @@ uint8_t do_SIB23(uint8_t Mod_id, sib2_part); ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib3_part); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list,sib13_part); } +#if 0 + /* TODO: this is disabled for the moment. + * Maybe we shouldn't put this together with SIBs 2/3. + * The problem is that the MAC message is now 92 bytes, which + * is too much in the SIB scheduler (the scheduler allocates + * 4 RBs with max MCS 8). + */ + //for D2D + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib18_part); + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib19_part); + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib21_part); #endif +#endif #ifdef XER_PRINT xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message); @@ -1091,6 +1514,176 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) } + +//TTN for D2D - 3GPP TS 36.331 (Section 5.10.2.3) +uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) +{ + + asn_enc_rval_t enc_rval; + UL_DCCH_Message_t ul_dcch_msg; + SidelinkUEInformation_r12_t *sidelinkUEInformation; + ARFCN_ValueEUTRA_r9_t carrierFreq = 25655;//sidelink communication frequency (hardcoded - should come from SIB2) + + memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); + ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_messageClassExtension; + ul_dcch_msg.message.choice.messageClassExtension.present = UL_DCCH_MessageType__messageClassExtension_PR_c2; + ul_dcch_msg.message.choice.messageClassExtension.choice.c2.present = UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12; + sidelinkUEInformation = &ul_dcch_msg.message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12; + + //3GPP TS 36.331 (Section 5.10.2.3) + sidelinkUEInformation->criticalExtensions.present = SidelinkUEInformation_r12__criticalExtensions_PR_c1; + sidelinkUEInformation->criticalExtensions.choice.c1.present = SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12; + switch(mode) { + //if SIB18 is available + case SL_RECEIVE_COMMUNICATION: // to receive sidelink communication + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12)); + memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12, (void*)&carrierFreq, + sizeof(ARFCN_ValueEUTRA_r9_t)); + break; + + case SL_TRANSMIT_NON_RELAY_ONE_TO_MANY: //to transmit non-relay related one-to-many sidelink communication + //commTxResourceReq + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12)); + memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12, (void*)&carrierFreq, + sizeof(ARFCN_ValueEUTRA_r9_t)); + memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12, + destinationInfoList, + sizeof(SL_DestinationInfoList_r12_t)); + break; + + case SL_TRANSMIT_NON_RELAY_ONE_TO_ONE://transmit non-relay related one-to-one sidelink communication + //if commTxResourceUC-ReqAllowed is included in SIB18 + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); + + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12)); + memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12, (void*)&carrierFreq, + sizeof (ARFCN_ValueEUTRA_r9_t)); + memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12, + destinationInfoList, + sizeof(SL_DestinationInfoList_r12_t)); + break; + + case SL_TRANSMIT_RELAY_ONE_TO_ONE: //transmit relay related one-to-one sidelink communication + //if SIB19 includes discConfigRelay and UE acts a relay or UE has a selected relay + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13= CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13)); + memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12, + destinationInfoList, + sizeof(*destinationInfoList)); + //set ue-type to relayUE or remoteUE + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; + //sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12->nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_remoteUE; + break; + + case SL_TRANSMIT_RELAY_ONE_TO_MANY: //transmit relay related one-to-many sidelink communication + //if SIB19 includes discConfigRelay and UE acts a relay + //set ue-type to relayUE + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13= CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; + memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12, + destinationInfoList, + sizeof(*destinationInfoList)); + break; + + //if SIB19 is available + //we consider only one frequency - a serving frequency + case SL_RECEIVE_DISCOVERY: //receive sidelink discovery announcements + + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12)); + *sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12 = SidelinkUEInformation_r12_IEs__discRxInterest_r12_true; + break; + case SL_TRANSMIT_NON_PS_DISCOVERY://to transmit non-PS related sidelink discovery announcements + //for the first frequency + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12)); + + memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12, + (void*)discTxResourceReq, + sizeof(long)); + //for additional frequency + break; + + case SL_TRANSMIT_PS_DISCOVERY://to transmit PS related sidelink discovery announcements + //if to transmit non-relay PS related discovery announcements and SIB19 includes discConfigPS + //if UE is acting as relay UE and SIB includes discConfigRelay (relay threshold condition) + //if relay UE/has a selected relay UE and if SIB19 includes discConfigRelay + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13 = CALLOC(1, + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13 = *discTxResourceReq; + break; + //SIB21 + case SL_RECEIVE_V2X: + //TODO + break; + case SL_TRANSMIT_V2X: + //TODO + break; + //TODO: request sidelink discovery transmission/reception gaps + //TODO: report the system information parameters related to sidelink discovery of carriers other than the primary + default: + break; + } + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); +#endif + + + enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, + (void*)&ul_dcch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"SidelinkUEInformation Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); + +} + + uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) { @@ -1413,7 +2006,7 @@ do_RRCConnectionSetup( // CQI ReportConfig physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= CQI_ReportModeAperiodic_rm30; #else *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI @@ -1535,7 +2128,7 @@ do_RRCConnectionSetup( physicalConfigDedicated2->schedulingRequestConfig->present = SchedulingRequestConfig_PR_setup; if (carrier->sib1->tdd_Config == NULL) { - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 31 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid; + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid; } else { switch (carrier->sib1->tdd_Config->subframeAssignment) { case 1: @@ -1830,11 +2423,13 @@ do_RRCConnectionReconfiguration( RSRP_Range_t *rsrp, C_RNTI_t *cba_rnti, struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList - *dedicatedInfoNASList - -#if defined(Rel10) || defined(Rel14) + *dedicatedInfoNASList, + SL_CommConfig_r12_t *sl_CommConfig, + SL_DiscConfig_r12_t *sl_DiscConfig +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , SCellToAddMod_r10_t *SCell_config #endif + ) //------------------------------------------------------------------------------ { @@ -1926,6 +2521,45 @@ do_RRCConnectionReconfiguration( rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.dedicatedInfoNASList = dedicatedInfoNASList; rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.securityConfigHO = NULL; + //TTN for D2D + //allocate dedicated resource pools for SL communication (sl_CommConfig_r12) + if (sl_CommConfig != NULL) { + LOG_I(RRC,"[RRCConnectionReconfiguration] allocating a dedicated resource pool for SL communication \n"); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12)); + memcpy((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, (void*)sl_CommConfig, + sizeof(SL_CommConfig_r12_t)); + } + + //allocate dedicated resource pools for SL discovery (sl_DiscConfig) + if (sl_DiscConfig != NULL){ + LOG_I(RRC,"[RRCConnectionReconfiguration] allocating a dedicated resource pool for SL discovery \n"); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12)); + memcpy((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12, (void*)sl_DiscConfig, + sizeof(SL_DiscConfig_r12_t)); + } + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg, buffer, @@ -2341,7 +2975,7 @@ uint8_t do_RRCConnectionRelease( uint8_t TMGI[5] = {4,3,2,1,0};//TMGI is a string of octet, ref. TS 24.008 fig. 10.5.4a -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, uint8_t sync_area, uint8_t *buffer, @@ -2516,7 +3150,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension)); measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measId=measid; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrpResult=rsrp_s; measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrqResult=rsrq_s; #else diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h similarity index 93% rename from openair2/RRC/LITE/MESSAGES/asn1_msg.h rename to openair2/RRC/LTE/MESSAGES/asn1_msg.h index 05396bf727961b03a8278f00ddbbf606da6bd629..a4da38c0196a23efc250e90ac9f4d3fa3d1d83bc 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -39,7 +39,8 @@ #include <asn_application.h> #include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */ -#include "RRC/LITE/defs.h" +#include "RRC/LTE/rrc_defs.h" +#include "SL-DestinationInfoList-r12.h" /* * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) @@ -103,6 +104,14 @@ routine only generates an mo-data establishment cause. uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); +/** +\brief Generate an SidelinkUEInformation UL-DCCH-Message (UE). +@param destinationInfoList Pointer to a list of destination for which UE requests E-UTRAN to assign dedicated resources +@param discTxResourceReq Pointer to number of discovery messages for discovery announcements for which UE requests E-UTRAN to assign dedicated resources +@param mode Indicates different requests from upper layers +@returns Size of encoded bit stream in bytes*/ +uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); + /** \brief Generate an RRCConnectionSetupComplete UL-DCCH-Message (UE) @param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU @returns Size of encoded bit stream in bytes*/ @@ -186,8 +195,10 @@ do_RRCConnectionReconfiguration( struct MeasConfig__speedStatePars *speedStatePars, RSRP_Range_t *rsrp, C_RNTI_t *cba_rnti, - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList* dedicatedInfoNASList -#if defined(Rel10) || defined(Rel14) + struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList* dedicatedInfoNASList, + SL_CommConfig_r12_t *sl_CommConfig, + SL_DiscConfig_r12_t *sl_DiscConfig +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , SCellToAddMod_r10_t *SCell_config #endif ); @@ -250,7 +261,7 @@ uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer,int Transaction_ * @returns Size of encoded bit stream in bytes */ uint8_t do_MCCHMessage(uint8_t *buffer); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*** * \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) * @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c new file mode 100644 index 0000000000000000000000000000000000000000..2d91828861c4e4c07a92f12677abf3c2a9d224ae --- /dev/null +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c @@ -0,0 +1,1417 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 asn1_msg.c +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#include <stdio.h> +#include <sys/types.h> +#include <stdlib.h> /* for atoi(3) */ +#include <unistd.h> /* for getopt(3) */ +#include <string.h> /* for strerror(3) */ +#include <sysexits.h> /* for EX_* exit codes */ +#include <errno.h> /* for errno */ +#include "UTIL/LOG/log.h" +#include <asn_application.h> +#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */ +#include <per_encoder.h> +#include "asn1_msg.h" + + + +//#include for NB-IoT------------------- +#include "RRCConnectionRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "UL-CCCH-Message-NB.h" +#include "UL-DCCH-Message-NB.h" +#include "DL-CCCH-Message-NB.h" +#include "DL-DCCH-Message-NB.h" +#include "EstablishmentCause-NB-r13.h" +#include "RRCConnectionSetup-NB.h" +#include "SRB-ToAddModList-NB-r13.h" +#include "DRB-ToAddModList-NB-r13.h" +#include "RRC/LTE/defs_NB_IoT.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "MasterInformationBlock-NB.h" +#include "SystemInformation-NB.h" +#include "SystemInformationBlockType1.h" +#include "SIB-Type-NB-r13.h" +#include "RRCConnectionResume-NB.h" +#include "RRCConnectionReestablishment-NB.h" +#include "../defs_NB_IoT.h" +//---------------------------------------- + +//#include "PHY/defs.h" +#include "enb_config.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + + + + +/*do_MIB_NB_NB_IoT*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint16_t N_RB_DL,//may not needed--> for NB_IoT only 1 PRB is used + uint32_t frame, + uint32_t hyper_frame) +{ + asn_enc_rval_t enc_rval; + BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT); + + /* + * systemFrameNumber-MSB: (TS 36.331 pag 576) + * define the 4 MSB of the SFN (10 bits). The last significant 6 bits will be acquired implicitly by decoding the NPBCH + * NOTE: 6 LSB will be used for counting the 64 radio frames in the TTI period (640 ms) that is exactly the MIB period + * + * hyperSFN-LSB: + * indicates the 2 least significant bits of the HSFN. The remaining 8 bits are present in SIB1-NB + * NOTE: with the 2 bits we count the 4 HSFN (is 1 SIB1-Nb modification period) while the other 6 count the number of modification periods + * + * + * NOTE: in OAI never modify the SIB messages!!?? + */ + + //XXX check if correct the bit assignment + uint8_t sfn_MSB = (uint8_t)((frame>>6) & 0x0f); // all the 4 bits are set to 1 + uint8_t hsfn_LSB = (uint8_t)(hyper_frame & 0x03); //2 bits set to 1 (0x3 = 0011) + uint16_t spare=0; //11 bits --> use uint16 + + mib_NB_IoT->message.systemFrameNumber_MSB_r13.buf = &sfn_MSB; + mib_NB_IoT->message.systemFrameNumber_MSB_r13.size = 1; //if expressed in byte + mib_NB_IoT->message.systemFrameNumber_MSB_r13.bits_unused = 4; //is byte based (so how many bits you don't use of the 8 bits of a bite + + mib_NB_IoT->message.hyperSFN_LSB_r13.buf= &hsfn_LSB; + mib_NB_IoT->message.hyperSFN_LSB_r13.size= 1; + mib_NB_IoT->message.hyperSFN_LSB_r13.bits_unused = 6; + + //XXX to be set?? + mib_NB_IoT->message.spare.buf = (uint8_t *)&spare; + mib_NB_IoT->message.spare.size = 2; + mib_NB_IoT->message.spare.bits_unused = 5; + + //decide how to set it + mib_NB_IoT->message.schedulingInfoSIB1_r13 =11; //see TS 36.213-->tables 16.4.1.3-3 ecc... + mib_NB_IoT->message.systemInfoValueTag_r13= 0; + mib_NB_IoT->message.ab_Enabled_r13 = 0; + + //to be decided + mib_NB_IoT->message.operationModeInfo_r13.present = MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13; + mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 0; + + printf("[MIB] Initialization of frame information,sfn_MSB %x, hsfn_LSB %x\n", + (uint32_t)sfn_MSB, + (uint32_t)hsfn_LSB); + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message_NB, + (void*)mib_NB_IoT, + carrier->MIB_NB_IoT, + 100); + if(enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); + +} + +/*do_SIB1_NB*/ +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ) +{ + BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT); + SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT); + + + asn_enc_rval_t enc_rval; + + PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT; + MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; + SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT; + SIB_Type_NB_r13_t *sib_type_NB_IoT; + + + long* attachWithoutPDN_Connectivity = NULL; + attachWithoutPDN_Connectivity = CALLOC(1,sizeof(long)); + long *nrs_CRS_PowerOffset=NULL; + nrs_CRS_PowerOffset = CALLOC(1, sizeof(long)); + long *eutraControlRegionSize=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI) + eutraControlRegionSize = CALLOC(1,sizeof(long)); + long systemInfoValueTagSI = 0; + + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13; + + //allocation + *sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13; + + + /*TS 36.331 v14.2.0 pag 589 + * hyperSFN-MSB + * Indicates the 8 most significant bits of the hyper-SFN. Together with the hyper-LSB in MIB-NB the complete HSFN is build up + */ + //FIXME see if correct + uint8_t hyperSFN_MSB = (uint8_t) ((frame>>2)& 0xff); + + //XXX to be checked + (*sib1_NB_IoT)->hyperSFN_MSB_r13.buf = &hyperSFN_MSB; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0; + + memset(&PLMN_identity_info_NB_IoT,0,sizeof(PLMN_IdentityInfo_NB_r13_t)); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + + asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0; + + //left as it is??? +#if defined(ENABLE_ITTI) + dummy_mcc[0] = (configuration->mcc / 100) % 10; + dummy_mcc[1] = (configuration->mcc / 10) % 10; + dummy_mcc[2] = (configuration->mcc / 1) % 10; +#else + dummy_mcc[0] = 0; + dummy_mcc[1] = 0; + dummy_mcc[2] = 1; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0; + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0; + + +#if defined(ENABLE_ITTI) + + if (configuration->mnc >= 100) { + dummy_mnc[0] = (configuration->mnc / 100) % 10; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } else { + if (configuration->mnc_digit_length == 2) { + dummy_mnc[0] = (configuration->mnc / 10) % 10; + dummy_mnc[1] = (configuration->mnc / 1) % 10; + dummy_mnc[2] = 0xf; + } else { + dummy_mnc[0] = (configuration->mnc / 100) % 100; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } + } + +#else + dummy_mnc[0] = 0; + dummy_mnc[1] = 1; + dummy_mnc[2] = 0xf; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]); + + if (dummy_mnc[2] != 0xf) { + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[2]); + } + + //still set to "notReserved" as in the previous case + PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved; + + *attachWithoutPDN_Connectivity = 0; + PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity; + + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.plmn_IdentityList_r13.list,&PLMN_identity_info_NB_IoT); + + // 16 bits = 2 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte + + //lefts as it is? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (configuration->tac >> 8) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (configuration->tac >> 0) & 0xff; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0; + + // 28 bits --> i have to use 32 bits = 4 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (configuration->cell_identity >> 20) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (configuration->cell_identity >> 12) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (configuration->cell_identity >> 4) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (configuration->cell_identity << 4) & 0xf0; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4; + + //Still set to "notBarred" as in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred; + + //Still Set to "notAllowed" like in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed; + + + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589 + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 = 0; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value) + + (*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(P_Max_t)); + *((*sib1_NB_IoT)->p_Max_r13) = 23; + + //FIXME + (*sib1_NB_IoT)->freqBandIndicator_r13 = +#if defined(ENABLE_ITTI) + configuration->eutra_band; +#else + 5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode) +#endif + + //OPTIONAL new parameters, to be used? + /* + * freqBandInfo_r13 + * multiBandInfoList_r13 + * nrs_CRS_PowerOffset_r13 + * sib1_NB_IoT->downlinkBitmap_r13.choice.subframePattern10_r13 =(is a BIT_STRING) + */ + + + (*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13)); + ((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING; + + *eutraControlRegionSize = 1; + (*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize; + + + *nrs_CRS_PowerOffset= 0; + (*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset; + + schedulingInfo_NB_IoT = (SchedulingInfo_NB_r13_t*) malloc (3*sizeof(SchedulingInfo_NB_r13_t)); + sib_type_NB_IoT = (SIB_Type_NB_r13_t *) malloc (3*sizeof(SIB_Type_NB_r13_t)); + + memset(&schedulingInfo_NB_IoT[0],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[1],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[2],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&sib_type_NB_IoT[0],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[1],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[2],0,sizeof(SIB_Type_NB_r13_t)); + + + // Now, follow the scheduler SIB configuration + // There is only one sib2+sib3 common setting + schedulingInfo_NB_IoT[0].si_Periodicity_r13=SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; + schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission. + schedulingInfo_NB_IoT[0].si_TB_r13= SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits + + + // This is for SIB2/3 + /*SIB3 --> There is no mapping information of SIB2 since it is always present + * in the first SystemInformation message + * listed in the schedulingInfoList list. + * */ + sib_type_NB_IoT[0]=SIB_Type_NB_r13_sibType3_NB_r13; + + ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]); + + //printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13); + +#if defined(ENABLE_ITTI) + + if (configuration->frame_type == TDD) +#endif + { + //FIXME in NB-IoT mandatory to be FDD --> so must give an error + LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct? + exit(-1); + } + + //FIXME which value chose for the following parameter + (*sib1_NB_IoT)->si_WindowLength_r13=SystemInformationBlockType1_NB__si_WindowLength_r13_ms160; + (*sib1_NB_IoT)->si_RadioFrameOffset_r13= 0; + + /*In Nb-IoT change/update of specific SI message can additionally be indicated by a SI message specific value tag + * systemInfoValueTagSI (there is no SystemInfoValueTag in SIB1-NB but only in MIB-NB) + *contained in systemInfoValueTagList_r13 + **/ + //FIXME correct? + (*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13)); + asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI); + + +#ifdef XER_PRINT //generate xml files + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB1_NB_IoT, + 100); + + if (enc_rval.encoded > 0){ + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformationBlockType1-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*SIB23_NB_IoT*/ +//to be clarified is it is possible to carry SIB2 and SIB3 in the same SI message for NB-IoT? +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier,//MP: this is already a carrier[CC_id] + NbIoTRrcConfigurationReq *configuration ) //openair2/COMMON/rrc_messages_types.h +{ + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part; + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part; + + BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + + asn_enc_rval_t enc_rval; + RACH_Info_NB_r13_t rach_Info_NB_IoT; + NPRACH_Parameters_NB_r13_t *nprach_parameters; + + //optional + long *connEstFailOffset = NULL; + connEstFailOffset = CALLOC(1, sizeof(long)); + +// RSRP_ThresholdsNPRACH_InfoList_NB_r13_t *rsrp_ThresholdsPrachInfoList; +// RSRP_Range_t rsrp_range; + + ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition; + struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config; + struct DL_GapConfig_NB_r13 *dl_Gap; + + long *srs_SubframeConfig; + srs_SubframeConfig= CALLOC(1, sizeof(long)); + + + if (bcch_message) { + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + } else { + LOG_E(RRC,"[NB-IoT %d] BCCH_MESSAGE_NB is null, exiting\n", Mod_id); + exit(-1); + } + + //before schould be allocated memory somewhere? +// if (!carrier->sib2_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib2_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } +// +// if (!carrier->sib3_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib3_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } + + + LOG_I(RRC,"[NB-IoT %d] Configuration SIB2/3\n", Mod_id); + + sib2_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + sib3_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib2_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib3_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + + sib2_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13; + sib3_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13; + + //may bug if not correct allocation of memory + carrier->sib2_NB_IoT = &sib2_NB_part->choice.sib2_r13; + carrier->sib3_NB_IoT = &sib3_NB_part->choice.sib3_r13; + sib2_NB_IoT = carrier->sib2_NB_IoT; + sib3_NB_IoT = carrier->sib3_NB_IoT; + + nprach_parameters = (NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(NPRACH_Parameters_NB_r13_t)); + + memset(&nprach_parameters[0],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[1],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[2],0,sizeof(NPRACH_Parameters_NB_r13_t)); + +/// SIB2-NB----------------------------------------- + + //Barring is manage by ab-Enabled in MIB-NB (but is not a struct as ac-BarringInfo in LTE legacy) + + //RACH Config. Common-------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.preambleTransMax_CE_r13 = + configuration->rach_preambleTransMax_CE_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.powerRampingStep = + configuration->rach_powerRampingStep_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.preambleInitialReceivedTargetPower = + configuration->rach_preambleInitialReceivedTargetPower_NB; + + rach_Info_NB_IoT.ra_ResponseWindowSize_r13 = configuration->rach_raResponseWindowSize_NB; + rach_Info_NB_IoT.mac_ContentionResolutionTimer_r13 = configuration-> rach_macContentionResolutionTimer_NB; + //rach_infoList max size = maxNPRACH-Resources-NB-r13 = 3 + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.rach_InfoList_r13.list,&rach_Info_NB_IoT); + + //TS 36.331 pag 614 --> if not present the value to infinity sould be used + *connEstFailOffset = 0; + + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.connEstFailOffset_r13 = connEstFailOffset; /*OPTIONAL*/ + + + // BCCH-Config-NB-IoT---------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.bcch_Config_r13.modificationPeriodCoeff_r13 + = configuration->bcch_modificationPeriodCoeff_NB; + + // PCCH-Config-NB-IoT----------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.defaultPagingCycle_r13 + = configuration->pcch_defaultPagingCycle_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.nB_r13 = configuration->pcch_nB_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.npdcch_NumRepetitionPaging_r13 = configuration-> pcch_npdcch_NumRepetitionPaging_NB; + + //NPRACH-Config-NB-IoT----------------------------------------------------------------- + + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13 = NULL; + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_CP_Length_r13 = configuration->nprach_CP_Length; + /*OPTIONAL*/ +// =CALLOC(1, sizeof(struct RSRP_ThresholdsNPRACH_InfoList_NB_r13)); //fatto uguale dopo +// rsrp_ThresholdsPrachInfoList = sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13; +// rsrp_range = configuration->nprach_rsrp_range_NB; +// ASN_SEQUENCE_ADD(&rsrp_ThresholdsPrachInfoList->list,rsrp_range); + + // According configuration to set the 3 CE level configuration setting + + nprach_parameters[0].nprach_Periodicity_r13 = configuration->nprach_Periodicity[0]; + nprach_parameters[0].nprach_StartTime_r13 = configuration->nprach_StartTime[0]; + nprach_parameters[0].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[0]; + nprach_parameters[0].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[0]; + nprach_parameters[0].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[0]; + nprach_parameters[0].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[0].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[0].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[0]; + nprach_parameters[0].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[0]; + nprach_parameters[0].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[0]; + + nprach_parameters[1].nprach_Periodicity_r13 = configuration->nprach_Periodicity[1]; + nprach_parameters[1].nprach_StartTime_r13 = configuration->nprach_StartTime[1]; + nprach_parameters[1].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[1]; + nprach_parameters[1].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[1]; + nprach_parameters[1].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[1]; + nprach_parameters[1].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[1].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[1].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[1]; + nprach_parameters[1].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[1]; + nprach_parameters[1].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[1]; + + nprach_parameters[2].nprach_Periodicity_r13 = configuration->nprach_Periodicity[2]; + nprach_parameters[2].nprach_StartTime_r13 = configuration->nprach_StartTime[2]; + nprach_parameters[2].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[2]; + nprach_parameters[2].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[2]; + nprach_parameters[2].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[2]; + nprach_parameters[2].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[2].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[2].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[2]; + nprach_parameters[2].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[2]; + nprach_parameters[2].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[2]; + + + //nprach_parameterList have a max size of 3 possible nprach configuration (see maxNPRACH_Resources_NB_r13) + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[0]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[1]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[2]); + + // NPDSCH-Config NB-IOT + sib2_NB_IoT->radioResourceConfigCommon_r13.npdsch_ConfigCommon_r13.nrs_Power_r13= configuration->npdsch_nrs_Power; + + + //NPUSCH-Config NB-IoT---------------------------------------------------------------- + //list of size 3 (see maxNPRACH_Resources_NB_r13) + ack_nack_repetition = configuration-> npusch_ack_nack_numRepetitions_NB; //is an enumerative + ASN_SEQUENCE_ADD(&(sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ack_NACK_NumRepetitions_Msg4_r13.list) ,&ack_nack_repetition); + + *srs_SubframeConfig = configuration->npusch_srs_SubframeConfig_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.srs_SubframeConfig_r13= srs_SubframeConfig; /*OPTIONAL*/ + + + /*OPTIONAL*/ + dmrs_config = CALLOC(1,sizeof(struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13)); + dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13; + dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13; + + /*OPTIONAL + * -define the base sequence for a DMRS sequence in a cell with multi tone transmission (3,6,12) see TS 36.331 NPUSCH-Config-NB + * -if not defined will be calculated based on the cellID once we configure the phy layer (rrc_mac_config_req) through the config_sib2 */ + dmrs_config->threeTone_BaseSequence_r13 = NULL; + dmrs_config->sixTone_BaseSequence_r13 = NULL; + dmrs_config->twelveTone_BaseSequence_r13 = NULL; + + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.dmrs_Config_r13 = dmrs_config; + + //ulReferenceSignalsNPUSCH + /*Reference Signal (RS) for UL in NB-IoT is called DRS (Demodulation Reference Signal) + * sequence-group hopping can be enabled or disabled by means of the cell-specific parameter groupHoppingEnabled_r13 + * sequence-group hopping can be disabled for certain specific UE through the parameter groupHoppingDisabled (physicalConfigDedicated) + * groupAssignmentNPUSCH--> is used for generate the sequence-shift pattern + */ + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupHoppingEnabled_r13= configuration->npusch_groupHoppingEnabled; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13 =configuration->npusch_groupAssignmentNPUSCH_r13; + + + //dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/ + dl_Gap = CALLOC(1,sizeof(struct DL_GapConfig_NB_r13)); + dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB; + dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB; + dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.dl_Gap_r13 = dl_Gap; + + + // uplinkPowerControlCommon - NB-IoT------------------------------------------------------ + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.p0_NominalNPUSCH_r13 = configuration->npusch_p0_NominalNPUSCH; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.deltaPreambleMsg3_r13 = configuration->deltaPreambleMsg3; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.alpha_r13 = configuration->npusch_alpha; + //no deltaFlist_PUCCH and no UL cyclic prefix + + // UE Timers and Constants -NB-IoT-------------------------------------------------------- + sib2_NB_IoT->ue_TimersAndConstants_r13.t300_r13 = configuration-> ue_TimersAndConstants_t300_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t301_r13 = configuration-> ue_TimersAndConstants_t301_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t310_r13 = configuration-> ue_TimersAndConstants_t310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t311_r13 = configuration-> ue_TimersAndConstants_t311_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n310_r13 = configuration-> ue_TimersAndConstants_n310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n311_r13 = configuration-> ue_TimersAndConstants_n311_NB; + + //other SIB2-NB Parameters-------------------------------------------------------------------------------- + sib2_NB_IoT->freqInfo_r13.additionalSpectrumEmission_r13 = 1; + sib2_NB_IoT->freqInfo_r13.ul_CarrierFreq_r13 = NULL; /*OPTIONAL*/ + + sib2_NB_IoT->timeAlignmentTimerCommon_r13=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; + + /*OPTIONAL*/ + sib2_NB_IoT->multiBandInfoList_r13 = NULL; + +/// SIB3-NB------------------------------------------------------- + + sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4; + sib3_NB_IoT->cellReselectionServingFreqInfo_r13.s_NonIntraSearch_r13=0; //or define in configuration? + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_RxLevMin_r13 = -70; + //new + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13 = CALLOC(1,sizeof(*sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)); + *(sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)= 10; //a caso + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.p_Max_r13 = NULL; + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.s_IntraSearchP_r13 = 31; // s_intraSearch --> s_intraSearchP!!! (they call in a different way) + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.t_Reselection_r13=1; + + //how to manage? + sib3_NB_IoT->freqBandInfo_r13 = NULL; + sib3_NB_IoT->multiBandInfoList_r13 = NULL; + + +///BCCH message (generate the SI message) + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13; + + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = SystemInformation_NB__criticalExtensions_PR_systemInformation_r13; + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list.count=0; + + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib2_NB_part); + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib3_NB_part); + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB23_NB_IoT, + 900); +// AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", +// enc_rval.failed_type->name, enc_rval.encoded); + +//#if defined(ENABLE_ITTI)..... + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformation-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI-NB encoding failed for SIB23_NB_IoT\n"); + return(-1); + } + + carrier->sib2_NB_IoT = sib2_NB_IoT; + carrier->sib3_NB_IoT = sib3_NB_IoT; + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionSetup_NB_IoT--> the aim is to establish SRB1 and SRB1bis(implicitly)*/ +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, // maybe not used + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1 + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT +) + +{ + + asn_enc_rval_t enc_rval; + + + //MP:logical channel group not defined for Nb-IoT + + //MP: logical channel priority pag 605 (is 1 for SRB1 and for SRB1bis should be the same) + //long* prioritySRB1 = NULL; + long* prioritySRB1bis = NULL; + BOOLEAN_t* logicalChannelSR_Prohibit =NULL; //pag 605 + BOOLEAN_t* npusch_AllSymbols= NULL; + +// struct SRB_ToAddMod_NB_r13* SRB1_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB = NULL; + + struct SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL; + + //No UL_specific parameters for NB-IoT in LogicalChanelConfig-NB + + PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13; + rrcConnectionSetup_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionSetup_r13; + + + if (*SRB_configList_NB_IoT) { + free(*SRB_configList_NB_IoT); + } + *SRB_configList_NB_IoT = CALLOC(1,sizeof(SRB_ToAddModList_NB_r13_t)); + +/// SRB1-------------------- + { +// SRB1_config_NB = CALLOC(1,sizeof(*SRB1_config_NB)); +// +// //no srb_Identity in SRB_ToAddMod_NB +// +// SRB1_rlc_config_NB = CALLOC(1,sizeof(*SRB1_rlc_config_NB)); +// SRB1_config_NB->rlc_Config_r13 = SRB1_rlc_config_NB; +// +// SRB1_rlc_config_NB->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; +// SRB1_rlc_config_NB->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//the only possible in NB_IoT +// +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_timer_poll_retransmit_r13; +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_max_retx_threshold_r13; +//// //(musT be disabled--> SRB1 config pag 640 specs ) +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; +// +// +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; +// //(musT be disabled--> SRB1 config pag 640 specs ) +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 = NULL; +// +// SRB1_lchan_config_NB = CALLOC(1,sizeof(*SRB1_lchan_config_NB)); +// SRB1_config_NB->logicalChannelConfig_r13 = SRB1_lchan_config_NB; +// +// SRB1_lchan_config_NB->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; +// +// +// prioritySRB1 = CALLOC(1, sizeof(long)); +// *prioritySRB1 = 1; +// SRB1_lchan_config_NB->choice.explicitValue.priority_r13 = prioritySRB1; +// +// logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); +// *logicalChannelSR_Prohibit = 1; +// //schould be set to TRUE (specs pag 641) +// SRB1_lchan_config_NB->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; +// +// //ADD SRB1 +// ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1_config_NB); + } + +///SRB1bis (The configuration for SRB1 and SRB1bis is the same) the only difference is the logical channel identity = 3 but not set here + + SRB1bis_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_config_NB_IoT)); + + //no srb_Identity in SRB_ToAddMod_NB + SRB1bis_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_rlc_config_NB_IoT)); + SRB1bis_config_NB_IoT->rlc_Config_r13 = SRB1bis_rlc_config_NB_IoT; + + SRB1bis_rlc_config_NB_IoT->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT + + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; + //(musT be disabled--> SRB1 config pag 640 specs ) + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; + + SRB1bis_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_lchan_config_NB_IoT)); + SRB1bis_config_NB_IoT->logicalChannelConfig_r13 = SRB1bis_lchan_config_NB_IoT; + + SRB1bis_lchan_config_NB_IoT->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; + + prioritySRB1bis = CALLOC(1, sizeof(long)); + *prioritySRB1bis = 1; //same as SRB1? + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.priority_r13 = prioritySRB1bis; + + logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); + *logicalChannelSR_Prohibit = 1; //schould be set to TRUE (specs pag 641) + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; + + //ADD SRB1bis + //MP: Actually there is no way to distinguish SRB1 and SRB1bis once put in the list + //MP: SRB_ToAddModList_NB_r13_t size = 1 + ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1bis_config_NB_IoT); + + + // PhysicalConfigDedicated (NPDCCH, NPUSCH, CarrierConfig, UplinkPowerControl) + + physicalConfigDedicated2_NB_IoT = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT)); + *physicalConfigDedicated_NB_IoT = physicalConfigDedicated2_NB_IoT; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13= CALLOC(1, sizeof(*physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13)); + + //no tpc, no cqi and no pucch, no pdsch, no soundingRS, no AntennaInfo, no scheduling request config + + /* + * NB-IoT supports the operation with either one or two antenna ports, AP0 and AP1. + * For the latter case, Space Frequency Block Coding (SFBC) is applied. + * Once selected, the same transmission scheme applies to NPBCH, NPDCCH, and NPDSCH. + * */ + + //FIXME: MP: CarrierConfigDedicated check the set values ---------------------------------------------- + + //DL + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_CarrierFreq_r13.carrierFreq_r13=0;//random value set + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13->present= + DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13->present = + DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.inbandCarrierInfo_r13= NULL; + + //UL + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->ul_CarrierConfig_r13.ul_CarrierFreq_r13= NULL; + + // NPDCCH + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_NumRepetitions_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_Offset_USS_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_StartSF_USS_r13=0; + + // NPUSCH //(specs TS 36.331 v14.2.1 pag 643) /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->ack_NACK_NumRepetitions_r13= NULL; + npusch_AllSymbols= CALLOC(1, sizeof(BOOLEAN_t)); + *npusch_AllSymbols= 1; //TRUE + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->npusch_AllSymbols_r13= npusch_AllSymbols; /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->groupHoppingDisabled_r13=NULL; /* OPTIONAL */ + + // UplinkPowerControlDedicated + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13->p0_UE_NPUSCH_r13 = 0; // 0 dB (specs TS36.331 v14.2.1 pag 643) + + + //Fill the rrcConnectionSetup-NB message + rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value + rrcConnectionSetup_NB_IoT->criticalExtensions.present = RRCConnectionSetup_NB__criticalExtensions_PR_c1; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ; + //MP: carry only SRB1bis at the moment and phyConfigDedicated + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = *SRB_configList_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = physicalConfigDedicated2_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = NULL; + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes), ecause %d\n", + enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_SecurityModeCommand - exactly the same as previous implementation*/ +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm) +{ + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present = + SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; + + // the two following information could be based on the mod_id + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm + = (CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm + = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] securityModeCommand-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : securityModeCommand-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_UECapabilityEnquiry_NB_IoT - very similar to legacy lte*/ +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +) + +{ + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + //no RAT type in NB-IoT + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.rrc_TransactionIdentifier = Transaction_id; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = UECapabilityEnquiry_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present = + UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13; + + //no ue_CapabilityRequest (list of RAT_Type) + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] UECapabilityEnquiry-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : UECapabilityEnquiry-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReconfiguration_NB_IoT-->may convey information for resource configuration + * (including RBs, MAC main configuration and physical channel configuration) + * including any associated dedicated NAS information.*/ +uint16_t do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT, + MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT) + +{ + + //check on DRB_list if contains more than 2 DRB? + + asn_enc_rval_t enc_rval; + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13; + rrcConnectionReconfiguration_NB = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReconfiguration_r13; + + // RRCConnectionReconfiguration + rrcConnectionReconfiguration_NB->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReconfiguration_NB->criticalExtensions.present = RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ; + + //RAdioResourceconfigDedicated + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13 = + CALLOC(1,sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->srb_ToAddModList_r13 = SRB1_list_NB; //only SRB1 + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToAddModList_r13 = DRB_list_NB_IoT; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToReleaseList_r13 = DRB_list2_NB_IoT; //NULL + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->physicalConfigDedicated_r13 = physicalConfigDedicated_NB_IoT; + //FIXME may not used now + //rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->rlf_TimersAndConstants_r13 + + if (mac_MainConfig_NB_IoT!=NULL) { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13 = + CALLOC(1, sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->present + =RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13; + //why memcopy only this one? + memcpy(&rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->choice.explicitValue_r13, + mac_MainConfig_NB_IoT, sizeof(*mac_MainConfig_NB_IoT)); + + } else { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13=NULL; + } + + //no measConfig, measIDlist + //no mobilityControlInfo + + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.dedicatedInfoNASList_r13 = dedicatedInfoNASList_NB_IoT; + //mainly used for cell-reselection/handover purposes?? + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.fullConfig_r13 = NULL; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed %s, %li\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //changed only asn_DEF_DL_DCCH_Message_NB +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); +#endif + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT)... + + + LOG_I(RRC,"RRCConnectionReconfiguration-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReestablishmentReject - exactly the same as legacy LTE*/ +uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13; + rrcConnectionReestablishmentReject = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishmentReject_r13; + + // RRCConnectionReestablishmentReject //exactly the same as LTE + rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReject_NB_IoT*/ +uint8_t do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) + +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13; + rrcConnectionReject_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReject_r13; + + // RRCConnectionReject-NB_IoT + rrcConnectionReject_NB_IoT->criticalExtensions.present = RRCConnectionReject_NB__criticalExtensions_PR_c1; + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13; + /* let's put an extended wait time of 1s for the moment */ + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.extendedWaitTime_r13 = 1; + //new-use of suspend indication + //If present, this field indicates that the UE should remain suspended and not release its stored context. + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13= + CALLOC(1, sizeof(long)); + *(rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13)= + RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; + + //Only Modified "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %ld)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReject-NB Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + + +//no do_MBSFNAreaConfig(..) in NB-IoT +//no do_MeasurementReport(..) in NB-IoT + +/*do_DLInformationTransfer_NB*/ +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer) + +{ + ssize_t encoded; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + + memset(&dl_dcch_msg_NB_IoT, 0, sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.rrc_TransactionIdentifier = transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = DLInformationTransfer_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.size = pdu_length; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.buf = pdu_buffer; + + encoded = uper_encode_to_new_buffer (&asn_DEF_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer); + + //only change in "asn_DEF_DL_DCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[10000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + return encoded; +} + +/*do_ULInformationTransfer*/ +//for the moment is not needed (UE-SIDE) + +/*OAI_UECapability_t *fill_ue_capability*/ + +/*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use? +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured? +{ + + asn_enc_rval_t enc_rval; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT; + + memset(&dl_ccch_msg_NB_IoT, 0, sizeof(DL_CCCH_Message_NB_t)); + + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13; + rrcConnectionReestablishment_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishment_r13; + + //rrcConnectionReestablishment_NB + rrcConnectionReestablishment_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = RRCConnectionReestablishment_NB__criticalExtensions_PR_c1; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = SRB_list_NB_IoT; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = NULL; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.nextHopChainingCount_r13=0; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %li)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); +#endif + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[30000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + LOG_I(RRC,"RRCConnectionReestablishment-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + return 0; +} + +/*do_RRCConnectionRelease_NB--> is used to command the release of an RRC connection*/ +uint8_t do_RRCConnectionRelease_NB_IoT( + uint8_t Mod_id, + uint8_t *buffer, + const uint8_t Transaction_id) +{ + + asn_enc_rval_t enc_rval; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13; + rrcConnectionRelease_NB_IoT = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionRelease_r13; + + // RRCConnectionRelease + rrcConnectionRelease_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionRelease_NB_IoT->criticalExtensions.present = RRCConnectionRelease_NB__criticalExtensions_PR_c1; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ; + + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = ReleaseCause_NB_r13_other; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.redirectedCarrierInfo_r13 = NULL; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.extendedWaitTime_r13 = NULL; + + //Why allocate memory for non critical extension? + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension=CALLOC(1, + sizeof(*rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension)); + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE);//check + + return((enc_rval.encoded+7)/8); +} + + + + diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.h b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..6fb073f80de30638aad1208c52a0af79edc42250 --- /dev/null +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.h @@ -0,0 +1,293 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 asn1_msg.h +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr ,navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifdef USER_MODE +#include <stdio.h> +#include <sys/types.h> +#include <stdlib.h> /* for atoi(3) */ +#include <unistd.h> /* for getopt(3) */ +#include <string.h> /* for strerror(3) */ +#include <sysexits.h> /* for EX_* exit codes */ +#include <errno.h> /* for errno */ +#else +#include <linux/module.h> /* Needed by all modules */ +#endif + +#include <asn_application.h> +#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */ + + +#include "RRC/LITE/defs_NB_IoT.h" + +/* + * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) + * output into the chosen string buffer. + * RETURN VALUES: + * 0: The structure is printed. + * -1: Problem printing the structure. + * WARNING: No sensible error value is returned. + */ + + +/** +\brief Generate configuration for SIB1 (eNB). +@param carrier pointer to Carrier information +@param N_RB_DL Number of downlink PRBs +@param frame radio frame number +@return size of encoded bit stream in bytes*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint32_t N_RB_DL, + uint32_t frame, + uint32_t hyper_frame); + + +/** +\brief Generate a default configuration for SIB1-NB (eNB). +@param Mod_id Instance of eNB +@param CC_id Component carrier to configure +@param carrier pointer to Carrier information +@param configuration Pointer Configuration Request structure +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ); + +/** +\brief Generate a default configuration for SIB2/SIB3-NB in one System Information PDU (eNB). +@param Mod_id Index of eNB (used to derive some parameters) +@param buffer Pointer to PER-encoded ASN.1 description of SI-NB PDU +@param systemInformation_NB_IoT Pointer to asn1c C representation of SI-NB PDU +@param sib2_NB Pointer (returned) to sib2_NB component withing SI-NB PDU +@param sib3_NB Pointer (returned) to sib3_NB component withing SI-NB PDU +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration + ); + +/**(UE-SIDE) +\brief Generate an RRCConnectionRequest-NB UL-CCCH-Message (UE) based on random string or S-TMSI. This +routine only generates an mo-data establishment cause. +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param rv 5 byte random string or S-TMSI +@param Mod_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRequest_NB_IoT(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); + + +/**(UE -SIDE) +\brief Generate an RRCConnectionSetupComplete-NB UL-DCCH-Message (UE) +@param Mod_id +@param Transaction_id +@param dedicatedInfoNASLength +@param dedicatedInfoNAS +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, + const char* dedicatedInfoNAS); + +/** (UE-SIDE) +\brief Generate an RRCConnectionReconfigurationComplete-NB UL-DCCH-Message (UE) +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param ctxt_pP +@param Transaction_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* buffer, + const uint8_t Transaction_id +); + +/** +\brief Generate an RRCConnectionSetup-NB DL-CCCH-Message (eNB). This routine configures SRB_ToAddMod (SRB1/SRB1bis-NB) and +PhysicalConfigDedicated-NB IEs. +@param ctxt_pP Running context +@param ue_context_pP UE context +@param CC_id Component Carrier ID +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param transmission_mode Transmission mode for UE (1-9) +@param UE_id UE index for this message +@param Transaction_id Transaction_ID for this message +@param SRB_configList Pointer (returned) to SRB1_config/SRB1bis_config(later) IEs for this UE +@param physicalConfigDedicated_NB Pointer (returned) to PhysicalConfigDedicated-NB IE for this UE +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //carrier[CC_id].Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed but not deleted + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //in order to be configured--> stanno puntando alla SRB_configlist dell ue_context + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT //in order to be configured--> stanno puntando alla physicalConfigDedicated dell ue_context +); + + +/** + * For which SRB is used in NB-IoT?? +\brief Generate an RRCConnectionReconfiguration-NB DL-DCCH-Message (eNB). This routine configures SRBToAddMod-NB (SRB1) and one DRBToAddMod-NB +(DRB3). PhysicalConfigDedicated-NB is not updated. +@param ctxt_pP Running context +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param Transaction_id Transaction_ID for this message +@param SRB_list_NB Pointer to SRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list_NB Pointer to DRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list2_NB Pointer to DRB List to be released (NULL if none to be released) +//sps not supported by NB-IoT +@param physicalConfigDedicated_NB Pointer to PhysicalConfigDedicated-NB to be modified (NULL if no modifications) +//measurement not supported by NB-IoT +@param mac_MainConfig Pointer to Mac_MainConfig(NULL if no modifications) +//no CBA functionalities +@returns Size of encoded bit stream in bytes*/ + +uint16_t +do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT, + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated, + MAC_MainConfig_t *mac_MainConfig, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + @param cipheringAlgorithm + @param integrityProtAlgorithm + */ + +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + */ + +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +); + + +/** + * There is nothing new in this type of message for NB-IoT (only change in some nomenclature) +\brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t +do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionReject-NB DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ +uint8_t +do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); + + +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer); + +//for now not implemented since UE side +//uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); + +//for now not implemented since UE side??? +//OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) + +/** +\brief Generate an RRCConnectionReestablishment-NB DL-CCCH Message + *@param + * + */ + +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT + ); + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message (eNB) +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-DCCH-Message PDU +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +//uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); diff --git a/openair2/RRC/LITE/MESSAGES/asn1_patch b/openair2/RRC/LTE/MESSAGES/asn1_patch similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1_patch rename to openair2/RRC/LTE/MESSAGES/asn1_patch diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-860.txt b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-860.txt similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-860.txt rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-860.txt diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-a20.txt b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-a20.txt similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-a20.txt rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-a20.txt diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-ah0.txt b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-ah0.txt similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-ah0.txt rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-ah0.txt diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-c60.txt b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-c60.txt similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/36331-c60.txt rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/36331-c60.txt diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-86.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-86.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-86.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-86.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-a20.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-a20.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-a20.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-a20.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-ah0.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-ah0.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-ah0.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-ah0.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-c60.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-c60.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-c60.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-InterNodeDefinitions-c60.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn.orig b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn.orig similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn.orig rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn.orig diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-ah0.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-ah0.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-ah0.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-ah0.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-c60.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-c60.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-c60.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-c60.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-86.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-86.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-86.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-86.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-a20.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-a20.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-a20.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-a20.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-ah0.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-ah0.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-ah0.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-ah0.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-c60.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-c60.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-c60.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-UE-Variables-c60.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e30.asn b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/RRC-e30.asn similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e30.asn rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/RRC-e30.asn diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/extract_asn1_from_spec.pl b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/extract_asn1_from_spec.pl similarity index 100% rename from openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/extract_asn1_from_spec.pl rename to openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/extract_asn1_from_spec.pl diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..7da9c014f1c0e9b22a6757f52306ef5789846053 --- /dev/null +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -0,0 +1,573 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 RRC/LITE/defs_NB_IoT.h +* \brief NB-IoT RRC struct definitions and function prototypes +* \author Navid Nikaein, Raymond Knopp and Michele Paffetti +* \date 2010 - 2014, 2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_DEFS_NB_IOT_H__ +#define __OPENAIR_RRC_DEFS_NB_IOT_H__ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "COMMON/s1ap_messages_types.h" +#include "COMMON/rrc_messages_types.h" + +#include "collection/tree.h" +#include "rrc_types_NB_IoT.h" +#include "COMMON/platform_constants.h" +#include "COMMON/platform_types.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#include "COMMON/mac_rrc_primitives.h" + +//-----NB-IoT #include files------- + +//#include "SystemInformationBlockType1-NB.h" +//#include "SystemInformation-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionSetup-NB.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionRequest-NB.h" +#include "RRCConnectionReestablishmentRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "BCCH-BCH-Message-NB.h" +#include "AS-Config-NB.h" +#include "AS-Context-NB.h" +#include "UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h +//------------------- + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +/* TODO: be sure this include is correct. + * It solves a problem of compilation of the RRH GW, + * issue #186. + */ +#if !defined(ENABLE_ITTI) +# include "as_message.h" +#endif + +#if defined(ENABLE_USE_MME) +# include "commonDef.h" +#endif + +#if ENABLE_RAL +# include "collection/hashtable/obj_hashtable.h" +#endif + + + +/*I will change the name of the structure for compile purposes--> hope not to undo this process*/ + +typedef unsigned int uid_NB_IoT_t; +#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT (((MAX_MOBILES_PER_ENB_NB_IoT/8)/sizeof(unsigned int)) + 1) + +typedef struct uid_linear_allocator_NB_IoT_s { + unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT]; +} uid_allocator_NB_IoT_t; + + +#define PROTOCOL_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + +#define PROTOCOL_RRC_CTXT_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + + +//left as they are --> used in LAYER2/epenair2_proc.c and UE side +typedef enum UE_STATE_NB_IoT_e { + RRC_INACTIVE_NB_IoT=0, + RRC_IDLE_NB_IoT, + RRC_SI_RECEIVED_NB_IoT, + RRC_CONNECTED_NB_IoT, + RRC_RECONFIGURED_NB_IoT, + RRC_HO_EXECUTION_NB_IoT //maybe not needed? +} UE_STATE_NB_IoT_t; + + +/** @defgroup _rrc RRC + * @ingroup _oai2 + * @{ + */ +typedef struct UE_RRC_INFO_NB_IoT_s { + UE_STATE_NB_IoT_t State; + uint8_t SIB1systemInfoValueTag; + uint32_t SIStatus; + uint32_t SIcnt; +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA +#endif + uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 + uint8_t handoverTarget; + //HO_STATE_t ho_state; + uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 + unsigned short UE_index; + uint32_t T300_active; + uint32_t T300_cnt; + uint32_t T304_active; + uint32_t T304_cnt; + uint32_t T310_active; + uint32_t T310_cnt; + uint32_t N310_cnt; + uint32_t N311_cnt; + rnti_t rnti; +} __attribute__ ((__packed__)) UE_RRC_INFO_NB_IoT; + +//#define NUM_PRECONFIGURED_LCHAN (NB_CH_CX*2) //BCCH, CCCH + +#define UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! +#define UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 + + + +// HO_STATE is not supported by NB-IoT + +//#define MAX_MOBILES_PER_ENB MAX_MOBILES_PER_RG +#define RRM_FREE(p) if ( (p) != NULL) { free(p) ; p=NULL ; } +#define RRM_MALLOC(t,n) (t *) malloc16( sizeof(t) * n ) +#define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) +#define RRM_CALLOC2(t,s) (t *) malloc16( s ) + +//Measurement Report not supported in NB-IoT + +#define PAYLOAD_SIZE_MAX 1024 +#define RRC_BUF_SIZE 255 +#define UNDEF_SECURITY_MODE 0xff +#define NO_SECURITY_MODE 0x20 + +/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ +#define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 + +typedef struct UE_S_TMSI_NB_IoT_s { + boolean_t presence; + mme_code_t mme_code; + m_tmsi_t m_tmsi; +} __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT; + + +typedef enum e_rab_satus_NB_IoT_e { + E_RAB_STATUS_NEW_NB_IoT, + E_RAB_STATUS_DONE_NB_IoT, // from the eNB perspective + E_RAB_STATUS_ESTABLISHED_NB_IoT, // get the reconfigurationcomplete form UE + E_RAB_STATUS_FAILED_NB_IoT, +} e_rab_status_NB_IoT_t; + +typedef struct e_rab_param_NB_IoT_s { + e_rab_t param; + uint8_t status; + uint8_t xid; // transaction_id +} __attribute__ ((__packed__)) e_rab_param_NB_IoT_t; + + +//HANDOVER_INFO not implemented in NB-IoT delete + + +#define RRC_HEADER_SIZE_MAX 64 +#define RRC_BUFFER_SIZE_MAX 1024 + +typedef struct { + char Payload[RRC_BUFFER_SIZE_MAX]; + char Header[RRC_HEADER_SIZE_MAX]; + char payload_size; +} RRC_BUFFER_NB_IoT; + +#define RRC_BUFFER_SIZE_NB_IoT sizeof(RRC_BUFFER_NB_IoT) + + +typedef struct RB_INFO_NB_IoT_s { + uint16_t Rb_id; //=Lchan_id + //LCHAN_DESC Lchan_desc[2]; no more used + //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT +} RB_INFO_NB_IoT; + +typedef struct SRB_INFO_NB_IoT_s { + uint16_t Srb_id; //=Lchan_id---> useful for distinguish between SRB1 and SRB1bis? + RRC_BUFFER_NB_IoT Rx_buffer; + RRC_BUFFER_NB_IoT Tx_buffer; + //LCHAN_DESC Lchan_desc[2]; no more used + unsigned int Trans_id; + uint8_t Active; +} SRB_INFO_NB_IoT; + + +typedef struct RB_INFO_TABLE_ENTRY_NB_IoT_s { + RB_INFO_NB_IoT Rb_info; + uint8_t Active; + uint32_t Next_check_frame; + uint8_t Status; +} RB_INFO_TABLE_ENTRY_NB_IoT; + +typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s { + SRB_INFO_NB_IoT Srb_info; + uint8_t Active; + uint8_t Status; + uint32_t Next_check_frame; +} SRB_INFO_TABLE_ENTRY_NB_IoT; + +//MEAS_REPORT_LIST_s not implemented in NB-IoT but is used at UE side +//HANDOVER_INFO_UE not implemented in NB-IoT +typedef struct HANDOVER_INFO_UE_NB_IoT_s { + PhysCellId_t targetCellId; + uint8_t measFlag; +} HANDOVER_INFO_UE_NB_IoT; + +//NB-IoT eNB_RRC_UE_NB_IoT_s--(used as a context in eNB --> ue_context in rrc_eNB_ue_context)------ +typedef struct eNB_RRC_UE_NB_IoT_s { + + EstablishmentCause_t establishment_cause; + uint8_t primaryCC_id; + //in NB-IoT only SRB0, SRB1 and SRB1bis (until AS security activation) exist + + /*MP: Concept behind List and List2 + * + * SRB_configList --> is used for the actual list of SRBs that is managed/that should be send over the RRC message + * SRB_configList2--> refers to all the SRBs configured for that specific transaction identifier + * this because in a single transaction one or more SRBs could be established + * and you want to keep memory on what happen for every transaction + * Transaction ID (xid): is used to associate the proper RRC....Complete message received by the UE to the corresponding + * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) + * this because it could happen that more messages are transmitted at the same time + */ + SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis + SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs + DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid + uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT + + struct PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; + MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; + + //No SPS(semi-persistent scheduling) in NB-IoT + //No Measurement report in NB-IoT + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1bis; + +#if defined(ENABLE_SECURITY) + /* KeNB as derived from KASME received from EPC */ + uint8_t kenb[32]; +#endif + + /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */ + e_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + + uint8_t Status; + rnti_t rnti; + uint64_t random_ue_identity; + + + + /* Information from UE RRC ConnectionRequest-NB-r13_IE--> NB-IoT */ + UE_S_TMSI_NB_IoT Initialue_identity_s_TMSI; + EstablishmentCause_NB_r13_t establishment_cause_NB_IoT; //different set for NB-IoT + + /* Information from UE RRC ConnectionReestablishmentRequest-NB--> NB-IoT */ + ReestablishmentCause_NB_r13_t reestablishment_cause_NB_IoT; //different set for NB_IoT + + /* UE id for initial connection to S1AP */ + uint16_t ue_initial_id; + + /* Information from S1AP initial_context_setup_req */ + uint32_t eNB_ue_s1ap_id :24; + + security_capabilities_t security_capabilities; + + /* Total number of e_rab already setup in the list */ //NAS list? + uint8_t setup_e_rabs; + /* Number of e_rab to be setup in the list */ //NAS list? + uint8_t nb_of_e_rabs; + /* list of e_rab to be setup by RRC layers */ + e_rab_param_NB_IoT_t e_rab[NB_RB_MAX_NB_IOT];//[S1AP_MAX_E_RAB]; + + // LG: For GTPV1 TUNNELS + uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; + rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + + //Which timers are referring to? + uint32_t ul_failure_timer; + uint32_t ue_release_timer; + //threshold of the release timer--> set in RRCConnectionRelease + uint32_t ue_release_timer_thres; +} eNB_RRC_UE_NB_IoT_t; +//-------------------------------------------------------------------------------- + +typedef uid_NB_IoT_t ue_uid_t; + + +//generally variable called: ue_context_pP +typedef struct rrc_eNB_ue_context_NB_IoT_s { + + /* Tree related data */ + RB_ENTRY(rrc_eNB_ue_context_NB_IoT_s) entries; + + /* Uniquely identifies the UE between MME and eNB within the eNB. + * This id is encoded on 24bits. + */ + rnti_t ue_id_rnti; + + // another key for protocol layers but should not be used as a key for RB tree + ue_uid_t local_uid; + + /* UE id for initial connection to S1AP */ + struct eNB_RRC_UE_NB_IoT_s ue_context; //context of ue in the e-nB + +} rrc_eNB_ue_context_NB_IoT_t; + + + +//---NB-IoT (completely changed)------------------------------- +//called "carrier"--> data from PHY layer +typedef struct { + + // buffer that contains the encoded messages + uint8_t *MIB_NB_IoT; + uint8_t sizeof_MIB_NB_IoT; + + uint8_t *SIB1_NB_IoT; + uint8_t sizeof_SIB1_NB_IoT; + uint8_t *SIB23_NB_IoT; + uint8_t sizeof_SIB23_NB_IoT; + + + //not actually implemented in OAI + uint8_t *SIB4_NB_IoT; + uint8_t sizeof_SIB4_NB_IoT; + uint8_t *SIB5_NB_IoT; + uint8_t sizeof_SIB5_NB_IoT; + uint8_t *SIB14_NB_IoT; + uint8_t sizeof_SIB14_NB_IoT; + uint8_t *SIB16_NB_IoT; + uint8_t sizeof_SIB16_NB_IoT; + + //TS 36.331 V14.2.1 +// uint8_t *SIB15_NB; +// uint8_t sizeof_SIB15_NB; +// uint8_t *SIB20_NB; +// uint8_t sizeof_SIB20_NB; +// uint8_t *SIB22_NB; +// uint8_t sizeof_SIB22_NB; + + //implicit parameters needed + int Ncp; //cyclic prefix for DL + int Ncp_UL; //cyclic prefix for UL + int p_eNB; //number of tx antenna port + int p_rx_eNB; //number of receiving antenna ports + uint32_t dl_CarrierFreq; //detected by the UE + uint32_t ul_CarrierFreq; //detected by the UE + uint16_t physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS + + //are the only static one (memory has been already allocated) + BCCH_BCH_Message_NB_t mib_NB_IoT; + BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB + BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI + + SystemInformationBlockType1_NB_t *sib1_NB_IoT; + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + //not implemented yet + SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; + SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; + SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; + SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; + + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + + uint8_t **MCCH_MESSAGE; // probably not needed , but added to remove errors + uint8_t sizeof_MCCH_MESSAGE[8];// but added to remove errors + SRB_INFO_NB_IoT MCCH_MESS[8];// MAX_MBSFN_AREA + /*future implementation TS 36.331 V14.2.1 + SystemInformationBlockType15_NB_r14_t *sib15; + SystemInformationBlockType20_NB_r14_t *sib20; + SystemInformationBlockType22_NB_r14_t *sib22; + + uint8_t SCPTM_flag; + uint8_t sizeof_SC_MCHH_MESS[]; + SC_MCCH_Message_NB_t scptm;*/ + + +} rrc_eNB_carrier_data_NB_IoT_t; +//--------------------------------------------------- + + + +//---NB-IoT---(completely change)--------------------- +typedef struct eNB_RRC_INST_NB_IoT_s { + + rrc_eNB_carrier_data_NB_IoT_t carrier[MAX_NUM_CCs]; + + uid_allocator_NB_IoT_t uid_allocator; // for rrc_ue_head + RB_HEAD(rrc_ue_tree_NB_IoT_s, rrc_eNB_ue_context_NB_IoT_s) rrc_ue_head; // ue_context tree key search by rnti + + uint8_t Nb_ue; + + hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t + hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t + + //RRC configuration + RrcConfigurationReq configuration; //rrc_messages_types.h + + // other PLMN parameters + /// Mobile country code + int mcc; + /// Mobile network code + int mnc; + /// number of mnc digits + int mnc_digit_length; + + // other RAN parameters //FIXME: to be checked--> depends on APP layer + int srb1_timer_poll_retransmit; + int srb1_max_retx_threshold; + int srb1_timer_reordering; + int srb1_timer_status_prohibit; + int srs_enable[MAX_NUM_CCs]; + + +} eNB_RRC_INST_NB_IoT; + +#define RRC_HEADER_SIZE_MAX_NB_IoT 64 +#define MAX_UE_CAPABILITY_SIZE_NB_IoT 255 + +//not needed for the moment +typedef struct OAI_UECapability_NB_IoT_s { + uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; + uint8_t sdu_size; +////NB-IoT------ + UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE +} OAI_UECapability_NB_IoT_t; + +#define RRC_BUFFER_SIZE_MAX_NB_IoT 1024 + + + +typedef struct UE_RRC_INST_NB_IoT_s { + Rrc_State_NB_IoT_t RrcState; + Rrc_Sub_State_NB_IoT_t RrcSubState; +# if defined(ENABLE_USE_MME) + plmn_t plmnID; + Byte_t rat; + as_nas_info_t initialNasMsg; +# endif + OAI_UECapability_NB_IoT_t *UECap; + uint8_t *UECapability; + uint8_t UECapability_size; + + UE_RRC_INFO_NB_IoT Info[NB_SIG_CNX_UE]; + + SRB_INFO_NB_IoT Srb0[NB_SIG_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1[NB_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb2[NB_CNX_UE]; + HANDOVER_INFO_UE_NB_IoT HandoverInfoUe; + /* + uint8_t *SIB1[NB_CNX_UE]; + uint8_t sizeof_SIB1[NB_CNX_UE]; + uint8_t *SI[NB_CNX_UE]; + uint8_t sizeof_SI[NB_CNX_UE]; + uint8_t SIB1Status[NB_CNX_UE]; + uint8_t SIStatus[NB_CNX_UE]; + SystemInformationBlockType1_t *sib1[NB_CNX_UE]; + SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). + */ + SystemInformationBlockType2_t *sib2[NB_CNX_UE]; + /* + SystemInformationBlockType3_t *sib3[NB_CNX_UE]; + SystemInformationBlockType4_t *sib4[NB_CNX_UE]; + SystemInformationBlockType5_t *sib5[NB_CNX_UE]; + SystemInformationBlockType6_t *sib6[NB_CNX_UE]; + SystemInformationBlockType7_t *sib7[NB_CNX_UE]; + SystemInformationBlockType8_t *sib8[NB_CNX_UE]; + SystemInformationBlockType9_t *sib9[NB_CNX_UE]; + SystemInformationBlockType10_t *sib10[NB_CNX_UE]; + SystemInformationBlockType11_t *sib11[NB_CNX_UE]; + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + uint8_t MBMS_flag; + uint8_t *MCCH_MESSAGE[NB_CNX_UE]; + uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; + uint8_t MCCH_MESSAGEStatus[NB_CNX_UE]; + MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; + SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; + SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; +#endif +#ifdef CBA + uint8_t num_active_cba_groups; + uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; +#endif + uint8_t num_srb; + struct SRB_ToAddMod *SRB1_config[NB_CNX_UE]; + struct SRB_ToAddMod *SRB2_config[NB_CNX_UE]; + struct DRB_ToAddMod *DRB_config[NB_CNX_UE][8]; + rb_id_t *defaultDRB; // remember the ID of the default DRB + MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; + struct ReportConfigToAddMod *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; + */ + struct QuantityConfig *QuantityConfig[NB_CNX_UE]; + /* + struct MeasIdToAddMod *MeasId[NB_CNX_UE][MAX_MEAS_ID]; + MEAS_REPORT_LIST *measReportList[NB_CNX_UE][MAX_MEAS_ID]; + uint32_t measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells + RSRP_Range_t s_measure; + struct MeasConfig__speedStatePars *speedStatePars; + struct PhysicalConfigDedicated *physicalConfigDedicated[NB_CNX_UE]; + struct SPS_Config *sps_Config[NB_CNX_UE]; + MAC_MainConfig_t *mac_MainConfig[NB_CNX_UE]; + MeasGapConfig_t *measGapConfig[NB_CNX_UE]; + double filter_coeff_rsrp; // [7] ??? + double filter_coeff_rsrq; // [7] ??? + float rsrp_db[7]; + float rsrq_db[7]; + float rsrp_db_filtered[7]; + float rsrq_db_filtered[7]; +#if ENABLE_RAL + obj_hash_table_t *ral_meas_thresholds; + ral_transaction_id_t scan_transaction_id; +#endif +#if defined(ENABLE_SECURITY) + // KeNB as computed from parameters within USIM card // + uint8_t kenb[32]; +#endif + + // Used integrity/ciphering algorithms // + CipheringAlgorithm_r12_t ciphering_algorithm; + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + */ +} UE_RRC_INST_NB_IoT; + + +#include "proto_NB_IoT.h" //should be put here otherwise compilation error + +#endif +/** @} */ diff --git a/openair2/RRC/LTE/extern_NB_IoT.h b/openair2/RRC/LTE/extern_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..f136b57b4787613605ad3f579f779b6005963598 --- /dev/null +++ b/openair2/RRC/LTE/extern_NB_IoT.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 vars.h +* \brief rrc external vars +* \author Navid Nikaein and Raymond Knopp, Michele Paffetti +* \date 2011-2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#define __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#include "RRC/LTE/defs_NB_IoT.h" +#include "PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "LAYER2/RLC/rlc.h" +#include "LogicalChannelConfig-NB-r13.h" +#include "LAYER2/MAC/defs_NB_IoT.h" + +#include "common/ran_context.h" + + +//MP: NOTE:XXX some of the parameters defined in vars_nb_iot are called by the extern.h file so not replicated here + +extern UE_RRC_INST_NB_IoT *UE_rrc_inst_NB_IoT; + +extern eNB_RRC_INST_NB_IoT *eNB_rrc_inst_NB_IoT; +extern PHY_Config_NB_IoT_t *config_INFO; + +extern rlc_info_t Rlc_info_am_NB_IoT,Rlc_info_am_config_NB_IoT; +extern uint8_t DRB2LCHAN_NB_IoT[2]; +extern LogicalChannelConfig_NB_r13_t SRB1bis_logicalChannelConfig_defaultValue_NB_IoT; +extern LogicalChannelConfig_NB_r13_t SRB1_logicalChannelConfig_defaultValue_NB_IoT; + +extern uint16_t T300_NB_IoT[8]; +extern uint16_t T301_NB_IoT[8]; +extern uint16_t T310_NB_IoT[8]; +extern uint16_t T311_NB_IoT[8]; +extern uint16_t N310_NB_IoT[8]; +extern uint16_t N311_NB_IoT[8]; +extern uint8_t *get_NB_IoT_MIB(struct eNB_RRC_INST_NB_IoT_s *nb_iot_rrc); +#endif + + diff --git a/openair2/RRC/LITE/plmn_data.h b/openair2/RRC/LTE/plmn_data.h similarity index 100% rename from openair2/RRC/LITE/plmn_data.h rename to openair2/RRC/LTE/plmn_data.h diff --git a/openair2/RRC/LTE/proto_NB_IoT.h b/openair2/RRC/LTE/proto_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..de09d39fab7b100b9335489cae95a513068baea2 --- /dev/null +++ b/openair2/RRC/LTE/proto_NB_IoT.h @@ -0,0 +1,260 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 proto_NB_IoT.h + * \brief RRC functions prototypes for eNB and UE for NB-IoT + * \author Navid Nikaein, Raymond Knopp and Michele Paffetti + * \date 2010 - 2014 + * \email navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it + * \version 1.0 + + */ +/** \addtogroup _rrc + * @{ + */ + +#include "RRC/LTE/defs_NB_IoT.h" +#include "pdcp.h" +#include "rlc.h" +#include "extern_NB_IoT.h" +#include "LAYER2/MAC/defs_NB_IoT.h" +/*NOTE: no static function should be declared in this header file (e.g. init_SI_NB)*/ + +/*------------------------common_nb_iot.c----------------------------------------*/ + +/** \brief configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs + */ +void openair_rrc_on_NB_IoT(const protocol_ctxt_t* const ctxt_pP); + +void rrc_config_buffer_NB_IoT(SRB_INFO_NB_IoT *srb_info, uint8_t Lchan_type, uint8_t Role); + +int L3_xface_init_NB_IoT(void); + +void openair_rrc_top_init_eNB_NB_IoT(void); + +//void rrc_top_cleanup(void); -->seems not to be used + +//rrc_t310_expiration-->seems not to be used + +/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310. +@param ctxt_pP running context +@param enb_index +@param CC_id +*/ +RRC_status_t rrc_rx_tx_NB_IoT(protocol_ctxt_t* const ctxt_pP, const uint8_t enb_index, const int CC_id); + +//long binary_search_int(int elements[], long numElem, int value);--> seems not to be used +//long binary_search_float(float elements[], long numElem, float value);--> used only at UE side + + + +//--------------------------------------- + + +//defined in L2_interface +//called by rx_sdu only in case of CCCH message (e.g RRCConnectionRequest-NB) +int8_t mac_rrc_data_ind_eNB_NB_IoT( + const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const rnti_t rntiP, + const rb_id_t srb_idP,//could be skipped since always go through the CCCH channel + const uint8_t* sduP, + const sdu_size_t sdu_lenP +); +//------------------------------------------- + +//defined in L2_interface +void dump_ue_list_NB_IoT(UE_list_NB_IoT_t *listP, int ul_flag); +//------------------------------------------- + + +//defined in L2_interface +void mac_eNB_rrc_ul_failure_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ + +//defined in eNB_scheduler_primitives.c +int rrc_mac_remove_ue_NB_IoT( + module_id_t mod_idP, + rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +void mac_eNB_rrc_ul_in_sync_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +int mac_eNB_get_rrc_status_NB_IoT( + const module_id_t Mod_idP, + const rnti_t rntiP +); +//--------------------------- + + +/*-----------eNB procedures (rrc_eNB_nb_iot.c)---------------*/ + +//---Initialization-------------- +void openair_eNB_rrc_on_NB_IoT( + const protocol_ctxt_t* const ctxt_pP +); + +void rrc_config_buffer_NB_IoT( + SRB_INFO_NB_IoT* Srb_info, + uint8_t Lchan_type, + uint8_t Role +); + +char openair_rrc_eNB_configuration_NB_IoT( + const module_id_t enb_mod_idP, + NbIoTRrcConfigurationReq* configuration +); + +//----------------------------- +/**\brief RRC eNB task. (starting of the RRC state machine) + \param void *args_p Pointer on arguments to start the task. */ +void *rrc_enb_task_NB_IoT(void *args_p); + +/**\brief Entry routine to decode a UL-CCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Running context + \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/ +int rrc_eNB_decode_ccch_NB_IoT( + protocol_ctxt_t* const ctxt_pP, + const SRB_INFO_NB_IoT* const Srb_info, + const int CC_id +); + +/**\brief Entry routine to decode a UL-DCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Context + \param Rx_sdu Pointer Received Message + \param sdu_size Size of incoming SDU*/ +int rrc_eNB_decode_dcch_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t Srb_id, + const uint8_t* const Rx_sdu, + const sdu_size_t sdu_sizeP +); + +/**\brief Generate RRCConnectionReestablishmentReject-NB + \param ctxt_pP Running context + \param ue_context_pP UE context + \param CC_id Component Carrier ID*/ +void rrc_eNB_generate_RRCConnectionReestablishmentReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_process_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + const uint8_t xid //transaction identifier +); + + +void //was under ITTI +rrc_eNB_reconfigure_DRBs_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP); + +void //was under ITTI +rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +// const uint8_t ho_state + ); + +void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB +); + +void rrc_eNB_generate_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_defaultRRCConnectionReconfiguration_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP + //no HO flag + ); + + +/// Utilities------------------------------------------------ + +void rrc_eNB_free_UE_NB_IoT( + const module_id_t enb_mod_idP, + const struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP + ); + +void rrc_eNB_free_mem_UE_context_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP +); + + + +/**\brief Function to get the next transaction identifier. + \param module_idP Instance ID for CH/eNB + \return a transaction identifier*/ +uint8_t rrc_eNB_get_next_transaction_identifier_NB_IoT(module_id_t module_idP); + + +int rrc_init_global_param_NB_IoT(void); + +//L2_interface.c +int8_t mac_rrc_data_req_eNB_NB_IoT( + const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const frame_t h_frameP, + const sub_frame_t subframeP, //need for the case in which both SIB1-NB_IoT and SIB23-NB_IoT will be scheduled in the same frame + const rb_id_t Srb_id, + uint8_t* const buffer_pP, + uint8_t flag +); + + + diff --git a/openair2/RRC/LITE/rrc_2_rrm_msg.c b/openair2/RRC/LTE/rrc_2_rrm_msg.c similarity index 100% rename from openair2/RRC/LITE/rrc_2_rrm_msg.c rename to openair2/RRC/LTE/rrc_2_rrm_msg.c diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c similarity index 68% rename from openair2/RRC/LITE/rrc_UE.c rename to openair2/RRC/LTE/rrc_UE.c index 260e1b729fc685651e8b4234c6bbdcfa68af91d4..49ed33d12960c4d34b8b332e05e3191a87faef57 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -30,20 +30,21 @@ #define RRC_UE #define RRC_UE_C +#define _GNU_SOURCE #include "assertions.h" #include "hashtable.h" #include "asn1_conversions.h" -#include "defs.h" -#include "PHY/TOOLS/dB_routines.h" -#include "extern.h" +#include "rrc_defs.h" +#include "rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "openair1/PHY/LTE_ESTIMATION/lte_estimation.h" #include "LAYER2/RLC/rlc.h" #include "COMMON/mac_rrc_primitives.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #ifndef CELLULAR -#include "RRC/LITE/MESSAGES/asn1_msg.h" +#include "RRC/LTE/MESSAGES/asn1_msg.h" #endif #include "RRCConnectionRequest.h" #include "RRCConnectionReconfiguration.h" @@ -53,7 +54,7 @@ #include "DL-DCCH-Message.h" #include "BCCH-DL-SCH-Message.h" #include "PCCH-Message.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "MCCH-Message.h" #endif #include "MeasConfig.h" @@ -80,21 +81,27 @@ # include "intertask_interface.h" #endif -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus +#include "openair2/LAYER2/MAC/mac_extern.h" -#ifdef PHY_EMUL -extern EMULATION_VARS *Emul_vars; -#endif -extern eNB_MAC_INST *eNB_mac_inst; -extern UE_MAC_INST *UE_mac_inst; -#ifdef BIGPHYSAREA -extern void *bigphys_malloc(int); +#ifdef Rel14 +#include "SL-Preconfiguration-r12.h" + +//for D2D +int ctrl_sock_fd; +#define BUFSIZE 1024 +struct sockaddr_in prose_app_addr; +int slrb_id; +int send_ue_information = 0; #endif +// for malloc_clear +#include "PHY/defs_UE.h" + //#define XER_PRINT -//extern int8_t dB_fixed2(uint32_t x,uint32_t y); + extern void pdcp_config_set_security( const protocol_ctxt_t* const ctxt_pP, @@ -139,8 +146,9 @@ static uint8_t check_trigger_meas_event( Q_OffsetRange_t ofn, Q_OffsetRange_t ocn, Hysteresis_t hys, Q_OffsetRange_t ofs, Q_OffsetRange_t ocs, long a3_offset, TimeToTrigger_t ttt); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); +uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index,SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); #endif @@ -233,6 +241,30 @@ static int rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_t subState ) return (0); } +//----------------------------------------------------------------------------- +void +openair_rrc_on_ue( + const protocol_ctxt_t* const ctxt_pP +) +//----------------------------------------------------------------------------- +{ + unsigned short i; + + + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); + + for (i = 0; i < NB_eNB_INST; i++) { + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" Activating CCCH (eNB %d)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), i); + UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Srb_id = CCCH; + memcpy (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Lchan_desc[0], &CCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + memcpy (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Lchan_desc[1], &CCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + rrc_config_buffer (&UE_rrc_inst[ctxt_pP->module_id].Srb0[i], CCCH, 1); + UE_rrc_inst[ctxt_pP->module_id].Srb0[i].Active = 1; + } +} + //----------------------------------------------------------------------------- static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index ) { @@ -250,9 +282,13 @@ static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType9_t) ); UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType10_t) ); UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType11_t) ); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType12_r9_t) ); UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType13_r9_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType18_r12_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType19_r12_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType21_r14_t) ); + #endif UE_rrc_inst[ctxt_pP->module_id].SI[eNB_index] = (uint8_t*)malloc16_clear( 64 ); @@ -262,10 +298,184 @@ static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt = 0; } +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) +{ + LOG_I(RRC,"Initializing Sidelink Pre-configuration for UE\n"); + + UE->SL_Preconfiguration[eNB_index] = malloc16_clear( sizeof(struct SL_Preconfiguration_r12) ); + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.rohc_Profiles_r12.profile0x0001_r12 = true; + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.carrierFreq_r12 = 3350; + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.maxTxPower_r12 = 0; + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.additionalSpectrumEmission_r12 = 0; + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.sl_bandwidth_r12 = SL_PreconfigGeneral_r12__sl_bandwidth_r12_n50; + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.tdd_ConfigSL_r12.subframeAssignmentSL_r12 = TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; + + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncCP_Len_r12 = SL_CP_Len_r12_normal; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncOffsetIndicator1_r12 = 0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncOffsetIndicator2_r12 = 0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncTxParameters_r12 = 0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncTxThreshOoC_r12 = 0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.filterCoefficient_r12 = FilterCoefficient_fc0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefMinHyst_r12 = SL_PreconfigSync_r12__syncRefMinHyst_r12_dB0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefDiffHyst_r12 = SL_PreconfigSync_r12__syncRefDiffHyst_r12_dB0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.ext1 = malloc16_clear(sizeof(struct SL_PreconfigSync_r12__ext1)); + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.ext1->syncTxPeriodic_r13 = NULL; + + struct SL_PreconfigCommPool_r12 *preconfigpool = malloc16_clear(sizeof(struct SL_PreconfigCommPool_r12)); + preconfigpool->sc_CP_Len_r12 = SL_CP_Len_r12_normal; + preconfigpool->sc_Period_r12 = SL_PeriodComm_r12_sf40; + // 20 PRBs for SL communications + preconfigpool->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20; + preconfigpool->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5; + preconfigpool->sc_TF_ResourceConfig_r12.prb_End_r12 = 44; + // Offset set to 0 subframes + preconfigpool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + preconfigpool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; + // 40 ms SL Period + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; + // 1st 4 subframes for PSCCH + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[0] = 0xF; + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[1] = 0; + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[2] = 0; + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[3] = 0; + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[4] = 0; + preconfigpool->sc_TxParameters_r12 = 0; + + preconfigpool->data_CP_Len_r12 = SL_CP_Len_r12_normal; + // 20 PRBs for SL communications + preconfigpool->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; + preconfigpool->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; + preconfigpool->data_TF_ResourceConfig_r12.prb_End_r12 = 44; + // Offset set to 0 subframes + preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; + // 40 ms SL Period + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; + // last 36 subframes for PSCCH + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[0] = 0xF0; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[1] = 0xFF; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[2] = 0xFF; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[3] = 0xFF; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[5] = 0xFF; + + preconfigpool->dataHoppingConfig_r12.hoppingParameter_r12 = 0; + preconfigpool->dataHoppingConfig_r12.numSubbands_r12 = SL_HoppingConfigComm_r12__numSubbands_r12_ns1; + preconfigpool->dataHoppingConfig_r12.rb_Offset_r12 = 0; + + preconfigpool->dataTxParameters_r12 = 0; + + ASN_SEQUENCE_ADD(&UE->SL_Preconfiguration[eNB_index]->preconfigComm_r12.list,preconfigpool); + + // Rel13 extensions + UE->SL_Preconfiguration[eNB_index]->ext1 = NULL; +/* + // Establish a SLRB (using DRB 3 for now) + protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + UE->DRB_config[0][0]->drb_Identity = 3; + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3; + UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + // TTN - Establish a new SLRB for PC5-S (using DRB 10 for now) + UE->DRB_config[0][1] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][1]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + UE->DRB_config[0][1]->drb_Identity = 10; + UE->DRB_config[0][1]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(UE->DRB_config[0][1]->eps_BearerIdentity) = 10; + UE->DRB_config[0][1]->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(UE->DRB_config[0][1]->logicalChannelIdentity) = UE->DRB_config[0][1]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + struct RLC_Config *DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); + struct PDCP_Config *DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); + struct PDCP_Config__rlc_UM *PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); + struct LogicalChannelConfig *DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); + struct LogicalChannelConfig__ul_SpecificParameters + *DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + long *logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; + UE->DRB_config[0][1]->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; + UE->DRB_config[0][1]->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + // avoid gcc warnings + (void)PDCP_rlc_UM; + + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; + UE->DRB_config[0][1]->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); + ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][1]); + + rrc_pdcp_config_asn1_req(&ctxt, + (SRB_ToAddModList_t *) NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*) NULL, + 0xff, NULL, NULL, NULL +#if defined(Rel10) || defined(Rel14) + , (PMCH_InfoList_r9_t *) NULL +#endif + ,NULL); + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL #if defined(Rel10) || defined(Rel14) + ,(PMCH_InfoList_r9_t *)NULL +#endif + ); +*/ +} + +#endif + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //----------------------------------------------------------------------------- #if 0 -static void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index) +void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index) { int i; UE_rrc_inst[ue_mod_idP].sizeof_MCCH_MESSAGE[eNB_index] = 0; @@ -281,7 +491,7 @@ static void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index) #endif //----------------------------------------------------------------------------- -static void openair_rrc_ue_init_security( const protocol_ctxt_t* const ctxt_pP ) +void openair_rrc_ue_init_security( const protocol_ctxt_t* const ctxt_pP ) { #if defined(ENABLE_SECURITY) // uint8_t *kRRCenc; @@ -323,7 +533,7 @@ char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_ UE_rrc_inst[ctxt.module_id].Srb2[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].HandoverInfoUe.measFlag=1; UE_rrc_inst[ctxt.module_id].ciphering_algorithm = CipheringAlgorithm_r12_eea0; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 2, 0)) UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920; #else UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved; @@ -334,12 +544,18 @@ char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_ LOG_D(RRC,PROTOCOL_RRC_CTXT_FMT" INIT: phy_sync_2_ch_ind\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); + + +#ifndef NO_RRM + send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id)); +#endif + #ifndef NO_RRM send_msg(&S_rrc,msg_rrc_phy_synch_to_CH_ind(ctxt.module_id,eNB_index,UE_rrc_inst[ctxt.module_id].Mac_id)); #endif #ifdef NO_RRM //init ch SRB0, SRB1 & BDTCH - openair_rrc_on(&ctxt); + openair_rrc_on_ue(&ctxt); #endif #ifdef CBA int j; @@ -430,6 +646,47 @@ static const char const nas_attach_req_guti[] = { }; #endif +//----------------------------------------------------------------------------- +void +rrc_t310_expiration( + const protocol_ctxt_t* const ctxt_pP, + const uint8_t eNB_index +) +//----------------------------------------------------------------------------- +{ + + if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State != RRC_CONNECTED) { + LOG_D(RRC, "Timer 310 expired, going to RRC_IDLE\n"); + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_IDLE; + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].UE_index = 0xffff; + UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Rx_buffer.payload_size = 0; + UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size = 0; + UE_rrc_inst[ctxt_pP->module_id].Srb1[eNB_index].Srb_info.Rx_buffer.payload_size = 0; + UE_rrc_inst[ctxt_pP->module_id].Srb1[eNB_index].Srb_info.Tx_buffer.payload_size = 0; + + if (UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active == 1) { + LOG_D (RRC,"[Inst %d] eNB_index %d, Remove RB %d\n ", ctxt_pP->module_id, eNB_index, + UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id); + rrc_pdcp_config_req (ctxt_pP, + SRB_FLAG_YES, + CONFIG_ACTION_REMOVE, + UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id, + 0); + rrc_rlc_config_req (ctxt_pP, + SRB_FLAG_YES, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Srb_info.Srb_id, + Rlc_info_um); + UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Active = 0; + UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Status = IDLE; + UE_rrc_inst[ctxt_pP->module_id].Srb2[eNB_index].Next_check_frame = 0; + } + } else { // Restablishment procedure + LOG_D(RRC, "Timer 310 expired, trying RRCRestablishment ...\n"); + } +} + //----------------------------------------------------------------------------- static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) { @@ -454,7 +711,7 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* c LOG_D(RLC, "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", ctxt_pP->frame, ctxt_pP->module_id+NB_eNB_INST, size, eNB_index, rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH); - rrc_data_req ( + rrc_data_req_ue ( ctxt_pP, DCCH, rrc_mui++, @@ -465,7 +722,7 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* c } //----------------------------------------------------------------------------- -static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) +void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) { uint8_t buffer[32], size; @@ -481,7 +738,7 @@ static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol rrc_mui, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), DCCH); - rrc_data_req ( + rrc_data_req_ue ( ctxt_pP, DCCH, rrc_mui++, @@ -529,6 +786,7 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co char message_string[10000]; size_t message_string_size; + //LOG_I(RRC, "Panos-D: rrc_ue_decode_ccch, Before xer_sprint() \n"); if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) { MessageDef *msg_p; @@ -725,7 +983,7 @@ rrc_ue_establish_drb( #ifdef PDCP_USE_NETLINK # if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) ip_addr_offset3 = 0; - ip_addr_offset4 = 8; + ip_addr_offset4 = 1; LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP, // interface_id @@ -808,7 +1066,7 @@ rrc_ue_process_measConfig( rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -825,7 +1083,7 @@ rrc_ue_process_measConfig( NULL, NULL, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL @@ -835,6 +1093,12 @@ rrc_ue_process_measConfig( , 0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); } @@ -1270,7 +1534,7 @@ rrc_ue_process_radioResourceConfigDedicated( kRRCenc, kRRCint, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(PMCH_InfoList_r9_t *)NULL #endif ,NULL); @@ -1280,8 +1544,9 @@ rrc_ue_process_radioResourceConfigDedicated( radioResourceConfigDedicated->srb_ToAddModList, (DRB_ToAddModList_t*)NULL, (DRB_ToReleaseList_t*)NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(PMCH_InfoList_r9_t *)NULL + , 0, 0 #endif ); @@ -1320,7 +1585,7 @@ rrc_ue_process_radioResourceConfigDedicated( rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -1337,7 +1602,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -1347,6 +1612,12 @@ rrc_ue_process_radioResourceConfigDedicated( , 0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); } @@ -1378,7 +1649,7 @@ rrc_ue_process_radioResourceConfigDedicated( rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -1395,7 +1666,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -1406,6 +1677,12 @@ rrc_ue_process_radioResourceConfigDedicated( , 0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); } @@ -1452,7 +1729,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, kUPenc -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(PMCH_InfoList_r9_t *)NULL #endif , UE_rrc_inst[ctxt_pP->module_id].defaultDRB); @@ -1462,8 +1739,9 @@ rrc_ue_process_radioResourceConfigDedicated( (SRB_ToAddModList_t*)NULL, radioResourceConfigDedicated->drb_ToAddModList, (DRB_ToReleaseList_t*)NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,(PMCH_InfoList_r9_t *)NULL + , 0, 0 #endif ); @@ -1486,7 +1764,7 @@ rrc_ue_process_radioResourceConfigDedicated( rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -1503,7 +1781,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -1513,13 +1791,19 @@ rrc_ue_process_radioResourceConfigDedicated( , UE_rrc_inst[ue_mod_idP].num_active_cba_groups, // UE_rrc_inst[ue_mod_idP].cba_rnti[0] +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); - + } } } - + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_CONNECTED; LOG_I(RRC,"[UE %d] State = RRC_CONNECTED (eNB %d)\n",ctxt_pP->module_id,eNB_index); } @@ -1542,8 +1826,8 @@ rrc_ue_process_securityModeCommand( uint8_t buffer[200]; int i, securityMode; - LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", - ctxt_pP->module_id,ctxt_pP->frame,eNB_index); + LOG_I(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", + ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index); switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) { case CipheringAlgorithm_r12_eea0: @@ -1600,8 +1884,10 @@ rrc_ue_process_securityModeCommand( ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; if (securityMode >= NO_SECURITY_MODE) { + LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n"); ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeComplete; } else { + LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n"); ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeFailure; } @@ -1652,52 +1938,56 @@ rrc_ue_process_securityModeCommand( | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4), kRRCenc, kRRCint, kUPenc); } else { - LOG_W(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", + LOG_I(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); } } else { - LOG_W(RRC, "Could not get PDCP instance where key=0x%ld\n", key); + LOG_I(RRC, "Could not get PDCP instance where key=0x%ld\n", key); } #endif //#if defined(ENABLE_SECURITY) if (securityModeCommand->criticalExtensions.present == SecurityModeCommand__criticalExtensions_PR_c1) { - if (securityModeCommand->criticalExtensions.choice.c1.present == SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) { - - ul_dcch_msg.message.choice.c1.choice.securityModeComplete.rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; - ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; - ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.choice.securityModeComplete_r8.nonCriticalExtension =NULL; - - LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d)\n", - ctxt_pP->module_id,ctxt_pP->frame,eNB_index); - - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, - (void*)&ul_dcch_msg, - buffer, - 100); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - + if (securityModeCommand->criticalExtensions.choice.c1.present != SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) + LOG_W(RRC,"securityModeCommand->criticalExtensions.choice.c1.present (%d) != SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8\n", + securityModeCommand->criticalExtensions.choice.c1.present); + + + ul_dcch_msg.message.choice.c1.choice.securityModeComplete.rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; + ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.choice.securityModeComplete_r8.nonCriticalExtension =NULL; + + LOG_I(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d), rrc_TransactionIdentifier: %ld\n", + ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index, securityModeCommand->rrc_TransactionIdentifier); + + enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, + (void*)&ul_dcch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + #ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); #endif - + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } + { + char message_string[20000]; + size_t message_string_size; + + //LOG_I(RRC, "Panos-D: rrc_ue_process_securityModeCommand, Before xer_sprint() \n"); + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } + } # endif #endif @@ -1717,7 +2007,9 @@ rrc_ue_process_securityModeCommand( buffer, PDCP_TRANSMISSION_MODE_CONTROL); } - } + + else LOG_W(RRC,"securityModeCommand->criticalExtensions.present (%d) != SecurityModeCommand__criticalExtensions_PR_c1\n", + securityModeCommand->criticalExtensions.present); } //----------------------------------------------------------------------------- @@ -1761,66 +2053,72 @@ rrc_ue_process_ueCapabilityEnquiry( // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size; - if (UECapabilityEnquiry->criticalExtensions.present == UECapabilityEnquiry__criticalExtensions_PR_c1) { - if (UECapabilityEnquiry->criticalExtensions.choice.c1.present == UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8) { - ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.present = UECapabilityInformation__criticalExtensions_PR_c1; - ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.present = - UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8; - ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count - =0; - - for (i=0; i<UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count; i++) { - - if (*UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.array[i] - == RAT_Type_eutra) { - ASN_SEQUENCE_ADD( - &ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list, - &ue_CapabilityRAT_Container); - - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, (void*) &ul_dcch_msg, buffer, 100); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); + AssertFatal(UECapabilityEnquiry->criticalExtensions.present == UECapabilityEnquiry__criticalExtensions_PR_c1, + "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n", + UECapabilityEnquiry->criticalExtensions.present,UECapabilityEnquiry__criticalExtensions_PR_c1); + if (UECapabilityEnquiry->criticalExtensions.choice.c1.present != UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8) + LOG_I(RRC,"UECapabilityEnquiry->criticalExtensions.choice.c1.present (%d) != UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8)\n", + UECapabilityEnquiry->criticalExtensions.choice.c1.present); + + ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.present = UECapabilityInformation__criticalExtensions_PR_c1; + ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.present = + UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8; + ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count + =0; + + for (i=0; i<UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count; i++) { + + if (*UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.array[i] + == RAT_Type_eutra) { + ASN_SEQUENCE_ADD( + &ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list, + &ue_CapabilityRAT_Container); + + enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, (void*) &ul_dcch_msg, buffer, 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + #ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); #endif - + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } + { + char message_string[20000]; + size_t message_string_size; + + //LOG_I(RRC, "Panos-D: rrc_ue_process_ueCapabilityEnquiry, Before xer_sprint() \n"); + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); + } + } # endif #endif + - LOG_D(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + LOG_I(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) { LOG_T(RRC, "%02x.", buffer[i]); } - - LOG_T(RRC, "\n"); - rrc_data_req ( - ctxt_pP, - DCCH, - rrc_mui++, - SDU_CONFIRM_NO, - (enc_rval.encoded + 7) / 8, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - } - } + + LOG_T(RRC, "\n"); + rrc_data_req_ue ( + ctxt_pP, + DCCH, + rrc_mui++, + SDU_CONFIRM_NO, + (enc_rval.encoded + 7) / 8, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } } } @@ -1865,6 +2163,45 @@ rrc_ue_process_rrcConnectionReconfiguration( rrc_ue_process_radioResourceConfigDedicated(ctxt_pP,eNB_index, rrcConnectionReconfiguration_r8->radioResourceConfigDedicated); } + //TTN for D2D + //if RRCConnectionReconfiguration message includes the sl-CommConfig + if ((rrcConnectionReconfiguration_r8->nonCriticalExtension != NULL) + && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension + != NULL) + && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension + != NULL) + && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension + != NULL) + && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension + != NULL) + && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 + != NULL)) { + if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12->commTxResources_r12->present != SL_CommConfig_r12__commTxResources_r12_PR_NOTHING){ + LOG_I(RRC,"sl-CommConfig is present\n"); + //process sl-CommConfig + rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, + (SystemInformationBlockType18_r12_t *)NULL, + (SystemInformationBlockType19_r12_t *)NULL, + rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, + (SL_DiscConfig_r12_t *)NULL + ); + } + } + +/* + //if RRCConnectionReconfiguration message includes the sl-DiscConfig + if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12->discTxResources_r12->present != SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING ){ + LOG_I(RRC,"sl-DiscConfig is present\n"); + //process sl-DiscConfig + rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, + (SystemInformationBlockType18_r12_t *)NULL, + (SystemInformationBlockType19_r12_t *)NULL, + (SL_CommConfig_r12_t* )NULL, + rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 + ); + } +*/ + #if defined(ENABLE_ITTI) /* Check if there is dedicated NAS information to forward to NAS */ @@ -1987,7 +2324,7 @@ rrc_ue_process_mobilityControlInfo( NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,NULL #endif ,NULL); @@ -1996,7 +2333,7 @@ rrc_ue_process_mobilityControlInfo( NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList drb2release_list // DRB_ToReleaseList -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,NULL #endif ,NULL); @@ -2031,7 +2368,7 @@ rrc_ue_process_mobilityControlInfo( eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -2048,7 +2385,7 @@ rrc_ue_process_mobilityControlInfo( NULL, NULL, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL @@ -2056,9 +2393,15 @@ rrc_ue_process_mobilityControlInfo( #ifdef CBA ,0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); - + // Re-establish PDCP for all RBs that are established // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DCCH); // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DCCH1); @@ -2141,6 +2484,7 @@ rrc_ue_decode_dcch( char message_string[30000]; size_t message_string_size; + //LOG_I(RRC, "Panos-D: rrc_ue_decode_dcch, Before xer_sprint() \n"); if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *)dl_dcch_msg)) > 0) { msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; @@ -2356,6 +2700,22 @@ rrc_ue_decode_dcch( } + //TTN test D2D (should not be here - in reality, this message will be triggered from ProSeApp) + if (send_ue_information == 0) { + LOG_I(RRC, "TEST SidelinkUEInformation [UE %d] Received (eNB %d)\n", + ctxt_pP->module_id, eNB_indexP); + SL_DestinationInfoList_r12_t *destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + SL_DestinationIdentity_r12_t *sl_destination_identity = CALLOC(1, sizeof(SL_DestinationIdentity_r12_t)); + sl_destination_identity->size = 3; + sl_destination_identity->buf = CALLOC(1,3); + sl_destination_identity->buf[0] = 0x00; + sl_destination_identity->buf[1] = 0x00; + sl_destination_identity->buf[2] = 0x01; + sl_destination_identity->bits_unused = 0; + ASN_SEQUENCE_ADD(&destinationInfoList->list,sl_destination_identity); + rrc_ue_generate_SidelinkUEInformation(ctxt_pP, eNB_indexP, destinationInfoList, NULL, SL_TRANSMIT_NON_RELAY_ONE_TO_ONE); + send_ue_information ++; + } break; case DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: @@ -2401,11 +2761,11 @@ rrc_ue_decode_dcch( case DL_DCCH_MessageType__c1_PR_counterCheck: break; -#if defined(Rel10) || defined(Rel14) - +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) case DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9: break; - +#endif +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10: break; @@ -2416,7 +2776,7 @@ rrc_ue_decode_dcch( case DL_DCCH_MessageType__c1_PR_spare1: case DL_DCCH_MessageType__c1_PR_spare2: case DL_DCCH_MessageType__c1_PR_spare3: -#if !defined(Rel14) +#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) case DL_DCCH_MessageType__c1_PR_spare4: #endif break; @@ -2439,7 +2799,7 @@ const char SIBType[12][6] = {"SIB3","SIB4","SIB5","SIB6","SIB7","SIB8","SIB9","S const char SIBPeriod[8][6]= {"rf8","rf16","rf32","rf64","rf128","rf256","rf512","ERR"}; int siPeriod_int[7] = {80,160,320,640,1280,2560,5120}; -static const char* SIBreserved( long value ) +const char* SIBreserved( long value ) { if (value < 0 || value > 1) return "ERR"; @@ -2449,7 +2809,7 @@ static const char* SIBreserved( long value ) return "reserved"; } -static const char* SIBbarred( long value ) +const char* SIBbarred( long value ) { if (value < 0 || value > 1) return "ERR"; @@ -2459,7 +2819,7 @@ static const char* SIBbarred( long value ) return "barred"; } -static const char* SIBallowed( long value ) +const char* SIBallowed( long value ) { if (value < 0 || value > 1) return "ERR"; @@ -2469,7 +2829,7 @@ static const char* SIBallowed( long value ) return "allowed"; } -static const char* SIB2SoundingPresent( int value ) +const char* SIB2SoundingPresent( int value ) { switch (value) { case SoundingRS_UL_ConfigCommon_PR_NOTHING: @@ -2484,7 +2844,7 @@ static const char* SIB2SoundingPresent( int value ) return "ERR"; } -static const char* SIB2numberOfRA_Preambles( long value ) +const char* SIB2numberOfRA_Preambles( long value ) { static char temp[4] = {0}; @@ -2495,7 +2855,7 @@ static const char* SIB2numberOfRA_Preambles( long value ) temp[3] = 0; // terminate string return temp; } -static const char* SIB2powerRampingStep( long value ) +const char* SIB2powerRampingStep( long value ) { if (value < 0 || value > 3) return "ERR"; @@ -2503,7 +2863,7 @@ static const char* SIB2powerRampingStep( long value ) static const char str[4][4] = {"dB0","dB2","dB4","dB6"}; return str[value]; } -static const char* SIB2preambleInitialReceivedTargetPower( long value ) +const char* SIB2preambleInitialReceivedTargetPower( long value ) { static char temp[8] = {0}; @@ -2514,7 +2874,7 @@ static const char* SIB2preambleInitialReceivedTargetPower( long value ) temp[7] = 0; // terminate string return temp; } -static const char* SIB2preambleTransMax( long value ) +const char* SIB2preambleTransMax( long value ) { static char temp[5] = {0}; @@ -2546,7 +2906,7 @@ static const char* SIB2preambleTransMax( long value ) /* unreachable but gcc warns... */ return "ERR"; } -static const char* SIB2ra_ResponseWindowSize( long value ) +const char* SIB2ra_ResponseWindowSize( long value ) { static char temp[4] = {0}; @@ -2559,7 +2919,7 @@ static const char* SIB2ra_ResponseWindowSize( long value ) snprintf( temp, sizeof(temp), "sf%ld", value+2 ); return temp; } -static const char* SIB2mac_ContentionResolutionTimer( long value ) +const char* SIB2mac_ContentionResolutionTimer( long value ) { static char temp[5] = {0}; @@ -2569,7 +2929,7 @@ static const char* SIB2mac_ContentionResolutionTimer( long value ) snprintf( temp, sizeof(temp), "sf%ld", 8 + value*8 ); return temp; } -static const char* SIB2modificationPeriodCoeff( long value ) +const char* SIB2modificationPeriodCoeff( long value ) { static char temp[32] = {0}; @@ -2579,7 +2939,7 @@ static const char* SIB2modificationPeriodCoeff( long value ) snprintf( temp, sizeof(temp), "n%d", (int)pow(2,value+1) ); return temp; } -static const char* SIB2defaultPagingCycle( long value ) +const char* SIB2defaultPagingCycle( long value ) { static char temp[32] = {0}; @@ -2589,7 +2949,7 @@ static const char* SIB2defaultPagingCycle( long value ) snprintf( temp, sizeof(temp), "rf%d", (int)pow(2,value+4) ); return temp; } -static const char* SIB2nB( long value ) +const char* SIB2nB( long value ) { if (value < 0 || value > 7) return "ERR"; @@ -2660,6 +3020,7 @@ int decode_BCCH_DLSCH_Message( char message_string[15000]; size_t message_string_size; + //LOG_I(RRC, "Panos-D: decode_BCCH_DLSCH_Message, Before xer_sprint() \n"); if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { MessageDef *msg_p; @@ -2684,6 +3045,9 @@ int decode_BCCH_DLSCH_Message( (void*)&bcch_message->message.choice.c1.choice.systemInformationBlockType1, sizeof(SystemInformationBlockType1_t) ); LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id ); + + //LOG_I( RRC, "Panos-D: decode_BCCH_DLSCH_Message1 BEFORE decode_SIB1"); + //printf("Panos-D: decode_BCCH_DLSCH_Message1 BEFORE decode_SIB1"); decode_SIB1( ctxt_pP, eNB_index, rsrq, rsrp ); } } @@ -2702,8 +3066,11 @@ int decode_BCCH_DLSCH_Message( LOG_D( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n", ctxt_pP->module_id, ctxt_pP->frame ); - + //LOG_I( RRC, "Panos-D: decode_BCCH_DLSCH_Message1 BEFORE OTHER decode_SI"); + //printf("Panos-D: decode_BCCH_DLSCH_Message1 BEFORE OTHER decode_SI"); decode_SI( ctxt_pP, eNB_index ); + //if (nfapi_mode == 3) + UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; } break; @@ -2763,7 +3130,7 @@ int decode_PCCH_DLSCH_Message( } //----------------------------------------------------------------------------- -static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) +int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) { SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; @@ -2887,7 +3254,7 @@ static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -2904,7 +3271,7 @@ static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ NULL, NULL, (MBSFN_SubframeConfigList_t *)NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL @@ -2914,9 +3281,15 @@ static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ , 0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); - + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; @@ -2994,7 +3367,7 @@ static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ //----------------------------------------------------------------------------- -static void dump_sib2( SystemInformationBlockType2_t *sib2 ) + void dump_sib2( SystemInformationBlockType2_t *sib2 ) { // ac_BarringInfo if (sib2->ac_BarringInfo) { @@ -3162,7 +3535,7 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 ) LOG_I( RRC, "radioResourceConfigCommon.ul_CyclicPrefixLength : %ld\n", sib2->radioResourceConfigCommon.ul_CyclicPrefixLength ); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 2, 0)) // UplinkPowerControlCommon_v1020 // ... #endif @@ -3194,13 +3567,14 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 ) LOG_I( RRC, "timeAlignmentTimerCommon : %ld\n", sib2->timeAlignmentTimerCommon ); -#if defined(Rel10) || defined(Rel14) - +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (sib2->lateNonCriticalExtension) { LOG_I( RRC, "lateNonCriticalExtension : %p\n", sib2->lateNonCriticalExtension ); } else LOG_I( RRC, "lateNonCriticalExtension : not defined\n" ); +#endif +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (sib2->ext1 && sib2->ext1->ssac_BarringForMMTEL_Voice_r9) { LOG_I( RRC, "ssac_BarringForMMTEL_Voice_r9->ac_BarringFactor : %ld\n", sib2->ext1->ssac_BarringForMMTEL_Voice_r9->ac_BarringFactor ); @@ -3220,7 +3594,9 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 ) BIT_STRING_to_uint32(&sib2->ext1->ssac_BarringForMMTEL_Video_r9->ac_BarringForSpecialAC) ); } else LOG_I( RRC, "ssac_BarringForMMTEL_Video_r9 : not defined\n" ); +#endif +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sib2->ext2 && sib2->ext2->ac_BarringForCSFB_r10) { LOG_I( RRC, "ac_BarringForCSFB_r10->ac_BarringFactor : %ld\n", sib2->ext2->ac_BarringForCSFB_r10->ac_BarringFactor ); @@ -3235,7 +3611,7 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 ) } //----------------------------------------------------------------------------- -static void dump_sib3( SystemInformationBlockType3_t *sib3 ) + void dump_sib3( SystemInformationBlockType3_t *sib3 ) { LOG_I( RRC, "Dumping SIB3 (see TS36.331 V8.21.0)\n" ); @@ -3310,7 +3686,7 @@ int Qoffsettab[31] = {-24,-22,-20,-18,-16,-14,-12,-10,-8,-6,-5,-4,-3,-2,-1,0,1,2 int PhysCellIdRange[16] = {4,8,12,16,24,32,48,64,84,96,128,168,252,504,0,0}; uint64_t arfcn_to_freq(long arfcn) { - + if (arfcn < 600) // Band 1 return((uint64_t)2110000000 + (arfcn*100000)); else if (arfcn <1200) // Band 2 @@ -3384,14 +3760,14 @@ uint64_t arfcn_to_freq(long arfcn) { exit(1); } } -static void dump_sib5( SystemInformationBlockType5_t *sib5 ) + void dump_sib5( SystemInformationBlockType5_t *sib5 ) { InterFreqCarrierFreqList_t interFreqCarrierFreqList = sib5->interFreqCarrierFreqList; int i,j; InterFreqCarrierFreqInfo_t *ifcfInfo; LOG_I( RRC, "Dumping SIB5 (see TS36.331 V8.21.0)\n" ); - + for (i=0;i<interFreqCarrierFreqList.list.count;i++) { LOG_I(RRC, "SIB5 InterFreqCarrierFreq element %d/%d\n",i,interFreqCarrierFreqList.list.count); ifcfInfo = interFreqCarrierFreqList.list.array[i]; @@ -3445,16 +3821,16 @@ static void dump_sib5( SystemInformationBlockType5_t *sib5 ) if (ifcfInfo->q_OffsetFreq) LOG_I(RRC," Q_OffsetFreq : %d\n",Qoffsettab[*ifcfInfo->q_OffsetFreq]); if (ifcfInfo->interFreqNeighCellList) { - + for (j=0;j<ifcfInfo->interFreqNeighCellList->list.count;j++) { LOG_I(RRC," Cell %d\n", j); LOG_I(RRC," PhysCellId : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->physCellId); LOG_I(RRC," Q_OffsetRange : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->q_OffsetCell); - + } } if (ifcfInfo->interFreqBlackCellList) { - + for (j=0;j<ifcfInfo->interFreqBlackCellList->list.count;j++) { LOG_I(RRC," Cell %d\n", j); LOG_I(RRC," PhysCellId start: %ld\n",ifcfInfo->interFreqBlackCellList->list.array[j]->start); @@ -3463,21 +3839,21 @@ static void dump_sib5( SystemInformationBlockType5_t *sib5 ) } } } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (ifcfInfo->ext1 && ifcfInfo->ext1->q_QualMin_r9) LOG_I(RRC," Q_QualMin_r9 : %ld\n",*ifcfInfo->ext1->q_QualMin_r9); - + if (ifcfInfo->ext1 && ifcfInfo->ext1->threshX_Q_r9) { LOG_I(RRC," threshX_HighQ_r9 : %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_HighQ_r9); LOG_I(RRC," threshX_LowQ_r9: %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_LowQ_r9); } #endif } - + } - -#if defined(Rel10) || defined(Rel14) -static void dump_sib13( SystemInformationBlockType13_r9_t *sib13 ) + +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + void dump_sib13( SystemInformationBlockType13_r9_t *sib13 ) { LOG_I( RRC, "[UE] Dumping SIB13\n" ); LOG_I( RRC, "[UE] dumping sib13 second time\n" ); @@ -3485,34 +3861,88 @@ static void dump_sib13( SystemInformationBlockType13_r9_t *sib13 ) LOG_I( RRC, "[UE] NotificationOffset-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationOffset_r9 ); LOG_I( RRC, "[UE] NotificationSF-Index-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationSF_Index_r9 ); } -#endif + +//TTN - SIB18 //----------------------------------------------------------------------------- -static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index ) -{ + void dump_sib18(SystemInformationBlockType18_r12_t *sib18){ + LOG_I( RRC, "[UE] Dumping SIB18\n" ); + for (int i = 0; i < sib18->commConfig_r12->commRxPool_r12.list.count; i++) { + LOG_I(RRC, " Contents of SIB18 %d/%d \n", i+1, sib18->commConfig_r12->commRxPool_r12.list.count); + LOG_I(RRC, " SIB18 rxPool_sc_CP_Len: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_CP_Len_r12); + LOG_I(RRC, " SIB18 sc_Period_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_Period_r12); + LOG_I(RRC, " SIB18 data_CP_Len_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->data_CP_Len_r12); + LOG_I(RRC, " SIB18 prb_Num_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, " SIB18 prb_Start_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, " SIB18 prb_End_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_End_r12); + //to add more log + } +} + +//TTN - SIB19 +//----------------------------------------------------------------------------- + void dump_sib19(SystemInformationBlockType19_r12_t *sib19){ + LOG_I( RRC, "[UE] Dumping SIB19\n" ); + for (int i = 0; i < sib19->discConfig_r12->discRxPool_r12.list.count; i++) { + LOG_I(RRC, " Contents of SIB19 %d/%d \n", i+1, sib19->discConfig_r12->discRxPool_r12.list.count); + LOG_I(RRC, " SIB19 cp_Len_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->cp_Len_r12); + LOG_I(RRC, " SIB19 discPeriod_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->discPeriod_r12); + LOG_I(RRC, " SIB19 numRetx_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRetx_r12); + LOG_I(RRC, " SIB19 numRepetition_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRepetition_r12); + LOG_I(RRC, " SIB19 prb_Num_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, " SIB19 prb_Start_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, " SIB19 prb_End_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_End_r12); + //to add more log + } +} + + void dump_sib21(SystemInformationBlockType21_r14_t *sib21){ + if ((sib21->sl_V2X_ConfigCommon_r14 != NULL) && (sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 !=NULL) ){ + for (int i = 0; i < sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count; i++) { + LOG_I(RRC, " Contents of SIB21 %d/%d \n", i+1, sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count); + LOG_I(RRC, " SIB21 sl_Subframe_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sl_Subframe_r14.present); + LOG_I(RRC, " SIB21 adjacencyPSCCH_PSSCH_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->adjacencyPSCCH_PSSCH_r14); + LOG_I(RRC, " SIB21 sizeSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sizeSubchannel_r14); + LOG_I(RRC, " SIB21 numSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->numSubchannel_r14); + LOG_I(RRC, " SIB21 startRB_Subchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->startRB_Subchannel_r14); + //to add more log + } + } + } + +#endif +//----------------------------------------------------------------------------- + int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index ) +{ + //LOG_D( RRC, "Panos-D: decode_SI 1 \n"); SystemInformation_t** si = &UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; int new_sib = 0; SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + //LOG_D( RRC, "Panos-D: decode_SI 2 \n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN ); // Dump contents - if ((*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_systemInformation_r8) { + if ((*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_systemInformation_r8 || + (*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_criticalExtensionsFuture) { LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n", (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count ); } else { + //LOG_D( RRC, "Panos-D: decode_SI 2.3 \n"); LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel8)\n" ); return -1; } + LOG_D( RRC, "Panos-D: decode_SI 3 \n"); for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { - LOG_D( RRC, "SI count %d\n", i ); + //LOG_I( RRC, "Panos-D: SI count %d\n", i ); struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; typeandinfo = (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; switch(typeandinfo->present) { case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + //LOG_D( RRC, "Panos-D: decode_SI 4 \n"); if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2; new_sib=1; @@ -3525,7 +3955,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->radioResourceConfigCommon, (struct PhysicalConfigDedicated *)NULL, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, #endif (MeasObjectToAddMod_t **)NULL, @@ -3541,7 +3971,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL @@ -3550,18 +3980,24 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in #ifdef CBA ,0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); // After SI is received, prepare RRCConnectionRequest -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option #endif #if !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) rrc_ue_generate_RRCConnectionRequest( ctxt_pP, eNB_index ); - + #endif - + if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_IDLE) { LOG_I( RRC, "[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n", ctxt_pP->module_id ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_SI_RECEIVED; @@ -3569,7 +4005,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in { MessageDef *message_ral_p = NULL; rrc_ral_system_information_ind_t ral_si_ind; - + message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_SYSTEM_INFORMATION_IND); memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t)); ral_si_ind.plmn_id.MCCdigit2 = '0'; @@ -3596,6 +4032,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: + //LOG_D( RRC, "Panos-D: decode_SI 5 \n"); if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4; new_sib=1; @@ -3620,7 +4057,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16; new_sib=1; - + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index], &typeandinfo->choice.sib5, sizeof(SystemInformationBlockType5_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB5 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib5(UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index]); @@ -3631,7 +4068,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32; new_sib=1; - + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index], &typeandinfo->choice.sib6, sizeof(SystemInformationBlockType6_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB6 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } @@ -3659,7 +4096,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&256) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=256; new_sib=1; - + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index], &typeandinfo->choice.sib9, sizeof(SystemInformationBlockType9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB9 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } @@ -3684,7 +4121,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in } break; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 2, 0)) case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2048) == 0) { @@ -3694,12 +4131,12 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB12 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - + case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4096) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4096; new_sib=1; - + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index], &typeandinfo->choice.sib13_v920, sizeof(SystemInformationBlockType13_r9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB13 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib13( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] ); @@ -3729,10 +4166,84 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in #ifdef CBA ,0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); break; } +#endif + +#if defined(Rel10) || defined(Rel14) + //SIB18 + case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8192) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=8192; + new_sib=1; + + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], &typeandinfo->choice.sib18_v1250, sizeof(SystemInformationBlockType18_r12_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB18 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib18( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] ); + // adding here function to store necessary parameters to transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB18 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); + + //process SIB18 to transfer SL-related parameters to PHY + rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, + UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], + (SystemInformationBlockType19_r12_t *)NULL, + (SL_CommConfig_r12_t *)NULL, + (SL_DiscConfig_r12_t *)NULL + ); + + } + break; + + //SIB19 + case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16384) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16384; + new_sib=1; + + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], &typeandinfo->choice.sib19_v1250, sizeof(SystemInformationBlockType19_r12_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB19 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib19( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] ); + // adding here function to store necessary parameters to transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB19 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); + //process SIB19 to transfer SL-related parameters to PHY + rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, + (SystemInformationBlockType18_r12_t *)NULL, + UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], + (SL_CommConfig_r12_t *)NULL, + (SL_DiscConfig_r12_t *)NULL + ); + + } + break; + + //SIB21 + case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32768) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32768; + new_sib=1; + + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index], &typeandinfo->choice.sib21_v1430, sizeof(SystemInformationBlockType21_r14_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB21 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib21( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] ); + // adding here function to store necessary parameters to transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB21 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); + //process SIB21 + //TODO + } + break; + + #endif default: break; @@ -3745,7 +4256,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt == sib1->schedulingInfoList.list.count) rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); - LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", + LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus, UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt, sib1->schedulingInfoList.list.count); @@ -3818,7 +4329,7 @@ void ue_meas_filtering( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ //Below routine implements Measurement Reporting procedure from 36.331 Section 5.5.5 //----------------------------------------------------------------------------- -static void rrc_ue_generate_MeasurementReport(protocol_ctxt_t* const ctxt_pP, uint8_t eNB_index ) + void rrc_ue_generate_MeasurementReport(protocol_ctxt_t* const ctxt_pP, uint8_t eNB_index ) { uint8_t buffer[32], size; @@ -3886,7 +4397,11 @@ static void rrc_ue_generate_MeasurementReport(protocol_ctxt_t* const ctxt_pP, ui size = do_MeasurementReport(ctxt_pP->module_id, buffer,measId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t); LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index); - result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA); + result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,NULL, NULL +#endif + ); AssertFatal (result == TRUE, "PDCP data request failed!\n"); //LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",ue_mod_idP,frameP, size, DCCH); } @@ -4012,7 +4527,7 @@ void ue_measurement_report_triggering(protocol_ctxt_t* const ctxt_pP, const uint //check_trigger_meas_event(ue_mod_idP, frameP, eNB_index, i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms) //----------------------------------------------------------------------------- -static uint8_t check_trigger_meas_event( + uint8_t check_trigger_meas_event( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, @@ -4075,7 +4590,7 @@ static uint8_t check_trigger_meas_event( return 0; } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //----------------------------------------------------------------------------- int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t* const Sdu, const uint8_t Sdu_len, const uint8_t mbsfn_sync_area ) { @@ -4139,7 +4654,7 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB } //----------------------------------------------------------------------------- -static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area ) + void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area ) { protocol_ctxt_t ctxt; @@ -4150,7 +4665,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i rrc_mac_config_req_ue(ue_mod_idP,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -4167,7 +4682,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i NULL, NULL, (MBSFN_SubframeConfigList_t *)NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -4178,9 +4693,15 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i , 0, 0 +#endif +#if defined(Rel14) + , + 0, + NULL, + NULL #endif ); - + UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, UE_rrc_inst[ue_mod_idP].Info[eNB_index].rnti, frameP, 0,eNB_index); @@ -4194,7 +4715,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) #endif ,NULL); @@ -4203,8 +4724,9 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList NULL,// DRB_ToReleaseList -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) &(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) + , 0, 0 #endif ); // */ @@ -4237,6 +4759,7 @@ void *rrc_ue_task( void *args_p ) switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(RRC, " *** Exiting RRC thread\n"); itti_exit_task (); break; @@ -4306,7 +4829,7 @@ void *rrc_ue_task( void *args_p ) RRC_MAC_CCCH_DATA_IND (msg_p).enb_index); break; -# if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case RRC_MAC_MCCH_DATA_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, msg_name, @@ -4321,6 +4844,15 @@ void *rrc_ue_task( void *args_p ) RRC_MAC_MCCH_DATA_IND (msg_p).sdu_size, RRC_MAC_MCCH_DATA_IND (msg_p).mbsfn_sync_area); break; + + /* //TTN (for D2D) + case RRC_MAC_SL_DISCOVERY_DATA_IND: + LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, msg_name, + RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).frame, RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).enb_index); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, M_RNTI, RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).frame, 0,RRC_MAC_SL_DISCOVERY_DATA_IND (msg_p).enb_index); + //send to ProSeApp + break; +*/ # endif /* PDCP messages */ @@ -4500,10 +5032,10 @@ void *rrc_ue_task( void *args_p ) /* Transfer data to PDCP */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0); - // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) + // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) if(UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) { - rrc_data_req (&ctxt, + rrc_data_req_ue (&ctxt, DCCH, rrc_mui++, SDU_CONFIRM_NO, @@ -4512,7 +5044,7 @@ void *rrc_ue_task( void *args_p ) } else { - rrc_data_req (&ctxt, + rrc_data_req_ue (&ctxt, DCCH1, rrc_mui++, SDU_CONFIRM_NO, @@ -4521,7 +5053,7 @@ void *rrc_ue_task( void *args_p ) } break; } - + # endif # if ENABLE_RAL @@ -4729,7 +5261,7 @@ openair_rrc_top_init_ue( UE_rrc_inst[module_id].UECapability_size = UECap->sdu_size; } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[UE] eMBMS active state is %d \n", eMBMS_active); for (module_id=0; module_id<NB_UE_INST; module_id++) { @@ -4737,6 +5269,14 @@ openair_rrc_top_init_ue( } #endif + +#ifdef Rel14 + /* TODO: this is disabled for the moment because the standard UE + * crashes when calling this function. + */ + //init_SL_preconfig(&UE_rrc_inst[module_id],0); +#endif + } else { UE_rrc_inst = NULL; } @@ -4752,6 +5292,1201 @@ rrc_top_cleanup_ue( { if (NB_UE_INST > 0) free (UE_rrc_inst); - + +} + + +//----------------------------------------------------------------------------- +uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index,SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) +{ + uint8_t size=0; + uint8_t buffer[100]; + + //Generate SidelinkUEInformation + if (((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8192) > 0) && (destinationInfoList != NULL)) {//if SIB18 is available + size = do_SidelinkUEInformation(ctxt_pP->module_id, buffer, destinationInfoList, NULL, mode); + LOG_I(RRC,"[UE %d][RRC_UE] Frame %d : Logical Channel UL-DCCH, Generating SidelinkUEInformation (bytes%d, eNB %d)\n", + ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); + //return size; + } + if (((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16384) > 0) && (discTxResourceReq != NULL)) {//if SIB19 is available + size = do_SidelinkUEInformation(ctxt_pP->module_id, buffer, NULL, discTxResourceReq, mode); + LOG_I(RRC,"[UE %d][RRC_UE] Frame %d : Logical Channel UL-DCCH, Generating SidelinkUEInformation (bytes%d, eNB %d)\n", + ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); + //return size; + } + + rrc_data_req_ue ( + ctxt_pP, + DCCH, + rrc_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + return size; +} + + +// 3GPP 36.331 (Section 5.10.7.3) +uint8_t fill_SLSS(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, SLSSID_r12_t *slss_id, uint8_t *subframe, uint8_t mode) +{ + long syncOffsetIndicator = 0; + switch(mode) { + case 1: //if triggered by SL discovery announcement and in-coverage + //discSyncConfig_r12 contains only one element + *slss_id = UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->slssid_r12; + syncOffsetIndicator = UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->syncOffsetIndicator_r12; + //select subframe for SLSS + break; + case 2: //if triggered by SL communication and in-coverage + + if (UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12) { + *slss_id = UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->slssid_r12; + syncOffsetIndicator = UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->syncOffsetIndicator_r12; + + //if RRC_CONNECTED (Todo: and if networkControlledSyncTx (RRCConnectionReconfiguration) is configured and set to On) + if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_CONNECTED){ + //select subframe(s) indicated by syncOffsetIndicator + *subframe = syncOffsetIndicator; + } else { + //select subframe(s) indicated by syncOffsetIndicator within SC period + } + break; + case 3: //if triggered by V2X communication and in coverage + + break; + case 4: //if triggered by V2X communication and out-of-coverage + + break; + case 5: //if triggered by V2X communication and UE has GNSS as the synchronization reference + + default: + //if UE has a selected SyncRefUE + //TODO + //else (no SyncRefUE Selected) + //Todo if trigger by V2X + //else randomly select an SLSSID from the set defined for out-of-coverage + *slss_id = 170;//hardcoded + //select the subframe according to syncOffsetIndicator1/2 from the preconfigured parameters + break; + } + } + return 0; } + + +//----------------------------------------------------------------------------- +void +rrc_ue_process_sidelink_radioResourceConfig( + module_id_t Mod_idP, + uint8_t eNB_index, + SystemInformationBlockType18_r12_t *sib18, + SystemInformationBlockType19_r12_t *sib19, + SL_CommConfig_r12_t* sl_CommConfig, + SL_DiscConfig_r12_t* sl_DiscConfig +) +//----------------------------------------------------------------------------- +{ + //process SIB18, configure MAC/PHY for receiving SL communication (RRC_IDLE and RRC_CONNECTED), for transmitting SL communication (RRC_IDLE) + if (sib18 != NULL) { + if (sib18->commConfig_r12 != NULL) { + //do not consider commTXPoolExceptional for the moment + //configure PHY/MAC to receive SL communication by using the RPs indicated by commRxPool + //sib18->commConfig_r12->commRxPool_r12 + //TODO + + if (sib18->commConfig_r12->commTxPoolNormalCommon_r12 !=NULL) { //commTxPoolNormalCommon - to transmit SL communication in RRC_IDLE + //maybe we don't consider this case for the moment since UE will immediately establish a RRC connection after receiving SIB messages + //configure PHY/MAC to transmit SL communication using the RPs indicated by the first entry in commTxPoolNormalCommon + //SL_CommResourcePool_r12_t sl_CommResourcePool = sib18->commConfig_r12->commTxPoolNormalCommon_r12->list.array[0]; + } + } + } + + //process SIB19, configure MAC/PHY for receiving SL discovery (RRC_IDLE and RRC_CONNECTED), for transmitting SL discovery (RRC_IDLE) + if (sib19 != NULL) { + //to receive non-PS related discovery announcements (discRxPool) + //sib19->discConfig_r12->discRxPool_r12; + + //to receive PS related discovery announcements (discRxPoolPS) + //sib19->ext1->discConfigPS_13->discRxPoolPS_r13; + + //to transmit non-PS related discovery in RRC_IDLE + //sib19->discConfig_r12->discTxPoolCommon_r12; + + //to transmit PS related discovery in RRC_IDLE + //sib19->ext1->discConfigPS_13->discTxPoolPS_Common_r13; + } + + //process sl_CommConfig, configure MAC/PHY for transmitting SL communication (RRC_CONNECTED) + if (sl_CommConfig != NULL) { + + if (sl_CommConfig->commTxResources_r12 != NULL) { + switch (sl_CommConfig->commTxResources_r12->present){ + case SL_CommConfig_r12__commTxResources_r12_PR_setup: + if (sl_CommConfig->commTxResources_r12->choice.setup.present == SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12 ){ + + LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, sl_RNTI size %d \n", + Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size ); + LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, sl_RNTI buf 0x%p \n", + Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf ); + LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, Mac_MainConfig_r12.retx_BSR_TimerSL %ld \n", + Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL ); + LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, sc_CommTxConfig %ld \n", + Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL ); + //configure scheduled resource for SL + //TODO + } else if (sl_CommConfig->commTxResources_r12->choice.setup.present == SL_CommConfig_r12__commTxResources_r12__setup_PR_ue_Selected_r12){ + //configure dedicated resources (commTxPoolNormalDedicated) for SL from which UE can autonomously select + //sl_CommConfig->commTxResources_r12->choice.setup.choice.ue_Selected_r12.commTxPoolNormalDedicated_r12; + + //for the moment, only pass the first entry (e.g., do not consider priorityList in commTxPoolNormalDedicated (3GPP 36.331 Section 5.10.4 1>2>3>4)) + //sl_CommConfig->commTxResources_r12->choice.setup.choice.ue_Selected_r12.commTxPoolNormalDedicated_r12.poolToAddModList_r12->list.array[0]; + } else { + //SL_CommConfig_r12__commTxResources_r12__setup_PR_NOTHING /* No components present */ + } + break; + + case SL_CommConfig_r12__commTxResources_r12_PR_release: + //release dedicated resources for SL communication + break; + + case SL_CommConfig_r12__commTxResources_r12_PR_NOTHING: /* No components present */ + break; + + default: + break; + } + } + + } + + //process sl_DiscConfig, configure MAC/PHY for transmitting SL discovery announcements (RRC_CONNECTED) + if (sl_DiscConfig != NULL) { + //dedicated resources for transmitting non-PS related discovery + if (sl_DiscConfig->discTxResources_r12 != NULL) { + + switch (sl_DiscConfig->discTxResources_r12->present) { + case SL_DiscConfig_r12__discTxResources_r12_PR_setup: + if (sl_DiscConfig->discTxResources_r12->choice.setup.present == SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12) { + //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12; + //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12; + //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; + } else if (sl_DiscConfig->discTxResources_r12->choice.setup.present == SL_DiscConfig_r12__discTxResources_r12__setup_PR_ue_Selected_r12) { + //sl_DiscConfig->discTxResources_r12->choice.setup.choice.ue_Selected_r12.discTxPoolDedicated_r12; + } else { + //SL_DiscConfig_r12__discTxResources_r12__setup_PR_NOTHING, /* No components present */ + } + break; + case SL_DiscConfig_r12__discTxResources_r12_PR_release: + //release dedicated resources for SL discovery + break; + case SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING: /* No components present */ + break; + default: + break; + } + + } + //dedicated resources for transmitting PS related discovery + if (sl_DiscConfig->ext2->discTxResourcesPS_r13 != NULL){ + switch (sl_DiscConfig->ext2->discTxResourcesPS_r13->present) { + case SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_setup: + if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_scheduled_r13) { + //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.scheduled_r13.discHoppingConfig_r13; + //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.scheduled_r13.discTxConfig_r13 + } else if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_ue_Selected_r13) { + //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.ue_Selected_r13.discTxPoolPS_Dedicated_r13; + } else { + //SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_NOTHING, /* No components present */ + } + + break; + case SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_release: + break; + case SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_NOTHING: + /* No components present */ + break; + default: + break; + } + } + } +} + +#ifdef Rel14 +//----------------------------------------------------------- +void +rrc_control_socket_init(){ + + struct sockaddr_in rrc_ctrl_socket_addr; + pthread_attr_t attr; + struct sched_param sched_param; + int optval; // flag value for setsockopt + //int n; // message byte size + + + // create the control socket + ctrl_sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ctrl_sock_fd == -1) { + LOG_E(RRC,"[rrc_control_socket_init] :Error opening socket %d (%d:%s)\n",ctrl_sock_fd,errno, strerror(errno)); + exit(EXIT_FAILURE); + } + // if (ctrl_sock_fd < 0) + // error("ERROR: Failed on opening socket"); + optval = 1; + setsockopt(ctrl_sock_fd, SOL_SOCKET, SO_REUSEADDR, + (const void *)&optval , sizeof(int)); + + //build the server's address + bzero((char *) &rrc_ctrl_socket_addr, sizeof(rrc_ctrl_socket_addr)); + rrc_ctrl_socket_addr.sin_family = AF_INET; + rrc_ctrl_socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); + rrc_ctrl_socket_addr.sin_port = htons(CONTROL_SOCKET_PORT_NO); + // associate the parent socket with a port + if (bind(ctrl_sock_fd, (struct sockaddr *) &rrc_ctrl_socket_addr, + sizeof(rrc_ctrl_socket_addr)) < 0) { + LOG_E(RRC,"[rrc_control_socket_init] ERROR: Failed on binding the socket\n"); + exit(1); + } + //create thread to listen to incoming packets + if (pthread_attr_init(&attr) != 0) { + LOG_E(RRC, "[rrc_control_socket_init]Failed to initialize pthread attribute for ProSe -> RRC communication (%d:%s)\n", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + sched_param.sched_priority = 10; + + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setschedparam(&attr, &sched_param); + + pthread_t rrc_control_socket_thread; + + if (pthread_create(&rrc_control_socket_thread, &attr, rrc_control_socket_thread_fct, NULL) != 0) { + LOG_E(RRC, "[rrc_control_socket_init]Failed to create new thread for RRC/ProSeApp communication (%d:%s)\n", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + pthread_setname_np( rrc_control_socket_thread, "RRC Control Socket" ); + +} + +//-------------------------------------------------------- +void *rrc_control_socket_thread_fct(void *arg) +{ + + int prose_addr_len; + char send_buf[BUFSIZE]; + char receive_buf[BUFSIZE]; + //int optval; + int n; + struct sidelink_ctrl_element *sl_ctrl_msg_recv = NULL; + struct sidelink_ctrl_element *sl_ctrl_msg_send = NULL; + uint32_t sourceL2Id, groupL2Id, destinationL2Id; + module_id_t module_id = 0; //hardcoded for testing only + uint8_t type; + UE_RRC_INST *UE = NULL; + protocol_ctxt_t ctxt; + struct RLC_Config *DRB_rlc_config = NULL; + struct PDCP_Config *DRB_pdcp_config = NULL; + struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LogicalChannelConfig *DRB_lchan_config = NULL; + struct LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; + long *logicalchannelgroup_drb = NULL; + int j = 0; + int i = 0; + + //from the main program, listen for the incoming messages from control socket (ProSe App) + prose_addr_len = sizeof(prose_app_addr); + //int enable_notification = 1; + while (1) { + LOG_I(RRC,"Listening to incoming connection from ProSe App \n"); + // receive a message from ProSe App + memset(receive_buf, 0, BUFSIZE); + n = recvfrom(ctrl_sock_fd, receive_buf, BUFSIZE, 0, + (struct sockaddr *) &prose_app_addr, (socklen_t *)&prose_addr_len); + if (n < 0){ + LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n"); + exit(EXIT_FAILURE); + } + //TODO: should store the address of ProSeApp [UE_rrc_inst] to be able to send UE state notification to the App + + //sl_ctrl_msg_recv = (struct sidelink_ctrl_element *) receive_buf; + sl_ctrl_msg_recv = calloc(1, sizeof(struct sidelink_ctrl_element)); + memcpy((void *)sl_ctrl_msg_recv, (void *)receive_buf, sizeof(struct sidelink_ctrl_element)); + + //process the message + switch (sl_ctrl_msg_recv->type) { + case SESSION_INIT_REQ: +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"Received SessionInitializationRequest on socket from ProSe App (msg type: %d)\n", sl_ctrl_msg_recv->type); +#endif + //TODO: get SL_UE_STATE from lower layer + + LOG_I(RRC,"Send UEStateInformation to ProSe App \n"); + memset(send_buf, 0, BUFSIZE); + + sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); + sl_ctrl_msg_send->type = UE_STATUS_INFO; + sl_ctrl_msg_send->sidelinkPrimitive.ue_state = UE_STATE_OFF_NETWORK; //off-network + memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); + free(sl_ctrl_msg_send); + + prose_addr_len = sizeof(prose_app_addr); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + if (n < 0) { + LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } + + +#ifdef DEBUG_CTRL_SOCKET + struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; + ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; + LOG_I(RRC,"[UEStateInformation] msg type: %d\n",ptr_ctrl_msg->type); + LOG_I(RRC,"[UEStateInformation] UE state: %d\n",ptr_ctrl_msg->sidelinkPrimitive.ue_state); +#endif + + /* if (enable_notification > 0) { + //create thread to send status notification (for testing purpose, status notification will be sent e.g., every 20 seconds) + pthread_t notification_thread; + if( pthread_create( ¬ification_thread , NULL , send_UE_status_notification , (void*) &sockfd) < 0) + error("ERROR: could not create thread"); + } + enable_notification = 0; + */ + break; + + case GROUP_COMMUNICATION_ESTABLISH_REQ: + sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id; + groupL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id; + +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[GroupCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[GroupCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); + LOG_I(RRC,"[GroupCommunicationEstablishReq] group Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); + LOG_I(RRC,"[GroupCommunicationEstablishReq] group IP Address: " IPV4_ADDR "\n",IPV4_ADDR_FORMAT(sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupIpAddress)); +#endif + + //store sourceL2Id/groupL2Id + UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; + UE_rrc_inst[module_id].groupL2Id = groupL2Id; + j = 0; + i = 0; + for (i=0; i< MAX_NUM_DEST; i++) { + if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; + if (UE_rrc_inst[module_id].destinationList[i] == groupL2Id) break; //group already exists! + } + if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = groupL2Id; + + // configure lower layers PDCP/MAC/PHY for this communication + //Establish a new RBID/LCID for this communication + // Establish a SLRB (using DRB 3 for now) + UE = &UE_rrc_inst[module_id]; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + UE->DRB_config[0][0]->drb_Identity = 3; + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3; + UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + /* avoid gcc warnings */ + (void)PDCP_rlc_UM; + + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); + + rrc_pdcp_config_asn1_req(&ctxt, + (SRB_ToAddModList_t *) NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*) NULL, + 0xff, NULL, NULL, NULL +#if defined(Rel10) || defined(Rel14) + , (PMCH_InfoList_r9_t *) NULL +#endif + ,NULL); + + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#if defined(Rel10) || defined(Rel14) + ,(PMCH_InfoList_r9_t *)NULL + , 0, 0 +#endif + ); + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#ifdef Rel14 + ,(PMCH_InfoList_r9_t *)NULL + , sourceL2Id, groupL2Id +#endif + ); + + + //configure MAC with sourceL2Id/groupL2ID + rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, +#if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 3, //LCID + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL + +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_ADD, + &sourceL2Id, + &groupL2Id +#endif + ); + + LOG_I(RRC,"Send GroupCommunicationEstablishResp to ProSe App\n"); + memset(send_buf, 0, BUFSIZE); + sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); + sl_ctrl_msg_send->type = GROUP_COMMUNICATION_ESTABLISH_RSP; + sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id + + memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); + free(sl_ctrl_msg_send); + + prose_addr_len = sizeof(prose_app_addr); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + if (n < 0){ + LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } + + +#ifdef DEBUG_CTRL_SOCKET + ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; + LOG_I(RRC,"[GroupCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); + LOG_I(RRC,"[GroupCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); +#endif + break; + + case GROUP_COMMUNICATION_RELEASE_REQ: + printf("-----------------------------------\n"); +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[GroupCommunicationReleaseRequest] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[GroupCommunicationReleaseRequest] Slrb Id: %i\n",sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id); +#endif + //reset groupL2ID from MAC LAYER + UE_rrc_inst[module_id].groupL2Id = 0x00000000; + sourceL2Id = UE_rrc_inst[module_id].sourceL2Id; + + rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, + #if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, + #endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 0, + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + #if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL + + #endif + #ifdef CBA + , + 0, + 0 + #endif + #if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_REMOVE, + &sourceL2Id, + &destinationL2Id + #endif + ); + + + LOG_I(RRC,"Send GroupCommunicationReleaseResponse to ProSe App \n"); + memset(send_buf, 0, BUFSIZE); + + sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); + sl_ctrl_msg_send->type = GROUP_COMMUNICATION_RELEASE_RSP; + //if the requested id exists -> release this ID + if (sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id == slrb_id) { + sl_ctrl_msg_send->sidelinkPrimitive.group_comm_release_rsp = GROUP_COMMUNICATION_RELEASE_OK; + slrb_id = 0; //Reset slrb_id + } else { + sl_ctrl_msg_send->sidelinkPrimitive.group_comm_release_rsp = GROUP_COMMUNICATION_RELEASE_FAILURE; + } + memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); + free(sl_ctrl_msg_send); + + prose_addr_len = sizeof(prose_app_addr); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + if (n < 0){ + LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } + break; + + + case DIRECT_COMMUNICATION_ESTABLISH_REQ: + sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.sourceL2Id; + destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.destinationL2Id; + +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[DirectCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[DirectCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); + LOG_I(RRC,"[DirectCommunicationEstablishReq] destination Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); +#endif + + //store sourceL2Id/destinationL2Id + UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; + i = 0; + j = 0; + for (i=0; i< MAX_NUM_DEST; i++) { + if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; + if (UE_rrc_inst[module_id].destinationList[i] == destinationL2Id) break; //destination already exists! + } + if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = destinationL2Id; + + // configure lower layers PDCP/MAC/PHY for this communication + //Establish a new RBID/LCID for this communication + // Establish a SLRB (using DRB 3 for now) + UE = &UE_rrc_inst[module_id]; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + UE->DRB_config[0][0]->drb_Identity = 3; + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3; + UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + /* avoid gcc warnings */ + (void)PDCP_rlc_UM; + + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); + + rrc_pdcp_config_asn1_req(&ctxt, + (SRB_ToAddModList_t *) NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*) NULL, + 0xff, NULL, NULL, NULL +#if defined(Rel10) || defined(Rel14) + , (PMCH_InfoList_r9_t *) NULL +#endif + ,NULL); + + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#if defined(Rel10) || defined(Rel14) + ,(PMCH_InfoList_r9_t *)NULL + , 0, 0 +#endif + ); + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#ifdef Rel14 + ,(PMCH_InfoList_r9_t *)NULL + , sourceL2Id, destinationL2Id +#endif + ); + + + //configure MAC with sourceL2Id/destinationL2Id + rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, +#if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 3, //LCID + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL + +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_ADD, + &sourceL2Id, + &destinationL2Id +#endif + ); + + LOG_I(RRC,"Send DirectCommunicationEstablishResp to ProSe App\n"); + memset(send_buf, 0, BUFSIZE); + sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); + sl_ctrl_msg_send->type = DIRECT_COMMUNICATION_ESTABLISH_RSP; + sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id + + memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); + free(sl_ctrl_msg_send); + + prose_addr_len = sizeof(prose_app_addr); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + if (n < 0){ + LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } + + +#ifdef DEBUG_CTRL_SOCKET + ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; + LOG_I(RRC,"[DirectCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); + LOG_I(RRC,"[DirectCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); +#endif + break; + + case PC5S_ESTABLISH_REQ: + type = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type; + sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id; +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[PC5EstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[PC5EstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type); //RX/TX + LOG_I(RRC,"[PC5EstablishReq] source Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id); +#endif + if (type > 0) { + destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id; +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[PC5EstablishReq] destination Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id); +#endif + } + + //store sourceL2Id/destinationL2Id + if (type > 0) { //TX + UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; + j = 0; + i = 0; + for (i=0; i< MAX_NUM_DEST; i++) { + if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; + if (UE_rrc_inst[module_id].destinationList[i] == destinationL2Id) break; //group already exists! + } + if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = destinationL2Id; + } else {//RX + UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; + } + + // configure lower layers PDCP/MAC/PHY for this communication + //Establish a new RBID/LCID for this communication + // Establish a SLRB (using DRB 10 for now) + UE = &UE_rrc_inst[module_id]; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + UE->DRB_config[0][0]->drb_Identity = 10; + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(UE->DRB_config[0][0]->eps_BearerIdentity) = 10; + UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + /* avoid gcc warnings */ + (void)PDCP_rlc_UM; + + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); + + rrc_pdcp_config_asn1_req(&ctxt, + (SRB_ToAddModList_t *) NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*) NULL, + 0xff, NULL, NULL, NULL +#if defined(Rel10) || defined(Rel14) + , (PMCH_InfoList_r9_t *) NULL +#endif + ,NULL); + + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#if defined(Rel10) || defined(Rel14) + ,(PMCH_InfoList_r9_t *)NULL + , 0, 0 +#endif + ); + + //TX + if (type > 0) { + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#ifdef Rel14 + ,(PMCH_InfoList_r9_t *)NULL + , sourceL2Id, destinationL2Id +#endif + ); + + //configure MAC with sourceL2Id/groupL2ID + rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, +#if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 10, //LCID + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL + +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_ADD, + &sourceL2Id, + &destinationL2Id +#endif + ); + } else {//RX + //configure MAC with sourceL2Id/groupL2ID + rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, +#if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 10, //LCID + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL + +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_ADD, + &sourceL2Id, + NULL +#endif + ); + + } + + LOG_I(RRC,"Send PC5EstablishRsp to ProSe App\n"); + memset(send_buf, 0, BUFSIZE); + sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); + sl_ctrl_msg_send->type = PC5S_ESTABLISH_RSP; + sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid28 = 10; + sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid29 = 10; + sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid30 = 10; + memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); + + prose_addr_len = sizeof(prose_app_addr); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); +// free(sl_ctrl_msg_send); + if (n < 0){ + LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } + break; + + + case PC5_DISCOVERY_MESSAGE: + + #ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[PC5DiscoveryMessage] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + #endif + //prepare SL_Discovery buffer + if (UE_rrc_inst) { + memcpy((void*)&UE_rrc_inst[module_id].SL_Discovery[0].Tx_buffer.Payload[0], (void*)&sl_ctrl_msg_recv->sidelinkPrimitive.pc5_discovery_message.payload[0], PC5_DISCOVERY_PAYLOAD_SIZE); + UE_rrc_inst[module_id].SL_Discovery[0].Tx_buffer.payload_size = PC5_DISCOVERY_PAYLOAD_SIZE; + LOG_I(RRC,"[PC5DiscoveryMessage] Copied %d bytes\n",PC5_DISCOVERY_PAYLOAD_SIZE); + } + break; + default: + break; + } + } + free (sl_ctrl_msg_recv); + return 0; +} + + +//----------------------------------------------------------------------------- +int decode_SL_Discovery_Message( + const protocol_ctxt_t* const ctxt_pP, + const uint8_t eNB_index, + const uint8_t* Sdu, + const uint8_t Sdu_len) +{ + + int prose_addr_len; + char send_buf[BUFSIZE]; + int n; + struct sidelink_ctrl_element *sl_ctrl_msg_send = NULL; + + //from the main program, listen for the incoming messages from control socket (ProSe App) + prose_addr_len = sizeof(prose_app_addr); + + //Store in Rx_buffer + memcpy((void*)&UE_rrc_inst[ctxt_pP->module_id].SL_Discovery[0].Rx_buffer.Payload[0], (void*)Sdu, Sdu_len); + UE_rrc_inst[ctxt_pP->module_id].SL_Discovery[0].Rx_buffer.payload_size = Sdu_len; + + memset(send_buf, 0, BUFSIZE); + //send to ProSeApp + memcpy((void *)send_buf, (void*)Sdu, Sdu_len); + prose_addr_len = sizeof(prose_app_addr); + + sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); + sl_ctrl_msg_send->type = PC5_DISCOVERY_MESSAGE; + // TODO: Add a check for the SDU size. + memcpy((void*)&sl_ctrl_msg_send->sidelinkPrimitive.pc5_discovery_message.payload[0], (void*) Sdu, PC5_DISCOVERY_PAYLOAD_SIZE); + + memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); + free(sl_ctrl_msg_send); + + prose_addr_len = sizeof(prose_app_addr); + + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + if (n < 0){ + // TODO: We should not just exit if the Prose App has not yet attached. It creates a race condition. + LOG_I(RRC, "ERROR: Failed to send to ProSe App\n"); + //exit(EXIT_FAILURE); + } + + + + return(0); +} + +#endif + +//----------------------------------------------------------------------------- +RRC_status_t +rrc_rx_tx_ue( + protocol_ctxt_t* const ctxt_pP, + const uint8_t enb_indexP, + const int CC_id +) +//----------------------------------------------------------------------------- +{ + +#ifdef LOCALIZATION + double estimated_distance; + protocol_ctxt_t ctxt; +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_IN); + + // check timers + + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_active == 1) { + if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt % 10) == 0) + LOG_D(RRC, + "[UE %d][RAPROC] Frame %d T300 Count %d ms\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt); + + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt + == T300[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.t300]) { + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_active = 0; + // ALLOW CCCH to be used + UE_rrc_inst[ctxt_pP->module_id].Srb0[enb_indexP].Tx_buffer.payload_size = 0; + rrc_ue_generate_RRCConnectionRequest (ctxt_pP, enb_indexP); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); + return (RRC_ConnSetup_failed); + } + + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T300_cnt++; + } + + if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].SIStatus&2)>0) { + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt + == N310[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.n310]) { + LOG_I(RRC,"Activating T310\n"); + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 1; + } + } else { // in case we have not received SIB2 yet + /* if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt == 100) { + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N310_cnt = 0; + + }*/ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); + return RRC_OK; + } + + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active == 1) { + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N311_cnt + == N311[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.n311]) { + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0; + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].N311_cnt = 0; + } + + if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt % 10) == 0) { + LOG_D(RRC, "[UE %d] Frame %d T310 Count %d ms\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt); + } + + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt == T310[UE_rrc_inst[ctxt_pP->module_id].sib2[enb_indexP]->ue_TimersAndConstants.t310]) { + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0; + rrc_t310_expiration (ctxt_pP, enb_indexP); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); + LOG_I(RRC,"Returning RRC_PHY_RESYNCH: T310 expired\n"); + return RRC_PHY_RESYNCH; + } + + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_cnt++; + } + + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_active==1) { + if ((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt % 10) == 0) + LOG_D(RRC,"[UE %d][RAPROC] Frame %d T304 Count %d ms\n",ctxt_pP->module_id,ctxt_pP->frame, + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt); + + if (UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_active = 0; + UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1; + LOG_E(RRC,"[UE %d] Handover failure..initiating connection re-establishment procedure... \n", + ctxt_pP->module_id); + //Implement 36.331, section 5.3.5.6 here + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); + return(RRC_Handover_failed); + } + + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T304_cnt--; + } + + // Layer 3 filtering of RRC measurements + if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[0] != NULL) { + ue_meas_filtering(ctxt_pP,enb_indexP); + } + + ue_measurement_report_triggering(ctxt_pP,enb_indexP); + + if (UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget > 0) { + LOG_I(RRC,"[UE %d] Frame %d : RRC handover initiated\n", ctxt_pP->module_id, ctxt_pP->frame); + } + + if((UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].State == RRC_HO_EXECUTION) && + (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId != 0xFF)) { + UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].State= RRC_IDLE; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); + return(RRC_HO_STARTED); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); + return (RRC_OK); +} + diff --git a/openair2/RRC/LITE/rrc_UE_ral.c b/openair2/RRC/LTE/rrc_UE_ral.c similarity index 100% rename from openair2/RRC/LITE/rrc_UE_ral.c rename to openair2/RRC/LTE/rrc_UE_ral.c diff --git a/openair2/RRC/LITE/rrc_UE_ral.h b/openair2/RRC/LTE/rrc_UE_ral.h similarity index 100% rename from openair2/RRC/LITE/rrc_UE_ral.h rename to openair2/RRC/LTE/rrc_UE_ral.h diff --git a/openair2/RRC/LTE/rrc_common.c b/openair2/RRC/LTE/rrc_common.c new file mode 100644 index 0000000000000000000000000000000000000000..0acb0d77010a41c8753b3fae87cafa014bf34be2 --- /dev/null +++ b/openair2/RRC/LTE/rrc_common.c @@ -0,0 +1,295 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 rrc_common.c + * \brief rrc common procedures for eNB and UE + * \author Navid Nikaein and Raymond Knopp + * \date 2011 - 2014 + * \version 1.0 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr + */ + +#include "rrc_defs.h" +#include "rrc_extern.h" +#include "LAYER2/MAC/mac_extern.h" +#include "COMMON/openair_defs.h" +#include "COMMON/platform_types.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "LAYER2/RLC/rlc.h" +#include "COMMON/mac_rrc_primitives.h" +#include "UTIL/LOG/log.h" +#include "asn1_msg.h" +#include "pdcp.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "rrc_eNB_UE_context.h" +#include "common/ran_context.h" + +#define DEBUG_RRC 1 +extern RAN_CONTEXT_t RC; +extern UE_MAC_INST *UE_mac_inst; + +extern mui_t rrc_eNB_mui; + +//----------------------------------------------------------------------------- +int +rrc_init_global_param( + void +) +//----------------------------------------------------------------------------- +{ + + rrc_rlc_register_rrc (rrc_data_ind, NULL); //register with rlc + + DCCH_LCHAN_DESC.transport_block_size = 4; + DCCH_LCHAN_DESC.max_transport_blocks = 16; + DCCH_LCHAN_DESC.Delay_class = 1; + DTCH_DL_LCHAN_DESC.transport_block_size = 52; + DTCH_DL_LCHAN_DESC.max_transport_blocks = 20; + DTCH_DL_LCHAN_DESC.Delay_class = 1; + DTCH_UL_LCHAN_DESC.transport_block_size = 52; + DTCH_UL_LCHAN_DESC.max_transport_blocks = 20; + DTCH_UL_LCHAN_DESC.Delay_class = 1; + + Rlc_info_um.rlc_mode = RLC_MODE_UM; + Rlc_info_um.rlc.rlc_um_info.timer_reordering = 5; + Rlc_info_um.rlc.rlc_um_info.sn_field_length = 10; + Rlc_info_um.rlc.rlc_um_info.is_mXch = 0; + //Rlc_info_um.rlc.rlc_um_info.sdu_discard_mode=16; + + Rlc_info_am_config.rlc_mode = RLC_MODE_AM; + Rlc_info_am_config.rlc.rlc_am_info.max_retx_threshold = 50; + Rlc_info_am_config.rlc.rlc_am_info.poll_pdu = 8; + Rlc_info_am_config.rlc.rlc_am_info.poll_byte = 1000; + Rlc_info_am_config.rlc.rlc_am_info.t_poll_retransmit = 15; + Rlc_info_am_config.rlc.rlc_am_info.t_reordering = 50; + Rlc_info_am_config.rlc.rlc_am_info.t_status_prohibit = 10; + + return 0; +} + +//----------------------------------------------------------------------------- +void +rrc_config_buffer( + SRB_INFO* Srb_info, + uint8_t Lchan_type, + uint8_t Role +) +//----------------------------------------------------------------------------- +{ + + Srb_info->Rx_buffer.payload_size = 0; + Srb_info->Tx_buffer.payload_size = 0; +} + + +//----------------------------------------------------------------------------- +long +binary_search_int( + int elements[], + long numElem, + int value +) +//----------------------------------------------------------------------------- +{ + long first, last, middle, search = -1; + first = 0; + last = numElem-1; + middle = (first+last)/2; + + if(value < elements[0]) { + return first; + } + + if(value > elements[last]) { + return last; + } + + while (first <= last) { + if (elements[middle] < value) { + first = middle+1; + } else if (elements[middle] == value) { + search = middle+1; + break; + } else { + last = middle -1; + } + + middle = (first+last)/2; + } + + if (first > last) { + LOG_E(RRC,"Error in binary search!"); + } + + return search; +} + +/* This is a binary search routine which operates on an array of floating + point numbers and returns the index of the range the value lies in + Used for RSRP and RSRQ measurement mapping. Can potentially be used for other things +*/ +//----------------------------------------------------------------------------- +long +binary_search_float( + float elements[], + long numElem, + float value +) +//----------------------------------------------------------------------------- +{ + long first, last, middle; + first = 0; + last = numElem-1; + middle = (first+last)/2; + + if(value <= elements[0]) { + return first; + } + + if(value >= elements[last]) { + return last; + } + + while (last - first > 1) { + if (elements[middle] > value) { + last = middle; + } else { + first = middle; + } + + middle = (first+last)/2; + } + + if (first < 0 || first >= numElem) { + LOG_E(RRC,"\n Error in binary search float!"); + } + + return first; +} + +typedef enum { BAND_TYPE_FDD, BAND_TYPE_TDD } band_type; + +typedef struct { + band_type t; + int band; + unsigned long ul_minfreq, ul_maxfreq; + unsigned long dl_minfreq, dl_maxfreq; +} band_freq; + +static band_freq bands[] = { + { BAND_TYPE_FDD, 1, 1920000000UL, 1980000000UL, 2110000000UL, 2170000000UL }, + { BAND_TYPE_FDD, 2, 1850000000UL, 1910000000UL, 1930000000UL, 1990000000UL }, + { BAND_TYPE_FDD, 3, 1710000000UL, 1785000000UL, 1805000000UL, 1880000000UL }, + { BAND_TYPE_FDD, 4, 1710000000UL, 1755000000UL, 2110000000UL, 2155000000UL }, + { BAND_TYPE_FDD, 5, 824000000UL, 849000000UL, 869000000UL, 894000000UL }, + /* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL }, + { BAND_TYPE_FDD, 7, 2500000000UL, 2570000000UL, 2620000000UL, 2690000000UL }, + { BAND_TYPE_FDD, 8, 880000000UL, 915000000UL, 925000000UL, 960000000UL }, + { BAND_TYPE_FDD, 9, 1749900000UL, 1784900000UL, 1844900000UL, 1879900000UL }, + { BAND_TYPE_FDD, 10, 1710000000UL, 1770000000UL, 2110000000UL, 2170000000UL }, + { BAND_TYPE_FDD, 11, 1427900000UL, 1447900000UL, 1475900000UL, 1495900000UL }, + { BAND_TYPE_FDD, 12, 699000000UL, 716000000UL, 729000000UL, 746000000UL }, + { BAND_TYPE_FDD, 13, 777000000UL, 787000000UL, 746000000UL, 756000000UL }, + { BAND_TYPE_FDD, 14, 788000000UL, 798000000UL, 758000000UL, 768000000UL }, + { BAND_TYPE_FDD, 17, 704000000UL, 716000000UL, 734000000UL, 746000000UL }, + { BAND_TYPE_FDD, 18, 815000000UL, 830000000UL, 860000000UL, 875000000UL }, + { BAND_TYPE_FDD, 19, 830000000UL, 845000000UL, 875000000UL, 890000000UL }, + { BAND_TYPE_FDD, 20, 832000000UL, 862000000UL, 791000000UL, 821000000UL }, + { BAND_TYPE_FDD, 21, 1447900000UL, 1462900000UL, 1495900000UL, 1510900000UL }, + { BAND_TYPE_FDD, 22, 3410000000UL, 3490000000UL, 3510000000UL, 3590000000UL }, + { BAND_TYPE_FDD, 23, 2000000000UL, 2020000000UL, 2180000000UL, 2200000000UL }, + { BAND_TYPE_FDD, 24, 1626500000UL, 1660500000UL, 1525000000UL, 1559000000UL }, + { BAND_TYPE_FDD, 25, 1850000000UL, 1915000000UL, 1930000000UL, 1995000000UL }, + + { BAND_TYPE_TDD, 33, 1900000000UL, 1920000000UL, 1900000000UL, 1920000000UL }, + { BAND_TYPE_TDD, 34, 2010000000UL, 2025000000UL, 2010000000UL, 2025000000UL }, + { BAND_TYPE_TDD, 35, 1850000000UL, 1910000000UL, 1850000000UL, 1910000000UL }, + { BAND_TYPE_TDD, 36, 1930000000UL, 1990000000UL, 1930000000UL, 1990000000UL }, + { BAND_TYPE_TDD, 37, 1910000000UL, 1930000000UL, 1910000000UL, 1930000000UL }, + { BAND_TYPE_TDD, 38, 2570000000UL, 2620000000UL, 2570000000UL, 2620000000UL }, + { BAND_TYPE_TDD, 39, 1880000000UL, 1920000000UL, 1880000000UL, 1920000000UL }, + { BAND_TYPE_TDD, 40, 2300000000UL, 2400000000UL, 2300000000UL, 2400000000UL }, + { BAND_TYPE_TDD, 41, 2496000000UL, 2690000000UL, 2496000000UL, 2690000000UL }, + { BAND_TYPE_TDD, 42, 3400000000UL, 3600000000UL, 3400000000UL, 3600000000UL }, + { BAND_TYPE_TDD, 43, 3600000000UL, 3800000000UL, 3600000000UL, 3800000000UL }, +}; + +typedef struct { + int band; + unsigned long dl_flow; + int dl_off; + int dl_offmin, dl_offmax; + unsigned long ul_flow; + int ul_off; + int ul_offmin, ul_offmax; +} earfcn; + +static earfcn earfcn_table[] = { + { 1, 2110000000UL, 0, 0, 599, 1920000000UL, 18000, 18000, 18599 }, + { 2, 1930000000UL, 600, 600, 1199, 1850000000UL, 18600, 18600, 19199 }, + { 3, 1805000000UL, 1200, 1200, 1949, 1710000000UL, 19200, 19200, 19949 }, + { 4, 2110000000UL, 1950, 1950, 2399, 1710000000UL, 19950, 19950, 20399 }, + { 5, 869000000UL, 2400, 2400, 2649, 824000000UL, 20400, 20400, 20649 }, + { 6, 875000000UL, 2650, 2650, 2749, 830000000UL, 20650, 20650, 20749 }, + { 7, 2620000000UL, 2750, 2750, 3449, 2500000000UL, 20750, 20750, 21449 }, + { 8, 925000000UL, 3450, 3450, 3799, 880000000UL, 21450, 21450, 21799 }, + { 9, 1844900000UL, 3800, 3800, 4149, 1749900000UL, 21800, 21800, 22149 }, + { 10, 2110000000UL, 4150, 4150, 4749, 1710000000UL, 22150, 22150, 22749 }, + { 11, 1475900000UL, 4750, 4750, 4949, 1427900000UL, 22750, 22750, 22949 }, + { 12, 729000000UL, 5010, 5010, 5179, 699000000UL, 23010, 23010, 23179 }, + { 13, 746000000UL, 5180, 5180, 5279, 777000000UL, 23180, 23180, 23279 }, + { 14, 758000000UL, 5280, 5280, 5379, 788000000UL, 23280, 23280, 23379 }, + { 17, 734000000UL, 5730, 5730, 5849, 704000000UL, 23730, 23730, 23849 }, + { 18, 860000000UL, 5850, 5850, 5999, 815000000UL, 23850, 23850, 23999 }, + { 19, 875000000UL, 6000, 6000, 6149, 830000000UL, 24000, 24000, 24149 }, + { 20, 791000000UL, 6150, 6150, 6449, 832000000UL, 24150, 24150, 24449 }, + { 21, 1495900000UL, 6450, 6450, 6599, 1447900000UL, 24450, 24450, 24599 }, + { 22, 3510000000UL, 6600, 6600, 7399, 3410000000UL, 24600, 24600, 25399 }, + { 23, 2180000000UL, 7500, 7500, 7699, 2000000000UL, 25500, 25500, 25699 }, + { 24, 1525000000UL, 7700, 7700, 8039, 1626500000UL, 25700, 25700, 26039 }, + { 25, 1930000000UL, 8040, 8040, 8689, 1850000000UL, 26040, 26040, 26689 }, + { 33, 1900000000UL, 36000, 36000, 36199, 1900000000UL, 36000, 36000, 36199 }, + { 34, 2010000000UL, 36200, 36200, 36349, 2010000000UL, 36200, 36200, 36349 }, + { 35, 1850000000UL, 36350, 36350, 36949, 1850000000UL, 36350, 36350, 36949 }, + { 36, 1930000000UL, 36950, 36950, 37549, 1930000000UL, 36950, 36950, 37549 }, + { 37, 1910000000UL, 37550, 37550, 37749, 1910000000UL, 37550, 37550, 37749 }, + { 38, 2570000000UL, 37750, 37750, 38249, 2570000000UL, 37750, 37750, 38249 }, + { 39, 1880000000UL, 38250, 38250, 38649, 1880000000UL, 38250, 38250, 38649 }, + { 40, 2300000000UL, 38650, 38650, 39649, 2300000000UL, 38650, 38650, 39649 }, + { 41, 2496000000UL, 39650, 39650, 41589, 2496000000UL, 39650, 39650, 41589 }, + { 42, 3400000000UL, 41590, 41590, 43589, 3400000000UL, 41590, 41590, 43589 }, + { 43, 3600000000UL, 43590, 43590, 45589, 3600000000UL, 43590, 43590, 45589 }, +}; + +int freq_to_arfcn10(int band, unsigned long freq) +{ + int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]); + int i; + + for (i = 0; i < N; i++) if (bands[i].band == band) break; + if (i == N) return -1; + + if (!(bands[i].dl_minfreq < freq && freq < bands[i].dl_maxfreq)) + return -1; + + return (freq - earfcn_table[i].dl_flow) / 100000UL + earfcn_table[i].dl_off; +} diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LTE/rrc_defs.h similarity index 82% rename from openair2/RRC/LITE/defs.h rename to openair2/RRC/LTE/rrc_defs.h index bda2655a4cb5c7a0ba13ce581c483ec2ee44d762..956c6ed76504bf2412cd76a052fca2a470a732a2 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file RRC/LITE/defs.h +/*! \file RRC/LTE/defs.h * \brief RRC struct definitions and function prototypes * \author Navid Nikaein and Raymond Knopp * \date 2010 - 2014 @@ -37,13 +37,138 @@ #include "collection/tree.h" #include "rrc_types.h" -#include "PHY/defs.h" +//#include "PHY/phy_defs.h" #include "LAYER2/RLC/rlc.h" #include "COMMON/platform_constants.h" #include "COMMON/platform_types.h" -#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/mac.h" + +//for D2D +#define DEBUG_CTRL_SOCKET +#define BUFSIZE 1024 +#define CONTROL_SOCKET_PORT_NO 8888 +#define MAX_NUM_DEST 10 +//netlink +//#define DEBUG_PDCP +#define UE_IP_PDCP_NETLINK_ID 31 +#define PDCP_PID 1 +#define NETLINK_HEADER_SIZE 16 +#define SL_DEFAULT_RAB_ID 3 +#define SLRB_ID 3 + +#define MAX_PAYLOAD 1024 /* maximum payload size*/ + +#define UE_STATE_NOTIFICATION_INTERVAL 50 + +#define IPV4_ADDR "%u.%u.%u.%u" +#define IPV4_ADDR_FORMAT(aDDRESS) \ + (uint8_t)((aDDRESS) & 0x000000ff), \ + (uint8_t)(((aDDRESS) & 0x0000ff00) >> 8 ), \ + (uint8_t)(((aDDRESS) & 0x00ff0000) >> 16), \ + (uint8_t)(((aDDRESS) & 0xff000000) >> 24) + + +//----------------------------------------------------- +// header for Control socket + +//Primitives +#define SESSION_INIT_REQ 1 +#define UE_STATUS_INFO 2 +#define GROUP_COMMUNICATION_ESTABLISH_REQ 3 +#define GROUP_COMMUNICATION_ESTABLISH_RSP 4 +#define DIRECT_COMMUNICATION_ESTABLISH_REQ 5 +#define DIRECT_COMMUNICATION_ESTABLISH_RSP 6 +#define GROUP_COMMUNICATION_RELEASE_REQ 7 +#define GROUP_COMMUNICATION_RELEASE_RSP 8 +#define PC5S_ESTABLISH_REQ 9 +#define PC5S_ESTABLISH_RSP 10 +#define PC5_DISCOVERY_MESSAGE 11 + + +#define PC5_DISCOVERY_PAYLOAD_SIZE 29 + + +typedef enum { + UE_STATE_OFF_NETWORK, + UE_STATE_ON_NETWORK +} SL_UE_STATE_t; + +typedef enum { + GROUP_COMMUNICATION_RELEASE_OK = 0, + GROUP_COMMUNICATION_RELEASE_FAILURE +} Group_Communication_Status_t; + +struct GroupCommunicationEstablishReq { + uint32_t sourceL2Id; + uint32_t groupL2Id; + uint32_t groupIpAddress; + uint8_t pppp; +}; + +struct GroupCommunicationReleaseReq { + uint32_t sourceL2Id; + uint32_t groupL2Id; + int slrb_id; +}; + +struct DirectCommunicationEstablishReq { + uint32_t sourceL2Id; + uint32_t destinationL2Id; + uint32_t pppp; +}; + +struct PC5SEstablishReq{ + uint8_t type; + uint32_t sourceL2Id; + uint32_t destinationL2Id; +}; + +struct PC5SEstablishRsp{ + uint32_t slrbid_lcid28; + uint32_t slrbid_lcid29; + uint32_t slrbid_lcid30; +}; + + +//PC5_DISCOVERY MESSAGE +typedef struct { + unsigned char payload[PC5_DISCOVERY_PAYLOAD_SIZE]; + uint32_t measuredPower; +} __attribute__((__packed__)) PC5DiscoveryMessage ; + + +struct sidelink_ctrl_element { + unsigned short type; + union { + struct GroupCommunicationEstablishReq group_comm_establish_req; + struct DirectCommunicationEstablishReq direct_comm_establish_req; + Group_Communication_Status_t group_comm_release_rsp; + //struct DirectCommunicationReleaseReq direct_comm_release_req; + SL_UE_STATE_t ue_state; + int slrb_id; + struct PC5SEstablishReq pc5s_establish_req; + struct PC5SEstablishRsp pc5s_establish_rsp; + PC5DiscoveryMessage pc5_discovery_message; + } sidelinkPrimitive; +}; + + +//global variables +extern struct sockaddr_in clientaddr; +extern int slrb_id; +extern pthread_mutex_t slrb_mutex; + +//the thread function +void *send_UE_status_notification(void *); + + + +//#include "COMMON/openair_defs.h" +#ifndef USER_MODE +//#include <rtai.h> +#endif #include "SystemInformationBlockType1.h" #include "SystemInformation.h" @@ -54,21 +179,28 @@ #include "RRCConnectionRequest.h" #include "RRCConnectionReestablishmentRequest.h" #include "BCCH-DL-SCH-Message.h" +#include "SBCCH-SL-BCH-MessageType.h" #include "BCCH-BCH-Message.h" -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "MCCH-Message.h" #include "MBSFNAreaConfiguration-r9.h" +#endif +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "SCellToAddMod-r10.h" #endif #include "AS-Config.h" #include "AS-Context.h" #include "UE-EUTRA-Capability.h" #include "MeasResults.h" +#include "SidelinkUEInformation-r12.h" + +/* for ImsiMobileIdentity_t */ +#include "MobileIdentity.h" /* correct Rel(8|10)/Rel14 differences * the code is in favor of Rel14, those defines do the translation */ -#if !defined(Rel14) +#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) # define CipheringAlgorithm_r12_t e_SecurityAlgorithmConfig__cipheringAlgorithm # define CipheringAlgorithm_r12_eea0 SecurityAlgorithmConfig__cipheringAlgorithm_eea0 # define CipheringAlgorithm_r12_eea1 SecurityAlgorithmConfig__cipheringAlgorithm_eea1 @@ -117,7 +249,7 @@ #endif // This corrects something generated by asn1c which is different between Rel8 and Rel10 -#if !defined(Rel10) && !defined(Rel14) +#if (RRC_VERSION <= MAKE_VERSION(10, 0, 0)) #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member SystemInformation_r8_IEs_sib_TypeAndInfo_Member #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib2 #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib3 @@ -138,7 +270,7 @@ #define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE /* -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib12_v920 #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib13_v920 #endif @@ -168,7 +300,7 @@ //-------- typedef unsigned int uid_t; -#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((NUMBER_OF_UE_MAX/8)/sizeof(unsigned int)) + 1) +#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((MAX_MOBILES_PER_ENB/8)/sizeof(unsigned int)) + 1) typedef struct uid_linear_allocator_s { unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE]; } uid_allocator_t; @@ -182,7 +314,7 @@ typedef struct uid_linear_allocator_s { #define PROTOCOL_RRC_CTXT_FMT PROTOCOL_CTXT_FMT #define PROTOCOL_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) -/** @defgroup _rrc RRC +/** @defgroup _rrc RRC * @ingroup _oai2 * @{ */ @@ -216,7 +348,22 @@ typedef enum HO_STATE_e { HO_COMPLETE // initiated by the target eNB } HO_STATE_t; -//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG +typedef enum SL_TRIGGER_e { + SL_RECEIVE_COMMUNICATION=0, + SL_TRANSMIT_RELAY_ONE_TO_ONE, + SL_TRANSMIT_RELAY_ONE_TO_MANY, + SL_TRANSMIT_NON_RELAY_ONE_TO_ONE, + SL_TRANSMIT_NON_RELAY_ONE_TO_MANY, + SL_RECEIVE_DISCOVERY, + SL_TRANSMIT_NON_PS_DISCOVERY, + SL_TRANSMIT_PS_DISCOVERY, + SL_RECEIVE_V2X, + SL_TRANSMIT_V2X, + SL_REQUEST_DISCOVERY_TRANSMISSION_GAPS, + SL_REQUEST_DISCOVERY_RECEPTION_GAPS +} SL_TRIGGER_t; + +//#define MAX_MOBILES_PER_ENB MAX_MOBILES_PER_RG #define RRM_FREE(p) if ( (p) != NULL) { free(p) ; p=NULL ; } #define RRM_MALLOC(t,n) (t *) malloc16( sizeof(t) * n ) #define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) @@ -258,7 +405,7 @@ typedef struct UE_RRC_INFO_s { uint8_t SIB1systemInfoValueTag; uint32_t SIStatus; uint32_t SIcnt; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA #endif uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 @@ -352,7 +499,7 @@ typedef struct SRB_INFO_TABLE_ENTRY_s { SRB_INFO Srb_info; uint8_t Active; uint8_t Status; - uint32_t Next_check_frame; + uint32_t Next_check_frame; } SRB_INFO_TABLE_ENTRY; typedef struct MEAS_REPORT_LIST_s { @@ -368,7 +515,7 @@ typedef struct HANDOVER_INFO_UE_s { typedef struct eNB_RRC_UE_s { uint8_t primaryCC_id; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) SCellToAddMod_r10_t sCell_config[2]; #endif SRB_ToAddModList_t* SRB_configList; @@ -391,6 +538,10 @@ typedef struct eNB_RRC_UE_s { SRB_INFO_TABLE_ENTRY Srb2; MeasConfig_t* measConfig; HANDOVER_INFO* handover_info; + MeasResults_t* measResults; + + UE_EUTRA_Capability_t* UE_Capability; + ImsiMobileIdentity_t imsi; #if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ @@ -479,7 +630,7 @@ typedef struct { uint8_t sizeof_SIB1; uint8_t *SIB23; uint8_t sizeof_SIB23; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t *SIB1_BR; uint8_t sizeof_SIB1_BR; uint8_t *SIB23_BR; @@ -498,12 +649,12 @@ typedef struct { SystemInformationBlockType1_t *sib1; SystemInformationBlockType2_t *sib2; SystemInformationBlockType3_t *sib3; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) SystemInformationBlockType1_t *sib1_BR; SystemInformationBlockType2_t *sib2_BR; SystemInformationBlockType2_t *sib3_BR; #endif -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) SystemInformationBlockType13_r9_t *sib13; uint8_t MBMS_flag; uint8_t num_mbsfn_sync_area; @@ -513,10 +664,15 @@ typedef struct { MBSFNAreaConfiguration_r9_t *mcch_message; SRB_INFO MCCH_MESS[8];// MAX_MBSFN_AREA #endif + //TTN - SIB 18,19,21 for D2D + SystemInformationBlockType18_r12_t *sib18; + SystemInformationBlockType19_r12_t *sib19; + SystemInformationBlockType21_r14_t *sib21; + // End - TTN SRB_INFO SI; SRB_INFO Srb0; - uint8_t *paging[NUMBER_OF_UE_MAX]; - uint32_t sizeof_paging[NUMBER_OF_UE_MAX]; + uint8_t *paging[MAX_MOBILES_PER_ENB]; + uint32_t sizeof_paging[MAX_MOBILES_PER_ENB]; } rrc_eNB_carrier_data_t; typedef struct eNB_RRC_INST_s { @@ -604,8 +760,29 @@ typedef struct UE_RRC_INST_s { SystemInformationBlockType9_t *sib9[NB_CNX_UE]; SystemInformationBlockType10_t *sib10[NB_CNX_UE]; SystemInformationBlockType11_t *sib11[NB_CNX_UE]; + uint8_t *MIB; +#ifdef Rel14 + //SIB18 + SystemInformationBlockType18_r12_t *sib18[NB_CNX_UE]; + SystemInformationBlockType19_r12_t *sib19[NB_CNX_UE]; + SystemInformationBlockType21_r14_t *sib21[NB_CNX_UE]; + + SBCCH_SL_BCH_MessageType_t mib_sl[NB_CNX_UE]; + /// Preconfiguration for Sidelink + struct SL_Preconfiguration_r12 *SL_Preconfiguration[NB_CNX_UE]; + //source L2 Id + uint32_t sourceL2Id; + //group L2 Id + uint32_t groupL2Id; + //current destination + uint32_t destinationL2Id; + //List of destinations + uint32_t destinationList[MAX_NUM_DEST]; + //sl_discovery.. + SRB_INFO SL_Discovery[NB_CNX_UE]; +#endif -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MBMS_flag; uint8_t *MCCH_MESSAGE[NB_CNX_UE]; uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; @@ -651,6 +828,11 @@ typedef struct UE_RRC_INST_s { /* Used integrity/ciphering algorithms */ CipheringAlgorithm_r12_t ciphering_algorithm; e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + +#ifdef Rel14 + /// Used for Sidelink Preconfiguration + DRB_ToAddModList_t *DRB_configList; +#endif } UE_RRC_INST; typedef struct UE_PF_PO_s { @@ -661,7 +843,7 @@ typedef struct UE_PF_PO_s { uint32_t T; /* DRX cycle */ } UE_PF_PO_t; -#include "proto.h" +#include "rrc_proto.h" #endif /** @} */ diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c similarity index 79% rename from openair2/RRC/LITE/rrc_eNB.c rename to openair2/RRC/LTE/rrc_eNB.c index d74dce189061e661d265725f83f4246c2f4a0f43..0e74cf2621abe436d16c457b0ed4a745d66d2bfa 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -30,17 +30,17 @@ #define RRC_ENB #define RRC_ENB_C -#include "defs.h" -#include "extern.h" +#include "rrc_defs.h" +#include "rrc_extern.h" #include "assertions.h" #include "common/ran_context.h" #include "asn1_conversions.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "LAYER2/RLC/rlc.h" -#include "LAYER2/MAC/proto.h" +#include "LAYER2/MAC/mac_proto.h" #include "UTIL/LOG/log.h" #include "COMMON/mac_rrc_primitives.h" -#include "RRC/LITE/MESSAGES/asn1_msg.h" +#include "RRC/LTE/MESSAGES/asn1_msg.h" #include "RRCConnectionRequest.h" #include "RRCConnectionReestablishmentRequest.h" //#include "ReestablishmentCause.h" @@ -52,14 +52,17 @@ #include "TDD-Config.h" #include "HandoverCommand.h" #include "rlc.h" -#include "SIMULATION/ETH_TRANSPORT/extern.h" #include "rrc_eNB_UE_context.h" #include "platform_types.h" #include "msc.h" +#include "SL-CommConfig-r12.h" +#include "PeriodicBSR-Timer-r12.h" +#include "RetxBSR-Timer-r12.h" +#include "UTIL/LOG/vcd_signal_dumper.h" #include "T.h" -//#if defined(Rel10) || defined(Rel14) +//#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "MeasResults.h" //#endif @@ -92,11 +95,8 @@ # include "rrc_eNB_ral.h" #endif -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus -#if defined(FLEXRAN_AGENT_SB_IF) -#include "flexran_agent_extern.h" -#endif //#define XER_PRINT extern RAN_CONTEXT_t RC; @@ -114,6 +114,24 @@ extern uint16_t two_tier_hexagonal_cellIds[7]; mui_t rrc_eNB_mui = 0; +void +openair_rrc_on( + const protocol_ctxt_t* const ctxt_pP +) +//----------------------------------------------------------------------------- +{ + int CC_id; + + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1; + rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0, CCCH, 1); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1; + } +} + //----------------------------------------------------------------------------- static void init_SI( @@ -126,11 +144,11 @@ init_SI( ) //----------------------------------------------------------------------------- { -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int i; #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 1, 0)) SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(SystemInformationBlockType1_v1310_IEs_t *)NULL; #endif @@ -143,7 +161,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp = configuration->prefix_type[CC_id]; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq = configuration->downlink_frequency[CC_id]; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq = configuration->downlink_frequency[CC_id]+ configuration->uplink_frequency_offset[CC_id]; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id]; #endif LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", @@ -223,8 +241,8 @@ init_SI( PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. ul_ReferenceSignalsPUSCH.cyclicShift); - -#if defined(Rel10) || defined(Rel14) + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag > 0) { for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count; i++) { @@ -244,7 +262,8 @@ init_SI( PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset); } - + +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) // SIB13 for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count; i++) { LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n", @@ -258,15 +277,86 @@ init_SI( PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9); } +#endif } else memset((void*)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13)); + + //TTN - SIB 18 + for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count; j++) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + j+1, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); + + } + + //TTN - SIB 19 + for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count; j++) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + j+1, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); + + } + #endif LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) && (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR!=NULL)) { AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL, @@ -291,7 +381,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->freqBandIndicator, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition, #endif 0, // rnti @@ -299,12 +389,12 @@ init_SI( &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib, (RadioResourceConfigCommonSIB_t *) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon, -#if defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t *) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon, #endif (struct PhysicalConfigDedicated *)NULL, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -319,20 +409,20 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.ul_Bandwidth, &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission, (MBSFN_SubframeConfigList_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag, (MBSFN_AreaInfoList_r9_t*) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9, (PMCH_InfoList_r9_t *) NULL #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , sib1_v13ext #endif ); } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*------------------------------------------------------------------------------*/ static void init_MCCH( @@ -390,15 +480,17 @@ init_MCCH( // LOG_I(RRC, "DUY: session ID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->sessionId_r9->buf[0]); rrc_mac_config_req_eNB(enb_mod_idP, CC_id, 0,0,0,0,0, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif 0,//rnti (BCCH_BCH_Message_t *)NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t *) NULL, +#endif (struct PhysicalConfigDedicated *)NULL, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -411,16 +503,16 @@ init_MCCH( (MobilityControlInfo_t *)NULL, (SchedulingInfoList_t *) NULL, 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) -# endif -# ifdef Rel14 +#endif +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (SystemInformationBlockType1_v1310_IEs_t *)NULL -# endif +#endif ); //LOG_I(RRC,"DUY: lcid after rrc_mac_config_req is %02d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9); @@ -452,16 +544,21 @@ static void init_MBMS( NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -# if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) -# endif +#endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, NULL, // SRB_ToAddModList NULL, // DRB_ToAddModList NULL, // DRB_ToReleaseList - &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)); + &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) + +#ifdef Rel14 + ,0, 0 +#endif + ); //rrc_mac_config_req(); } @@ -498,7 +595,7 @@ rrc_eNB_get_next_transaction_identifier( // // AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB index invalid (%d/%d)!", enb_mod_idP, NB_eNB_INST); // -// for (i = 0; i < NUMBER_OF_UE_MAX; i++) { +// for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { // if (RC.rrc[enb_mod_idP]->Info.UE_list[i] == UE_identity) { // // UE_identity already registered // reg = TRUE; @@ -601,7 +698,7 @@ rrc_eNB_get_next_free_ue_context( } } -#if !defined(ENABLE_USE_MME) +#if 0 //!defined(ENABLE_USE_MME) void rrc_eNB_emulation_notify_ue_module_id( const module_id_t ue_module_idP, const rnti_t rntiP, @@ -610,6 +707,7 @@ void rrc_eNB_emulation_notify_ue_module_id( const uint8_t cell_identity_byte2P, const uint8_t cell_identity_byte3P) { + LOG_I(RRC, "Panos-D: rrc_eNB_emulation_notify_ue_module_id 1 \n"); module_id_t enb_module_id; struct rrc_eNB_ue_context_s* ue_context_p = NULL; int CC_id; @@ -662,7 +760,7 @@ rrc_eNB_free_mem_UE_context( PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); #endif @@ -885,9 +983,10 @@ void release_UE_in_freeList(module_id_t mod_id) PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { eNB_PHY = RC.eNB[mod_id][CC_id]; - for (i=0; i<NUMBER_OF_UE_MAX; i++) { + for (i=0; i<MAX_MOBILES_PER_ENB; i++) { ulsch = eNB_PHY->ulsch[i]; if((ulsch != NULL) && (ulsch->rnti == rnti)){ + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); clean_eNb_ulsch(ulsch); } @@ -896,14 +995,20 @@ void release_UE_in_freeList(module_id_t mod_id) memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); } } - for (i=0; i<NUMBER_OF_UE_MAX; i++) { + for (i=0; i<MAX_MOBILES_PER_ENB; i++) { dlsch = eNB_PHY->dlsch[i][0]; if((dlsch != NULL) && (dlsch->rnti == rnti)){ + void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); clean_eNb_dlsch(dlsch); } } + if (rrc_agent_registered[mod_id]) { + agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change(mod_id, + rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } + for(j = 0; j < 10; j++){ ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; if(ul_req_tmp){ @@ -1206,15 +1311,17 @@ rrc_eNB_generate_RRCConnectionReestablishment( rrc_mac_config_req_eNB(ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ctxt_pP->rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t *) NULL, +#endif (struct PhysicalConfigDedicated* ) ue_context_pP->ue_context.physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -1227,10 +1334,10 @@ rrc_eNB_generate_RRCConnectionReestablishment( NULL, (SchedulingInfoList_t *) NULL, 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) ,(SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); @@ -1274,7 +1381,7 @@ rrc_eNB_generate_RRCConnectionReestablishment( void rrc_eNB_process_RRCConnectionReestablishmentComplete( const protocol_ctxt_t* const ctxt_pP, - const rnti_t const reestablish_rnti, + const rnti_t reestablish_rnti, rrc_eNB_ue_context_t* ue_context_pP, const uint8_t xid, RRCConnectionReestablishmentComplete_r8_IEs_t * rrcConnectionReestablishmentComplete @@ -1801,8 +1908,10 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( (struct MeasConfig__speedStatePars*)Sparams, // Sparams, (RSRP_Range_t*)rsrp, // rsrp, (C_RNTI_t*)cba_RNTI, // cba_RNTI - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList //dedicatedInfoNASList -#if defined(Rel10) || defined(Rel14) + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, //dedicatedInfoNASList + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (SCellToAddMod_r10_t*)NULL #endif ); @@ -1871,9 +1980,10 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( // eNB_MAC_INST *eNB_MAC = RC.mac[ctxt_prior.module_id]; // for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { // eNB_PHY = RC.eNB[ctxt_prior.module_id][CC_id]; -// for (int i=0; i<NUMBER_OF_UE_MAX; i++) { +// for (int i=0; i<MAX_MOBILES_PER_ENB; i++) { // ulsch = eNB_PHY->ulsch[i]; // if((ulsch != NULL) && (ulsch->rnti == ctxt_prior.rnti)){ +// void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); // LOG_I(RRC, "clean_eNb_ulsch UE %x \n", ctxt_prior.rnti); // clean_eNb_ulsch(ulsch); // break; @@ -2264,8 +2374,10 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co (struct SPS_Config*)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList -#if defined(Rel10) || defined(Rel14) + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (SCellToAddMod_r10_t*)NULL #endif ); @@ -2523,20 +2635,22 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons memset(buffer, 0, RRC_BUF_SIZE); - size = do_RRCConnectionReconfiguration(ctxt_pP, - buffer, - xid, - (SRB_ToAddModList_t*)NULL, - (DRB_ToAddModList_t*)DRB_configList2, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // *sps_Config, - NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList -#if defined(Rel10) || defined(Rel14) - , (SCellToAddMod_r10_t*)NULL + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + xid, + (SRB_ToAddModList_t*)NULL, + (DRB_ToAddModList_t*)DRB_configList2, + (DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct SPS_Config*)NULL, // *sps_Config, + NULL, NULL, NULL, NULL,NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (SCellToAddMod_r10_t*)NULL #endif - ); + ); #ifdef RRC_MSG_PRINT @@ -2655,8 +2769,10 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList -#if defined(Rel10) || defined(Rel14) + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (SCellToAddMod_r10_t*)NULL #endif ); @@ -2751,7 +2867,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; MeasIdToAddModList_t *MeasId_list = NULL; MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) long *sr_ProhibitTimer_r9 = NULL; // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); //uint8_t sCellIndexToAdd = 0; @@ -2971,7 +3087,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR mac_MainConfig->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); @@ -3038,7 +3154,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons //feedback mode needs to be set as well //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable printf("setting cqi reporting mode to rm31\n"); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportModeAperiodic_rm31; #else *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI @@ -3181,7 +3297,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); - + if (ho_state == 1 /*HO_MEASURMENT */ ) { LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", ctxt_pP->module_id, ctxt_pP->frame); @@ -3299,30 +3415,622 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = FilterCoefficient_fc4; *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = FilterCoefficient_fc4; - LOG_I(RRC, - "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", - ctxt_pP->module_id, ctxt_pP->frame); - // store the information in an intermediate structure for Hanodver management - //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); - ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = *DRB_configList; - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = - CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, - (void *)mac_MainConfig, sizeof(MAC_MainConfig_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = - CALLOC(1, sizeof(PhysicalConfigDedicated_t)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(PhysicalConfigDedicated_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); - - } - + LOG_I(RRC, + "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", + ctxt_pP->module_id, ctxt_pP->frame); + // store the information in an intermediate structure for Hanodver management + //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); + ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2; + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = *DRB_configList; + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = + CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); + memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, + (void *)mac_MainConfig, sizeof(MAC_MainConfig_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = + CALLOC(1, sizeof(PhysicalConfigDedicated_t)); + memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, + (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(PhysicalConfigDedicated_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); + + } + +#if defined(ENABLE_ITTI) + /* Initialize NAS list */ + dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + + /* Add all NAS PDUs to the list */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { + if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { + dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedInfoNas, + (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); + ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); + } + + /* TODO parameters yet to process ... */ + { + // ue_context_pP->ue_context.e_rab[i].param.qos; + // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; + // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + } + + /* TODO should test if e RAB are Ok before! */ + ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; + LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", + i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); + } + + /* If list is empty free the list and reset the address */ + if (dedicatedInfoNASList->list.count == 0) { + free(dedicatedInfoNASList); + dedicatedInfoNASList = NULL; + } + +#endif + + memset(buffer, 0, RRC_BUF_SIZE); + + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + xid, //Transaction_id, + (SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList + (DRB_ToAddModList_t*)*DRB_configList, + (DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct SPS_Config*)NULL, // *sps_Config, + (struct PhysicalConfigDedicated*)*physicalConfigDedicated, +#ifdef EXMIMO_IOT + NULL, NULL, NULL,NULL, +#else + (MeasObjectToAddModList_t*)MeasObj_list, + (ReportConfigToAddModList_t*)ReportConfig_list, + (QuantityConfig_t*)quantityConfig, + (MeasIdToAddModList_t*)MeasId_list, +#endif + (MAC_MainConfig_t*)mac_MainConfig, + (MeasGapConfig_t*)NULL, + (MobilityControlInfo_t*)NULL, + (struct MeasConfig__speedStatePars*)Sparams, + (RSRP_Range_t*)rsrp, + (C_RNTI_t*)cba_RNTI, + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (SCellToAddMod_r10_t*)NULL +#endif + ); + +#ifdef RRC_MSG_PRINT + LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); + for (i = 0; i < size; i++) { + LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); + } + LOG_F(RRC,"\n"); + //////////////////////////////////////// +#endif + +#if defined(ENABLE_ITTI) + + /* Free all NAS PDUs */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { + if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { + /* Free the NAS PDU buffer and invalidate it */ + free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer); + ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL; + } + } + +#endif + + LOG_I(RRC, + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + + LOG_D(RRC, + "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); + + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + size); + + rrc_data_req( + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +} + +//----------------------------------------------------------------------------- +void +flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + const uint8_t ho_state, + agent_reconf_rrc * trig_param + ) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + int i; + + // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; + struct PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; + + struct SRB_ToAddMod *SRB2_config = NULL; + struct SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; + struct SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; + struct LogicalChannelConfig__ul_SpecificParameters + *SRB2_ul_SpecificParameters = NULL; + SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + SRB_ToAddModList_t **SRB_configList2 = NULL; + + struct DRB_ToAddMod *DRB_config = NULL; + struct RLC_Config *DRB_rlc_config = NULL; + struct PDCP_Config *DRB_pdcp_config = NULL; + struct PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; + struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LogicalChannelConfig *DRB_lchan_config = NULL; + struct LogicalChannelConfig__ul_SpecificParameters + *DRB_ul_SpecificParameters = NULL; + DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; + DRB_ToAddModList_t** DRB_configList2 = NULL; + MAC_MainConfig_t *mac_MainConfig = NULL; + MeasObjectToAddModList_t *MeasObj_list = NULL; + MeasObjectToAddMod_t *MeasObj = NULL; + ReportConfigToAddModList_t *ReportConfig_list = NULL; + ReportConfigToAddMod_t *ReportConfig_per;//, *ReportConfig_A1, + // *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + MeasIdToAddModList_t *MeasId_list = NULL; + MeasIdToAddMod_t *MeasId0; //, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; +#if Rel10 + long *sr_ProhibitTimer_r9 = NULL; + // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); + //uint8_t sCellIndexToAdd = 0; +#endif + + long *logicalchannelgroup, *logicalchannelgroup_drb; + long *maxHARQ_Tx, *periodicBSR_Timer; + + RSRP_Range_t *rsrp = NULL; + struct MeasConfig__speedStatePars *Sparams = NULL; + QuantityConfig_t *quantityConfig = NULL; + CellsToAddMod_t *CellToAdd = NULL; + CellsToAddModList_t *CellsToAddModList = NULL; + struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + /* for no gcc warnings */ + (void)dedicatedInfoNas; + + C_RNTI_t *cba_RNTI = NULL; + + uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, + +#ifdef CBA + //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; + uint8_t *cba_RNTI_buf; + cba_RNTI = CALLOC(1, sizeof(C_RNTI_t)); + cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); + cba_RNTI->buf = cba_RNTI_buf; + cba_RNTI->size = 2; + cba_RNTI->bits_unused = 0; + + // associate UEs to the CBa groups as a function of their UE id + if (rrc_inst->num_active_cba_groups) { + cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff; + cba_RNTI->buf[1] = 0xff; + LOG_D(RRC, + "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n", + enb_mod_idP, frameP, + rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups], + ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP); + } else { + cba_RNTI->buf[0] = 0x0; + cba_RNTI->buf[1] = 0x0; + LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP); + } + +#endif + + T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + + // Configure SRB2 + /// SRB2 + SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid]; + if (*SRB_configList2) { + free(*SRB_configList2); + } + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + + SRB2_config->srb_Identity = 2; + SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config)); + SRB2_config->rlc_Config = SRB2_rlc_config; + + SRB2_rlc_config->present = SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; + + SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config)); + SRB2_config->logicalChannelConfig = SRB2_lchan_config; + + SRB2_lchan_config->present = SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; + + SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); + + SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs + SRB2_ul_SpecificParameters->prioritisedBitRate = + LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for CCCH and DCCH is 0 as defined in 36331 + logicalchannelgroup = CALLOC(1, sizeof(long)); + *logicalchannelgroup = 0; + + SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; + + SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; + // this list has the configuration for SRB1 and SRB2 + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + // this list has only the configuration for SRB2 + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + + // Configure DRB + //*DRB_configList = CALLOC(1, sizeof(*DRB_configList)); + // list for all the configured DRB + if (*DRB_configList) { + free(*DRB_configList); + } + *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); + memset(*DRB_configList, 0, sizeof(**DRB_configList)); + + // list for the configured DRB for a this xid + DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + if (*DRB_configList2) { + free(*DRB_configList2); + } + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); + memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); + + + /// DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); + + DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 + // DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32 + // NN: this is the 1st DRB for this ue, so set it to 1 + DRB_config->drb_Identity = (DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32, value: x + DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 + DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); + DRB_config->rlc_Config = DRB_rlc_config; + +#ifdef RRC_DEFAULT_RAB_IS_AM + DRB_rlc_config->present = RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25; +#else + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; +#ifdef CBA + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms5;//T_Reordering_ms25; +#else + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; +#endif +#endif + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + DRB_config->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + /* avoid gcc warnings */ + (void)PDCP_rlc_AM; + (void)PDCP_rlc_UM; + +#ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT + PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); + DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; + PDCP_rlc_AM->statusReportRequired = FALSE; +#else + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; +#endif + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); + DRB_config->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); + ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); + + //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); + + mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); + // ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; + + mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); + + maxHARQ_Tx = CALLOC(1, sizeof(long)); + *maxHARQ_Tx = MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + periodicBSR_Timer = CALLOC(1, sizeof(long)); + *periodicBSR_Timer = PeriodicBSR_Timer_r12_sf64; + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + + mac_MainConfig->timeAlignmentTimerDedicated = TimeAlignmentTimer_infinity; + + mac_MainConfig->drx_Config = NULL; + + mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); + + mac_MainConfig->phr_Config->present = MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes + + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB + +#ifdef Rel10 + sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); + *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR + mac_MainConfig->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); + mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; + //sps_RA_ConfigList_rlola = NULL; +#endif + + //change the transmission mode for the primary component carrier + //TODO: add codebook subset restriction here + //TODO: change TM for secondary CC in SCelltoaddmodlist + if (*physicalConfigDedicated) { + if ((*physicalConfigDedicated)->antennaInfo) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.ue_TransmissionMode[0]; + LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.ue_TransmissionMode[0]); + if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm3) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; + } + else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; + + } + else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; + } + else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; + } + } + else { + LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); + } + if ((*physicalConfigDedicated)->cqi_ReportConfig) { + if ((rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6)) { + //feedback mode needs to be set as well + //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + printf("setting cqi reporting mode to rm31\n"); +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportModeAperiodic_rm31; +#else + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI +#endif + } + } + else { + LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n"); + } + } + else { + LOG_E(RRC,"physical_config_dedicated not present in RRCConnectionReconfiguration. Not reconfiguring!\n"); + } + + // Measurement ID list + MeasId_list = CALLOC(1, sizeof(*MeasId_list)); + memset((void *)MeasId_list, 0, sizeof(*MeasId_list)); + + MeasId0 = CALLOC(1, sizeof(*MeasId0)); + MeasId0->measId = 1; + MeasId0->measObjectId = 1; + MeasId0->reportConfigId = 1; + ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId0); + + /* + * Add one EUTRA Measurement Object + */ + + MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); + memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list)); + + // Configure MeasObject + + MeasObj = CALLOC(1, sizeof(*MeasObj)); + memset((void *)MeasObj, 0, sizeof(*MeasObj)); + + MeasObj->measObjectId = 1; + MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz + //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t)); + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; + MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB + + MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = + (CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + + CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; + + // Add adjacent cell lists (6 per eNB) + for (i = 0; i < 6; i++) { + CellToAdd = (CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); + CellToAdd->cellIndex = i + 1; + CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); + CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + + ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); + } + + ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; + + // Report Configurations for periodical, A1-A5 events + + /* RRC Strategy Measurement */ + + + if (strcmp("one_shot", trig_param->trigger_policy) == 0){ + + trig_param->report_interval = 0; + trig_param->report_amount = 0; + + } + + else if (strcmp("event_driven", trig_param->trigger_policy) == 0){ + + trig_param->report_interval = 6; + trig_param->report_amount = 2; + + } + + else if (strcmp("periodical", trig_param->trigger_policy) == 0){ + + trig_param->report_interval = 1; + trig_param->report_amount = 7; + + } + + else { + + LOG_E(FLEXRAN_AGENT, "There is something wrong on RRC agent!"); + } + + + + ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list)); + + ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per)); + + // Periodical Measurement Report + + ReportConfig_per->reportConfigId = 1; + ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = + ReportConfigEUTRA__triggerType_PR_periodical; + + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose = + ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + + // ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = TimeToTrigger_ms40; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = trig_param->report_interval ;//ReportInterval_ms2048; // RRC counter frame- ms1024 is 1ms + + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = trig_param->report_amount; //ReportConfigEUTRA__reportAmount_r2; // put r1 to see once, r2 for 2 times and ... + + + ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per); + + + + quantityConfig = CALLOC(1, sizeof(*quantityConfig)); + memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct QuantityConfigEUTRA)); + memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); + quantityConfig->quantityConfigCDMA2000 = NULL; + quantityConfig->quantityConfigGERAN = NULL; + quantityConfig->quantityConfigUTRA = NULL; + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP))); + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = FilterCoefficient_fc4; + + #if defined(ENABLE_ITTI) /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -3333,22 +4041,22 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, - (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); } /* TODO parameters yet to process ... */ - { + // { // ue_context_pP->ue_context.e_rab[i].param.qos; // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; - } + // } /* TODO should test if e RAB are Ok before! */ ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", - i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); + i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); } /* If list is empty free the list and reset the address */ @@ -3360,31 +4068,33 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons #endif memset(buffer, 0, RRC_BUF_SIZE); - + size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, xid, //Transaction_id, - (SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList - (DRB_ToAddModList_t*)*DRB_configList, + (SRB_ToAddModList_t*)NULL, // SRB_configList + (DRB_ToAddModList_t*)NULL, (DRB_ToReleaseList_t*)NULL, // DRB2_list, (struct SPS_Config*)NULL, // *sps_Config, (struct PhysicalConfigDedicated*)*physicalConfigDedicated, -#ifdef EXMIMO_IOT - NULL, NULL, NULL,NULL, -#else +// #ifdef EXMIMO_IOT +// NULL, NULL, NULL,NULL, +// #else (MeasObjectToAddModList_t*)MeasObj_list, (ReportConfigToAddModList_t*)ReportConfig_list, (QuantityConfig_t*)quantityConfig, (MeasIdToAddModList_t*)MeasId_list, -#endif +// #endif (MAC_MainConfig_t*)mac_MainConfig, (MeasGapConfig_t*)NULL, (MobilityControlInfo_t*)NULL, (struct MeasConfig__speedStatePars*)Sparams, (RSRP_Range_t*)rsrp, (C_RNTI_t*)cba_RNTI, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList -#if defined(Rel10) || defined(Rel14) + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (SCellToAddMod_r10_t*)NULL #endif ); @@ -3431,122 +4141,15 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons size); rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } -typedef enum { BAND_TYPE_FDD, BAND_TYPE_TDD } band_type; - -typedef struct { - band_type t; - int band; - unsigned long ul_minfreq, ul_maxfreq; - unsigned long dl_minfreq, dl_maxfreq; -} band_freq; - -static band_freq bands[] = { - { BAND_TYPE_FDD, 1, 1920000000UL, 1980000000UL, 2110000000UL, 2170000000UL }, - { BAND_TYPE_FDD, 2, 1850000000UL, 1910000000UL, 1930000000UL, 1990000000UL }, - { BAND_TYPE_FDD, 3, 1710000000UL, 1785000000UL, 1805000000UL, 1880000000UL }, - { BAND_TYPE_FDD, 4, 1710000000UL, 1755000000UL, 2110000000UL, 2155000000UL }, - { BAND_TYPE_FDD, 5, 824000000UL, 849000000UL, 869000000UL, 894000000UL }, - /* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL }, - { BAND_TYPE_FDD, 7, 2500000000UL, 2570000000UL, 2620000000UL, 2690000000UL }, - { BAND_TYPE_FDD, 8, 880000000UL, 915000000UL, 925000000UL, 960000000UL }, - { BAND_TYPE_FDD, 9, 1749900000UL, 1784900000UL, 1844900000UL, 1879900000UL }, - { BAND_TYPE_FDD, 10, 1710000000UL, 1770000000UL, 2110000000UL, 2170000000UL }, - { BAND_TYPE_FDD, 11, 1427900000UL, 1447900000UL, 1475900000UL, 1495900000UL }, - { BAND_TYPE_FDD, 12, 699000000UL, 716000000UL, 729000000UL, 746000000UL }, - { BAND_TYPE_FDD, 13, 777000000UL, 787000000UL, 746000000UL, 756000000UL }, - { BAND_TYPE_FDD, 14, 788000000UL, 798000000UL, 758000000UL, 768000000UL }, - { BAND_TYPE_FDD, 17, 704000000UL, 716000000UL, 734000000UL, 746000000UL }, - { BAND_TYPE_FDD, 18, 815000000UL, 830000000UL, 860000000UL, 875000000UL }, - { BAND_TYPE_FDD, 19, 830000000UL, 845000000UL, 875000000UL, 890000000UL }, - { BAND_TYPE_FDD, 20, 832000000UL, 862000000UL, 791000000UL, 821000000UL }, - { BAND_TYPE_FDD, 21, 1447900000UL, 1462900000UL, 1495900000UL, 1510900000UL }, - { BAND_TYPE_FDD, 22, 3410000000UL, 3490000000UL, 3510000000UL, 3590000000UL }, - { BAND_TYPE_FDD, 23, 2000000000UL, 2020000000UL, 2180000000UL, 2200000000UL }, - { BAND_TYPE_FDD, 24, 1626500000UL, 1660500000UL, 1525000000UL, 1559000000UL }, - { BAND_TYPE_FDD, 25, 1850000000UL, 1915000000UL, 1930000000UL, 1995000000UL }, - - { BAND_TYPE_TDD, 33, 1900000000UL, 1920000000UL, 1900000000UL, 1920000000UL }, - { BAND_TYPE_TDD, 34, 2010000000UL, 2025000000UL, 2010000000UL, 2025000000UL }, - { BAND_TYPE_TDD, 35, 1850000000UL, 1910000000UL, 1850000000UL, 1910000000UL }, - { BAND_TYPE_TDD, 36, 1930000000UL, 1990000000UL, 1930000000UL, 1990000000UL }, - { BAND_TYPE_TDD, 37, 1910000000UL, 1930000000UL, 1910000000UL, 1930000000UL }, - { BAND_TYPE_TDD, 38, 2570000000UL, 2620000000UL, 2570000000UL, 2620000000UL }, - { BAND_TYPE_TDD, 39, 1880000000UL, 1920000000UL, 1880000000UL, 1920000000UL }, - { BAND_TYPE_TDD, 40, 2300000000UL, 2400000000UL, 2300000000UL, 2400000000UL }, - { BAND_TYPE_TDD, 41, 2496000000UL, 2690000000UL, 2496000000UL, 2690000000UL }, - { BAND_TYPE_TDD, 42, 3400000000UL, 3600000000UL, 3400000000UL, 3600000000UL }, - { BAND_TYPE_TDD, 43, 3600000000UL, 3800000000UL, 3600000000UL, 3800000000UL }, -}; - -typedef struct { - int band; - unsigned long dl_flow; - int dl_off; - int dl_offmin, dl_offmax; - unsigned long ul_flow; - int ul_off; - int ul_offmin, ul_offmax; -} earfcn; - -static earfcn earfcn_table[] = { - { 1, 2110000000UL, 0, 0, 599, 1920000000UL, 18000, 18000, 18599 }, - { 2, 1930000000UL, 600, 600, 1199, 1850000000UL, 18600, 18600, 19199 }, - { 3, 1805000000UL, 1200, 1200, 1949, 1710000000UL, 19200, 19200, 19949 }, - { 4, 2110000000UL, 1950, 1950, 2399, 1710000000UL, 19950, 19950, 20399 }, - { 5, 869000000UL, 2400, 2400, 2649, 824000000UL, 20400, 20400, 20649 }, - { 6, 875000000UL, 2650, 2650, 2749, 830000000UL, 20650, 20650, 20749 }, - { 7, 2620000000UL, 2750, 2750, 3449, 2500000000UL, 20750, 20750, 21449 }, - { 8, 925000000UL, 3450, 3450, 3799, 880000000UL, 21450, 21450, 21799 }, - { 9, 1844900000UL, 3800, 3800, 4149, 1749900000UL, 21800, 21800, 22149 }, - { 10, 2110000000UL, 4150, 4150, 4749, 1710000000UL, 22150, 22150, 22749 }, - { 11, 1475900000UL, 4750, 4750, 4949, 1427900000UL, 22750, 22750, 22949 }, - { 12, 729000000UL, 5010, 5010, 5179, 699000000UL, 23010, 23010, 23179 }, - { 13, 746000000UL, 5180, 5180, 5279, 777000000UL, 23180, 23180, 23279 }, - { 14, 758000000UL, 5280, 5280, 5379, 788000000UL, 23280, 23280, 23379 }, - { 17, 734000000UL, 5730, 5730, 5849, 704000000UL, 23730, 23730, 23849 }, - { 18, 860000000UL, 5850, 5850, 5999, 815000000UL, 23850, 23850, 23999 }, - { 19, 875000000UL, 6000, 6000, 6149, 830000000UL, 24000, 24000, 24149 }, - { 20, 791000000UL, 6150, 6150, 6449, 832000000UL, 24150, 24150, 24449 }, - { 21, 1495900000UL, 6450, 6450, 6599, 1447900000UL, 24450, 24450, 24599 }, - { 22, 3510000000UL, 6600, 6600, 7399, 3410000000UL, 24600, 24600, 25399 }, - { 23, 2180000000UL, 7500, 7500, 7699, 2000000000UL, 25500, 25500, 25699 }, - { 24, 1525000000UL, 7700, 7700, 8039, 1626500000UL, 25700, 25700, 26039 }, - { 25, 1930000000UL, 8040, 8040, 8689, 1850000000UL, 26040, 26040, 26689 }, - { 33, 1900000000UL, 36000, 36000, 36199, 1900000000UL, 36000, 36000, 36199 }, - { 34, 2010000000UL, 36200, 36200, 36349, 2010000000UL, 36200, 36200, 36349 }, - { 35, 1850000000UL, 36350, 36350, 36949, 1850000000UL, 36350, 36350, 36949 }, - { 36, 1930000000UL, 36950, 36950, 37549, 1930000000UL, 36950, 36950, 37549 }, - { 37, 1910000000UL, 37550, 37550, 37749, 1910000000UL, 37550, 37550, 37749 }, - { 38, 2570000000UL, 37750, 37750, 38249, 2570000000UL, 37750, 37750, 38249 }, - { 39, 1880000000UL, 38250, 38250, 38649, 1880000000UL, 38250, 38250, 38649 }, - { 40, 2300000000UL, 38650, 38650, 39649, 2300000000UL, 38650, 38650, 39649 }, - { 41, 2496000000UL, 39650, 39650, 41589, 2496000000UL, 39650, 39650, 41589 }, - { 42, 3400000000UL, 41590, 41590, 43589, 3400000000UL, 41590, 41590, 43589 }, - { 43, 3600000000UL, 43590, 43590, 45589, 3600000000UL, 43590, 43590, 45589 }, -}; - -int freq_to_arfcn10(int band, unsigned long freq) -{ - int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]); - int i; - - for (i = 0; i < N; i++) if (bands[i].band == band) break; - if (i == N) return -1; - - if (!(bands[i].dl_minfreq < freq && freq < bands[i].dl_maxfreq)) - return -1; - - return (freq - earfcn_table[i].dl_flow) / 100000UL + earfcn_table[i].dl_off; -} //----------------------------------------------------------------------------- int @@ -3561,7 +4164,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( uint8_t size; uint8_t buffer[100]; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t sCellIndexToAdd = 0; //one SCell so far // uint8_t sCellIndexToAdd; @@ -3593,9 +4196,11 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( (struct MeasConfig__speedStatePars*)NULL, (RSRP_Range_t*)NULL, (C_RNTI_t*)NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , ue_context_pP->ue_context.sCell_config #endif ); @@ -3629,46 +4234,72 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( void rrc_eNB_process_MeasurementReport( const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + rrc_eNB_ue_context_t* ue_context_pP, const MeasResults_t* const measResults2 ) //----------------------------------------------------------------------------- { + int i=0; + int neighboring_cells=-1; + T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + if (measResults2 == NULL ) + return; + + if (measResults2->measId > 0 ){ + if (ue_context_pP->ue_context.measResults == NULL) { + ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(MeasResults_t)); + } + ue_context_pP->ue_context.measResults->measId=measResults2->measId; + ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult; + ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult=measResults2->measResultPCell.rsrqResult; + LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRP of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult-140); + LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRQ of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult/2 - 20); + } + if (measResults2->measResultNeighCells == NULL) + return; - LOG_I(RRC, "[eNB %d] Frame %d: Process Measurement Report From UE %x (Measurement Id %d)\n", - ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId); - - if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { - LOG_I(RRC, "Physical Cell Id %d\n", - (int)measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); - LOG_I(RRC, "RSRP of Target %d\n", - (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> - measResult.rsrpResult)); - LOG_I(RRC, "RSRQ of Target %d\n", - (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> - measResult.rsrqResult)); - } + if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { + neighboring_cells = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count; + + if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) { + + ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*measResults2->measResultNeighCells)*neighboring_cells); + } + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count = neighboring_cells; + for (i=0; i < neighboring_cells; i++){ + memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i], + measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i], + sizeof(MeasResultListEUTRA_t)); + + LOG_D(RRC, "Physical Cell Id %d\n", + (int)ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId); + LOG_D(RRC, "RSRP of Target %d\n", + (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)); + LOG_D(RRC, "RSRQ of Target %d\n", + (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)); + } + } -#if defined(Rel10) || defined(Rel14) - LOG_I(RRC, "RSRP of Source %ld\n", measResults2->measResultPCell.rsrpResult); - LOG_I(RRC, "RSRQ of Source %ld\n", measResults2->measResultPCell.rsrqResult); -#else - LOG_I(RRC, "RSRP of Source %ld\n", measResults2->measResultServCell.rsrpResult); - LOG_I(RRC, "RSRQ of Source %ld\n", measResults2->measResultServCell.rsrqResult); -#endif +// #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) { - rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP, - ue_context_pP, - measResults2->measResultNeighCells->choice. - measResultListEUTRA.list.array[0]->physCellId); - } else { - LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, - ctxt_pP->rnti); - } + +// #else + // LOG_I(RRC, "RSRP of Source %d\n", measResults2->measResultServCell.rsrpResult); + // LOG_I(RRC, "RSRQ of Source %d\n", measResults2->measResultServCell.rsrqResult); +// #endif + + // if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) { + // rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP, + // ue_context_pP, + // measResults2->measResultNeighCells->choice. + // measResultListEUTRA.list.array[0]->physCellId); + // } else { + // LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, + // ctxt_pP->rnti); + // } //Look for IP address of the target eNB //Send Handover Request -> target eNB @@ -3858,7 +4489,12 @@ check_handovers( SDU_CONFIRM_NO, ue_context_p->ue_context.handover_info->size, ue_context_p->ue_context.handover_info->buf, - PDCP_TRANSMISSION_MODE_CONTROL); + PDCP_TRANSMISSION_MODE_CONTROL +#ifdef Rel14 + ,NULL, NULL +#endif + ); + //AssertFatal(result == TRUE, "PDCP data request failed!\n"); if(result != TRUE) { LOG_I(RRC, "PDCP data request failed!\n"); @@ -3923,7 +4559,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( // HandoverCommand_t handoverCommand; //uint8_t sourceModId = // get_adjacent_cell_mod_id(ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) long *sr_ProhibitTimer_r9; #endif @@ -4167,15 +4803,17 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t*) NULL, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t*) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -4191,13 +4829,13 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif -# ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (SystemInformationBlockType1_v1310_IEs_t *)NULL -# endif +#endif ); // Configure target eNB SRB2 @@ -4313,7 +4951,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR mac_MainConfig->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); @@ -4675,7 +5313,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( rrc_pdcp_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, (DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (PMCH_InfoList_r9_t *) NULL #endif ,NULL); @@ -4683,8 +5321,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( rrc_rlc_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, (DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (PMCH_InfoList_r9_t *) NULL + , 0, 0 #endif ); @@ -4713,8 +5352,10 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( Sparams, NULL, NULL, - dedicatedInfoNASList -#if defined(Rel10) || defined(Rel14) + dedicatedInfoNASList, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)NULL +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , NULL // SCellToAddMod_r10_t #endif ); @@ -4746,15 +5387,17 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -4766,13 +5409,13 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( (TDD_Config_t *) NULL, (MobilityControlInfo_t *) mobilityInfo, (SchedulingInfoList_t *) NULL, 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif -# ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (SystemInformationBlockType1_v1310_IEs_t *)NULL -# endif +#endif ); /* @@ -4896,7 +5539,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( kRRCenc, kRRCint, kUPenc -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (PMCH_InfoList_r9_t *) NULL #endif ,NULL); @@ -4907,8 +5550,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( DRB_configList, // (DRB_ToReleaseList_t *) NULL DRB_Release_configList2 -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (PMCH_InfoList_r9_t *) NULL + , 0, 0 #endif ); @@ -5016,15 +5660,17 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -5037,13 +5683,13 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( NULL, (SchedulingInfoList_t *) NULL, 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif -# ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (SystemInformationBlockType1_v1310_IEs_t *)NULL -# endif +#endif ); } else { // remove LCHAN from MAC/PHY @@ -5069,15 +5715,17 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( rrc_mac_config_req_eNB(ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -5090,13 +5738,13 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( NULL, (SchedulingInfoList_t *) NULL, 0, NULL, NULL, NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif -# ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (SystemInformationBlockType1_v1310_IEs_t *)NULL -# endif +#endif ); } } @@ -5185,15 +5833,17 @@ rrc_eNB_generate_RRCConnectionSetup( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -5206,13 +5856,13 @@ rrc_eNB_generate_RRCConnectionSetup( NULL, (SchedulingInfoList_t *) NULL, 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif -# ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (SystemInformationBlockType1_v1310_IEs_t *)NULL -# endif +#endif ); break; } @@ -5273,11 +5923,11 @@ openair_rrc_eNB_init( } #endif AssertFatal(RC.rrc[enb_mod_idP] != NULL, "RC.rrc not initialized!"); - AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); + AssertFatal(MAX_MOBILES_PER_ENB < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); #ifdef ENABLE_ITTI AssertFatal(configuration!=NULL,"configuration input is null\n"); #endif - // for (j = 0; j < NUMBER_OF_UE_MAX; j++) + // for (j = 0; j < MAX_MOBILES_PER_ENB; j++) // RC.rrc[ctxt.module_id].Info.UE[j].Status = RRC_IDLE; //CH_READY; // //#if defined(ENABLE_USE_MME) @@ -5286,7 +5936,7 @@ openair_rrc_eNB_init( //#endif // { // /* Init security parameters */ - // for (j = 0; j < NUMBER_OF_UE_MAX; j++) { + // for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { // RC.rrc[ctxt.module_id].ciphering_algorithm[j] = SecurityAlgorithmConfig__cipheringAlgorithm_eea0; // RC.rrc[ctxt.module_id].integrity_algorithm[j] = SecurityAlgorithmConfig__integrityProtAlgorithm_eia2; // rrc_eNB_init_security(enb_mod_idP, j); @@ -5300,13 +5950,13 @@ openair_rrc_eNB_init( uid_linear_allocator_init(&RC.rrc[ctxt.module_id]->uid_allocator); RB_INIT(&RC.rrc[ctxt.module_id]->rrc_ue_head); - // for (j = 0; j < (NUMBER_OF_UE_MAX + 1); j++) { + // for (j = 0; j < (MAX_MOBILES_PER_ENB + 1); j++) { // RC.rrc[enb_mod_idP]->Srb2[j].Active = 0; // } - RC.rrc[ctxt.module_id]->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); - RC.rrc[ctxt.module_id]->s1ap_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); + RC.rrc[ctxt.module_id]->initial_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL); + RC.rrc[ctxt.module_id]->s1ap_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL); memcpy(&RC.rrc[ctxt.module_id]->configuration,configuration,sizeof(RrcConfigurationReq)); @@ -5314,14 +5964,14 @@ openair_rrc_eNB_init( LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // can clear it at runtime RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag = 0; // This has to come from some top-level configuration // only CC_id 0 is logged -#if defined(Rel10) +#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel10 RRC detected, MBMS flag %d\n", #else LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel14 RRC detected, MBMS flag %d\n", @@ -5362,7 +6012,7 @@ openair_rrc_eNB_init( , configuration #endif ); - for (int ue_id = 0; ue_id < NUMBER_OF_UE_MAX; ue_id++) { + for (int ue_id = 0; ue_id < MAX_MOBILES_PER_ENB; ue_id++) { RC.rrc[ctxt.module_id]->carrier[CC_id].sizeof_paging[ue_id] = 0; RC.rrc[ctxt.module_id]->carrier[CC_id].paging[ue_id] = (uint8_t*) malloc16(256); } @@ -5371,7 +6021,7 @@ openair_rrc_eNB_init( rrc_init_global_param(); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) switch (RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag) { case 1: case 2: @@ -5637,7 +6287,7 @@ rrc_eNB_decode_ccch( ue_context_p->ue_context.reestablishment_xid = -1; // insert C-RNTI to map - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (reestablish_rnti_map[i][0] == 0) { reestablish_rnti_map[i][0] = ctxt_pP->rnti; reestablish_rnti_map[i][1] = c_rnti; @@ -5707,17 +6357,18 @@ rrc_eNB_decode_ccch( NULL, NULL, NULL -# if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (PMCH_InfoList_r9_t *) NULL -# endif +#endif ,NULL); rrc_rlc_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, (DRB_ToAddModList_t*) NULL, (DRB_ToReleaseList_t*) NULL -# if defined(Rel10) || defined(Rel14) - , (PMCH_InfoList_r9_t *) NULL +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (PMCH_InfoList_r9_t *) NULL, + 0,0 # endif ); #endif //NO_RRM @@ -5876,6 +6527,11 @@ rrc_eNB_decode_ccch( } else { // no context available + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + ctxt_pP->rnti, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), random_value); @@ -5934,18 +6590,19 @@ rrc_eNB_decode_ccch( NULL, NULL, NULL -# if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (PMCH_InfoList_r9_t *) NULL -# endif +#endif ,NULL); rrc_rlc_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, (DRB_ToAddModList_t*) NULL, (DRB_ToReleaseList_t*) NULL -# if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (PMCH_InfoList_r9_t *) NULL -# endif + , 0, 0 +#endif ); #endif //NO_RRM @@ -5982,7 +6639,6 @@ rrc_eNB_decode_dcch( asn_dec_rval_t dec_rval; //UL_DCCH_Message_t uldcchmsg; UL_DCCH_Message_t *ul_dcch_msg = NULL; //&uldcchmsg; - UE_EUTRA_Capability_t *UE_EUTRA_Capability = NULL; int i; struct rrc_eNB_ue_context_s* ue_context_p = NULL; #if defined(ENABLE_ITTI) @@ -6164,14 +6820,12 @@ rrc_eNB_decode_dcch( ue_context_p, ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); -#if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (mac_agent_registered[ctxt_pP->module_id]) { - agent_mac_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); } -#endif } #if defined(ENABLE_ITTI) # if defined(ENABLE_USE_MME) @@ -6284,7 +6938,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { { rnti_t reestablish_rnti = 0; // select C-RNTI from map - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) { reestablish_rnti = reestablish_rnti_map[i][1]; ue_context_p = rrc_eNB_get_ue_context( @@ -6322,14 +6976,12 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.rrc_TransactionIdentifier, &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8); -#if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (mac_agent_registered[ctxt_pP->module_id]) { - agent_mac_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } -#endif } //ue_context_p->ue_context.ue_release_timer = 0; ue_context_p->ue_context.ue_reestablishment_timer = 1; @@ -6384,14 +7036,12 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); -#if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (mac_agent_registered[ctxt_pP->module_id]) { - agent_mac_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } -#endif } } @@ -6529,18 +7179,33 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); #endif LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); + if (ue_context_p->ue_context.UE_Capability) { + LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti); + asn_DEF_UE_EUTRA_Capability.free_struct(&asn_DEF_UE_EUTRA_Capability, + ue_context_p->ue_context.UE_Capability, 0); + ue_context_p->ue_context.UE_Capability = 0; + } dec_rval = uper_decode(NULL, &asn_DEF_UE_EUTRA_Capability, - (void **)&UE_EUTRA_Capability, + (void **)&ue_context_p->ue_context.UE_Capability, ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. array[0]->ueCapabilityRAT_Container.buf, ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. array[0]->ueCapabilityRAT_Container.size, 0, 0); - //#ifdef XER_PRINT - //xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability); - //#endif +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); +#endif + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UE capabilities (%zu bytes)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + asn_DEF_UE_EUTRA_Capability.free_struct(&asn_DEF_UE_EUTRA_Capability, + ue_context_p->ue_context.UE_Capability, 0); + ue_context_p->ue_context.UE_Capability = 0; + } #if defined(ENABLE_USE_MME) @@ -6618,7 +7283,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { break; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) case UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: T(T_ENB_RRC_UE_INFORMATION_RESPONSE_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), @@ -6631,7 +7296,9 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); break; +#endif +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: T(T_ENB_RRC_RECONFIGURATION_COMPLETE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -6662,6 +7329,53 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { } return 0; + //TTN for D2D + } else if (ul_dcch_msg->message.present == UL_DCCH_MessageType_PR_messageClassExtension){ + LOG_I(RRC, "THINH [UL_DCCH_MessageType_PR_messageClassExtension]\n"); + + switch (ul_dcch_msg->message.choice.messageClassExtension.present) { + case UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */ + break; + case UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation + //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation + LOG_I(RRC,"THINH [UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); + +#ifdef RRC_MSG_PRINT + LOG_F(RRC,"[MSG] SidelinkUEInformation\n"); + + for (i = 0; i < sdu_sizeP; i++) { + LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); + } + + LOG_F(RRC,"\n"); +#endif + + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(SidelinkUEInformation) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + rrc_eNB_process_SidelinkUEInformation( + ctxt_pP, + ue_context_p, + &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12); + break; + default: + break; + } + //end TTN } else { LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown error %s:%u\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -6669,6 +7383,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { return -1; } + return 0; } #if defined(ENABLE_ITTI) @@ -6737,6 +7452,7 @@ rrc_enb_task( switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(RRC, " *** Exiting RRC thread\n"); itti_exit_task(); break; @@ -6894,7 +7610,7 @@ openair_rrc_top_init_eNB(int eMBMS_active,uint8_t HO_active) RC.rrc[module_id]->HO_flag = (uint8_t)HO_active; } -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[eNB] eMBMS active state is %d \n", eMBMS_active); for (module_id=0; module_id<NB_eNB_INST; module_id++) { @@ -6930,3 +7646,534 @@ rrc_top_cleanup_eNB( free(RC.rrc); } + +//----------------------------------------------------------------------------- +//TTN - for D2D +uint8_t +rrc_eNB_process_SidelinkUEInformation( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* ue_context_pP, + SidelinkUEInformation_r12_t * sidelinkUEInformation +) +//----------------------------------------------------------------------------- +{ + SL_DestinationInfoList_r12_t *destinationInfoList; + int n_destinations = 0; + int ue_type = 0; + int n_discoveryMessages = 0; + + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing SidelinkUEInformation from UE (SRB1 Active)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + + //For SL Communication + if (sidelinkUEInformation->criticalExtensions.present == SidelinkUEInformation_r12__criticalExtensions_PR_c1){ + if (sidelinkUEInformation->criticalExtensions.choice.c1.present == SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12){ + // express its interest to receive SL communication + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 != NULL){ + + } + + // express its interest to transmit non-relay one-to-many SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12 != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 != NULL)){ + n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.count; + destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + for (int i=0; i< n_destinations; i++ ){ + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); + } + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + + } + + // express its interest to transmit non-relay one-to-one SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13 != NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 != NULL){ + n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.count; + destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + for (int i=0; i< n_destinations; i++ ){ + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list,sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); + } + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + } + } + + // express its interest to transmit relay related one-to-one SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) &&(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13 != NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count > 0) { + n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count; + ue_type = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13; + destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + for (int i=0; i< n_destinations; i++ ){ + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); + } + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + } + } + + //express its interest to transmit relay related one-to-many SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13 != NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count > 0){ + n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count; + ue_type = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13; + destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + for (int i=0; i< n_destinations; i++ ){ + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list,sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); + } + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + } + } + + //For SL Discovery + //express its interest to receive SL discovery announcements + //express its interest to transmit non-PS related discovery announcements + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12 != NULL){ + n_discoveryMessages = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12); + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages); + return 0; + } + //express its interest to transmit PS related discovery announcements + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13 !=NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13 > 0){ + n_discoveryMessages = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13; + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages); + return 0; + } + } + } + } + return 0; +} + +//----------------------------------------------------------------------------- +int +rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + SL_DestinationInfoList_r12_t *destinationInfoList, + int n_discoveryMessages +) +//----------------------------------------------------------------------------- +{ + + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size = -1; + memset(buffer, 0, RRC_BUF_SIZE); + + // allocate dedicated pools for UE -sl-CommConfig/sl-DiscConfig (sl-V2X-ConfigDedicated) + //populate dedicated resources for SL communication (sl-CommConfig) + if ((destinationInfoList != NULL) && (destinationInfoList->list.count > 0)) { + + LOG_I(RRC,"[eNB %d] Frame %d, Generate RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x), number of destinations %d\n", + ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti,destinationInfoList->list.count ); + //get dedicated resources from available pool and assign to the UE + SL_CommConfig_r12_t sl_CommConfig[destinationInfoList->list.count]; + //get a RP from the available RPs + sl_CommConfig[0] = rrc_eNB_get_sidelink_commTXPool(ctxt_pP, ue_context_pP, destinationInfoList); + + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id + (SRB_ToAddModList_t*)NULL, + (DRB_ToAddModList_t*)NULL, + (DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct SPS_Config*)NULL, // *sps_Config, + NULL, NULL, NULL, NULL,NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, + (SL_CommConfig_r12_t*)&sl_CommConfig, + (SL_DiscConfig_r12_t*)NULL + #if defined(Rel10) || defined(Rel14) + , (SCellToAddMod_r10_t*)NULL + #endif + ); + // + } + //populate dedicated resources for SL discovery (sl-DiscConfig) + if (n_discoveryMessages > 0) { + SL_DiscConfig_r12_t sl_DiscConfig[n_discoveryMessages]; + //get a RP from the available RPs + sl_DiscConfig[0] = rrc_eNB_get_sidelink_discTXPool(ctxt_pP, ue_context_pP, n_discoveryMessages ); + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id + (SRB_ToAddModList_t*)NULL, + (DRB_ToAddModList_t*)NULL, + (DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct SPS_Config*)NULL, // *sps_Config, + NULL, NULL, NULL, NULL,NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, + (SL_CommConfig_r12_t*)NULL, + (SL_DiscConfig_r12_t*)&sl_DiscConfig + #if defined(Rel10) || defined(Rel14) + , (SCellToAddMod_r10_t*)NULL + #endif + ); + } + + LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x)\n", + ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + + rrc_data_req( + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + + // rrc_data_req(); + + return size; +} + +SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, SL_DestinationInfoList_r12_t *destinationInfoList ){ + // for the moment, use scheduled resource allocation + SL_CommConfig_r12_t *sl_CommConfig; + SL_CommResourcePool_r12_t *sc_CommTxConfig; + + sl_CommConfig = CALLOC(1, sizeof(struct SL_CommConfig_r12)); + sl_CommConfig->commTxResources_r12 = CALLOC(1, sizeof(*sl_CommConfig->commTxResources_r12)); + sl_CommConfig->commTxResources_r12->present = SL_CommConfig_r12__commTxResources_r12_PR_setup; + + sl_CommConfig->commTxResources_r12->choice.setup.present = SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size = 2; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf = CALLOC(1,2); + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[0] = 0x00; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[1] = 0x01;//ctxt_pP->rnti;//rnti + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.bits_unused = 0; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = CALLOC(1,sizeof(*sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12)); + //*sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = 12; //Msc + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL = RetxBSR_Timer_r12_sf320; //MacConfig, for testing only + //sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; + + sc_CommTxConfig = & sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; + + sc_CommTxConfig->sc_CP_Len_r12 = SL_CP_Len_r12_normal; + sc_CommTxConfig->sc_Period_r12 = SL_PeriodComm_r12_sf40; + sc_CommTxConfig->data_CP_Len_r12 = SL_CP_Len_r12_normal; + //sc_TF_ResourceConfig_r12 + sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_End_r12 = 44; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; + + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; + //dataHoppingConfig_r12 + sc_CommTxConfig->dataHoppingConfig_r12.hoppingParameter_r12 = 0; + sc_CommTxConfig->dataHoppingConfig_r12.numSubbands_r12 = SL_HoppingConfigComm_r12__numSubbands_r12_ns1; + sc_CommTxConfig->dataHoppingConfig_r12.rb_Offset_r12 = 0; + //ue_SelectedResourceConfig_r12 + sc_CommTxConfig->ue_SelectedResourceConfig_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->ue_SelectedResourceConfig_r12)); + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_End_r12 = 44; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0 ; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = 5; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = CALLOC(1,5); + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = 0; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[0] = 0xF0; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[1] = 0xFF; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[2] = 0xFF; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[3] = 0xFF; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[4] = 0xFF; + //rxParametersNCell_r12 + sc_CommTxConfig->rxParametersNCell_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12)); + sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 )); + sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->subframeAssignment = 0 ; + sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->specialSubframePatterns = 0; + sc_CommTxConfig->rxParametersNCell_r12->syncConfigIndex_r12 = 0; + //txParameters_r12 + sc_CommTxConfig->txParameters_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->txParameters_r12)); + sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.alpha_r12 = Alpha_r12_al0; + sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0; + sc_CommTxConfig->ext1 = NULL ; + + return *sl_CommConfig; +} + + +SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, int n_discoveryMessages ){ + //TODO + SL_DiscConfig_r12_t sl_DiscConfig; + sl_DiscConfig.discTxResources_r12 = CALLOC(1,sizeof(*sl_DiscConfig.discTxResources_r12)); + sl_DiscConfig.discTxResources_r12->present = SL_DiscConfig_r12__discTxResources_r12_PR_setup; + sl_DiscConfig.discTxResources_r12->choice.setup.present = SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12; + //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12; + //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12; + //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; + return sl_DiscConfig; +} +RRC_status_t +rrc_rx_tx( + protocol_ctxt_t* const ctxt_pP, + const int CC_id +) +//----------------------------------------------------------------------------- +{ + //uint8_t UE_id; + int32_t current_timestamp_ms, ref_timestamp_ms; + struct timeval ts; + struct rrc_eNB_ue_context_s *ue_context_p = NULL,*ue_to_be_removed = NULL; + +#ifdef LOCALIZATION + double estimated_distance; + protocol_ctxt_t ctxt; +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_IN); + + check_handovers(ctxt_pP); + // counetr, and get the value and aggregate + + // check for UL failure + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt_pP->rnti = ue_context_p->ue_id_rnti; + if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.ul_failure_timer); + } + else { + LOG_I(RRC,"UE rnti %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ul_failure_timer); + } + } + if (ue_context_p->ue_context.ul_failure_timer>0) { + ue_context_p->ue_context.ul_failure_timer++; + if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + // remove UE after 20 seconds after MAC has indicated UL failure + LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; + } + } + if (ue_context_p->ue_context.ue_release_timer_s1>0) { + ue_context_p->ue_context.ue_release_timer_s1++; + if (ue_context_p->ue_context.ue_release_timer_s1 >= + ue_context_p->ue_context.ue_release_timer_thres_s1) { + LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", + ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1); +// ue_context_p->ue_context.ue_release_timer_s1 = 0; +#if defined(ENABLE_USE_MME) +#if defined(ENABLE_ITTI) + rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); +#if 0 + { + int e_rab; + MessageDef *msg_delete_tunnels_p = NULL; + uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + // do not wait response + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context_p->ue_context.enb_gtp_ebi[e_rab]; + // erase data + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_S1AP_ENB, + NULL,0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + eNB_ue_s1ap_id); + + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids( + RC.rrc[ctxt_pP->module_id], + 0, + eNB_ue_s1ap_id); + if (NULL != rrc_ue_s1ap_ids) { + rrc_eNB_S1AP_remove_ue_ids( + RC.rrc[ctxt_pP->module_id], + rrc_ue_s1ap_ids); + } + } +#endif +#endif +#else + ue_to_be_removed = ue_context_p; +#endif + ue_context_p->ue_context.ue_release_timer_s1 = 0; + break; + } + } + + if (ue_context_p->ue_context.ue_release_timer_rrc>0) { + ue_context_p->ue_context.ue_release_timer_rrc++; + if (ue_context_p->ue_context.ue_release_timer_rrc >= + ue_context_p->ue_context.ue_release_timer_thres_rrc) { + LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_release_timer_rrc = 0; + break; + } + } + pthread_mutex_lock(&rrc_release_freelist); + if(rrc_release_info.num_UEs > 0){ + uint16_t release_total = 0; + for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ + if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ + release_total++; + } + if( (rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && + (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)){ + ue_context_p->ue_context.ue_release_timer_rrc = 1; + ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; +#if defined(ENABLE_USE_MME) +#if defined(ENABLE_ITTI) + int e_rab; + MessageDef *msg_complete_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; + uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; + if(rrc_release_info.RRC_release_ctrl[release_num].flag == 4){ + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_S1AP_ENB, + NULL,0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + eNB_ue_s1ap_id); + msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); + S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; + itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); + } + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + // do not wait response + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context_p->ue_context.enb_gtp_ebi[e_rab]; + // erase data + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids( + RC.rrc[ctxt_pP->module_id], + 0, + eNB_ue_s1ap_id); + if (NULL != rrc_ue_s1ap_ids) { + rrc_eNB_S1AP_remove_ue_ids( + RC.rrc[ctxt_pP->module_id], + rrc_ue_s1ap_ids); + } +#endif +#endif + rrc_release_info.RRC_release_ctrl[release_num].flag = 0; + rrc_release_info.num_UEs--; + break; + } + if(release_total >= rrc_release_info.num_UEs) + break; + } + } + pthread_mutex_unlock(&rrc_release_freelist); + + if (ue_context_p->ue_context.ue_reestablishment_timer>0) { + ue_context_p->ue_context.ue_reestablishment_timer++; + if (ue_context_p->ue_context.ue_reestablishment_timer >= + ue_context_p->ue_context.ue_reestablishment_timer_thres) { + LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + break; + } + } + + if (ue_context_p->ue_context.ue_release_timer>0) { + ue_context_p->ue_context.ue_release_timer++; + if (ue_context_p->ue_context.ue_release_timer >= + ue_context_p->ue_context.ue_release_timer_thres) { + LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_release_timer = 0; + break; + } + } + } + if (ue_to_be_removed) { + if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { + ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; + ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; + ue_to_be_removed->ue_context.ue_release_timer = 0; + ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; + } + rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed); + if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000){ + ue_to_be_removed->ue_context.ul_failure_timer = 0; + } + } + +#ifdef RRC_LOCALIZATION + + /* for the localization, only primary CC_id might be relevant*/ + gettimeofday(&ts, NULL); + current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; + ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt = *ctxt_pP; + ctxt.rnti = ue_context_p->ue_context.rnti; + estimated_distance = rrc_get_estimated_ue_distance( + &ctxt, + CC_id, + RC.rrc[ctxt_pP->module_id]->loc_type); + + if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && + estimated_distance != -1) { + LOG_D(LOCALIZE, " RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", + ctxt.rnti, + ctxt_pP->module_id, + current_timestamp_ms, + ctxt_pP->frame, + estimated_distance); + LOG_D(LOCALIZE, " RRC status %d\n", ue_context_p->ue_context.Status); + push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, + estimated_distance); + RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; + } + } + +#endif + (void)ts; /* remove gcc warning "unused variable" */ + (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ + (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); + return (RRC_OK); +} + diff --git a/openair2/RRC/LITE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c similarity index 97% rename from openair2/RRC/LITE/rrc_eNB_GTPV1U.c rename to openair2/RRC/LTE/rrc_eNB_GTPV1U.c index e5f2c5aaae1c469c4da1ffbcda1a41a0d7c264d4..135c6fea8d82e5279036ad7c11ae08df8d3d8683 100644 --- a/openair2/RRC/LITE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -28,9 +28,9 @@ */ #if defined(ENABLE_USE_MME) -# include "defs.h" -# include "extern.h" -# include "RRC/LITE/MESSAGES/asn1_msg.h" +# include "rrc_defs.h" +# include "rrc_extern.h" +# include "RRC/LTE/MESSAGES/asn1_msg.h" # include "rrc_eNB_GTPV1U.h" # include "rrc_eNB_UE_context.h" # include "msc.h" diff --git a/openair2/RRC/LITE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h similarity index 100% rename from openair2/RRC/LITE/rrc_eNB_GTPV1U.h rename to openair2/RRC/LTE/rrc_eNB_GTPV1U.h diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c similarity index 95% rename from openair2/RRC/LITE/rrc_eNB_S1AP.c rename to openair2/RRC/LTE/rrc_eNB_S1AP.c index 047a767fed8deaff2c1fc87a38b9d8eea0155883..59a2c352946f08fe93e3885149fc4bdfc9d7231d 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -27,13 +27,11 @@ * \company Eurecom * \email: navid.nikaein@eurecom.fr */ - #if defined(ENABLE_USE_MME) -# include "defs.h" -# include "extern.h" +# include "rrc_defs.h" +# include "rrc_extern.h" # include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -# include "RRC/LITE/MESSAGES/asn1_msg.h" -# include "RRC/LITE/defs.h" +# include "RRC/LTE/MESSAGES/asn1_msg.h" # include "rrc_eNB_UE_context.h" # include "rrc_eNB_S1AP.h" # include "enb_config.h" @@ -57,7 +55,11 @@ #include "UERadioAccessCapabilityInformation.h" #include "gtpv1u_eNB_task.h" -#include "RRC/LITE/rrc_eNB_GTPV1U.h" +#include "RRC/LTE/rrc_eNB_GTPV1U.h" + +#include "TLVDecoder.h" +#include "S1ap-NAS-PDU.h" +#include "flexran_agent_common_internal.h" extern RAN_CONTEXT_t RC; @@ -72,7 +74,7 @@ static const uint16_t S1AP_ENCRYPTION_EEA2_MASK = 0x4000; static const uint16_t S1AP_INTEGRITY_EIA1_MASK = 0x8000; static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x4000; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 2, 0)) # define INTEGRITY_ALGORITHM_NONE SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920 #else #ifdef EXMIMO_IOT @@ -82,8 +84,80 @@ static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x4000; #endif #endif +void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_context_pP) +{ + /* Process NAS message locally to get the IMSI */ + nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(nas_message_t)); + + int size = 0; + + nas_message_security_header_t *header = &nas_msg.header; + /* Decode the first octet of the header (security header type or EPS + * bearer identity, and protocol discriminator) */ + DECODE_U8((char *) pdu_buf, *(uint8_t*) (header), size); + + /* Decode NAS message only if decodable*/ + if (!(header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED + && header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE + && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE)) + return; + + if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { + /* Decode the message authentication code */ + DECODE_U32((char *) pdu_buf+size, header->message_authentication_code, size); + /* Decode the sequence number */ + DECODE_U8((char *) pdu_buf+size, header->sequence_number, size); + } + + /* Note: the value of the pointer (i.e. the address) is given by value, so we + * can modify it as we want. The callee retains the original address! */ + pdu_buf += size; + pdu_len -= size; + /* Decode plain NAS message */ + EMM_msg *e_msg = &nas_msg.plain.emm; + emm_msg_header_t *emm_header = &e_msg->header; + /* First decode the EMM message header */ + int e_head_size = 0; + + /* Check that buffer contains more than only the header */ + if (pdu_len <= sizeof(emm_msg_header_t)) + return; + + /* Decode the security header type and the protocol discriminator */ + DECODE_U8(pdu_buf + e_head_size, *(uint8_t *)(emm_header), e_head_size); + /* Decode the message type */ + DECODE_U8(pdu_buf + e_head_size, emm_header->message_type, e_head_size); + + /* Check that this is the right message */ + if (emm_header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) + return; + + pdu_buf += e_head_size; + pdu_len -= e_head_size; + + if (emm_header->message_type == IDENTITY_RESPONSE) { + decode_identity_response(&e_msg->identity_response, pdu_buf, pdu_len); + + if (e_msg->identity_response.mobileidentity.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { + memcpy(&ue_context_pP->ue_context.imsi, + &e_msg->identity_response.mobileidentity.imsi, + sizeof(ImsiMobileIdentity_t)); + } + } else if (emm_header->message_type == ATTACH_REQUEST) { + decode_attach_request(&e_msg->attach_request, pdu_buf, pdu_len); + + if (e_msg->attach_request.oldgutiorimsi.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { + /* the following is very dirty, we cast (implicitly) from + * ImsiEpsMobileIdentity_t to ImsiMobileIdentity_t*/ + memcpy(&ue_context_pP->ue_context.imsi, + &e_msg->attach_request.oldgutiorimsi.imsi, + sizeof(ImsiMobileIdentity_t)); + } + } +} # if defined(ENABLE_ITTI) //------------------------------------------------------------------------------ @@ -542,6 +616,10 @@ rrc_eNB_send_S1AP_UPLINK_NAS( S1AP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; + extract_imsi(S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer, + S1AP_UPLINK_NAS (msg_p).nas_pdu.length, + ue_context_pP); + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } } @@ -563,16 +641,17 @@ rrc_eNB_send_S1AP_UPLINK_NAS( &ulInformationTransfer->criticalExtensions.choice. c1.choice.ulInformationTransfer_r8; - if (ulInformationTransferR8->dedicatedInfoType. - present == - ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) + if (ulInformationTransferR8->dedicatedInfoType.present == + ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) { + + extract_imsi(ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size, + ue_context_pP); + s1ap_eNB_new_data_request (mod_id, ue_index, - ulInformationTransferR8-> - dedicatedInfoType.choice. - dedicatedInfoNAS.buf, - ulInformationTransferR8-> - dedicatedInfoType.choice. - dedicatedInfoNAS.size); + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size); + } } } } @@ -674,6 +753,10 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( rrcConnectionSetupComplete->dedicatedInfoNAS.buf; S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length = rrcConnectionSetupComplete->dedicatedInfoNAS.size; + extract_imsi(S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, + S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length, + ue_context_pP); + /* Fill UE identities with available information */ { S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask = UE_IDENTITIES_NONE; @@ -1912,7 +1995,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance /* insert data to UE_PF_PO or update data in UE_PF_PO */ pthread_mutex_lock(&ue_pf_po_mutex); uint8_t i = 0; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { /* set T = min(Tc,Tue) */ diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h similarity index 100% rename from openair2/RRC/LITE/rrc_eNB_S1AP.h rename to openair2/RRC/LTE/rrc_eNB_S1AP.h diff --git a/openair2/RRC/LITE/rrc_eNB_UE_context.c b/openair2/RRC/LTE/rrc_eNB_UE_context.c similarity index 100% rename from openair2/RRC/LITE/rrc_eNB_UE_context.c rename to openair2/RRC/LTE/rrc_eNB_UE_context.c diff --git a/openair2/RRC/LITE/rrc_eNB_UE_context.h b/openair2/RRC/LTE/rrc_eNB_UE_context.h similarity index 98% rename from openair2/RRC/LITE/rrc_eNB_UE_context.h rename to openair2/RRC/LTE/rrc_eNB_UE_context.h index 0e813cdee526819145296ff477ee620f39b00b1d..289b4d69d69275e75659a819a17b57d85fb2861c 100644 --- a/openair2/RRC/LITE/rrc_eNB_UE_context.h +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.h @@ -30,7 +30,7 @@ #ifndef __RRC_ENB_UE_CONTEXT_H__ #include "collection/tree.h" #include "COMMON/platform_types.h" -#include "defs.h" +#include "rrc_defs.h" void diff --git a/openair2/RRC/LITE/rrc_eNB_ral.c b/openair2/RRC/LTE/rrc_eNB_ral.c similarity index 100% rename from openair2/RRC/LITE/rrc_eNB_ral.c rename to openair2/RRC/LTE/rrc_eNB_ral.c diff --git a/openair2/RRC/LITE/rrc_eNB_ral.h b/openair2/RRC/LTE/rrc_eNB_ral.h similarity index 100% rename from openair2/RRC/LITE/rrc_eNB_ral.h rename to openair2/RRC/LTE/rrc_eNB_ral.h diff --git a/openair2/RRC/LITE/extern.h b/openair2/RRC/LTE/rrc_extern.h similarity index 88% rename from openair2/RRC/LITE/extern.h rename to openair2/RRC/LTE/rrc_extern.h index 71d8c9d0dcf8780dd91542ee1b5019ae12aa38d6..6c19fa9c7076202b934664657e2e9cc3c3c1508a 100644 --- a/openair2/RRC/LITE/extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -30,15 +30,13 @@ #ifndef __OPENAIR_RRC_EXTERN_H__ #define __OPENAIR_RRC_EXTERN_H__ -#include "defs.h" +#include "rrc_defs.h" #include "COMMON/mac_rrc_primitives.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" #include "LAYER2/RLC/rlc.h" extern UE_RRC_INST *UE_rrc_inst; -#include "LAYER2/MAC/extern.h" extern uint8_t DRB2LCHAN[8]; @@ -74,13 +72,13 @@ extern uint16_t N310[8]; extern uint16_t N311[8]; extern uint32_t T304[8]; extern uint32_t timeToTrigger_ms[16]; -extern float RSRP_meas_mapping[100]; -extern float RSRQ_meas_mapping[33]; +extern float RSRP_meas_mapping[98]; +extern float RSRQ_meas_mapping[35]; -extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; extern pthread_mutex_t ue_pf_po_mutex; -extern uint16_t reestablish_rnti_map[NUMBER_OF_UE_MAX][2]; +extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2]; #endif diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LTE/rrc_proto.h similarity index 78% rename from openair2/RRC/LITE/proto.h rename to openair2/RRC/LTE/rrc_proto.h index 063ab67e11d92df4d7caad456ce188fbb17c19dc..3cc774010d4a2eab75b3b90d26dbbff981433da5 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -25,13 +25,15 @@ * \date 2010 - 2014 * \email navid.nikaein@eurecom.fr * \version 1.0 - + */ /** \addtogroup _rrc * @{ */ -#include "RRC/LITE/defs.h" +#include "RRC/LTE/rrc_defs.h" + +#include "flexran_agent_extern.h" //main.c int rrc_init_global_param(void); @@ -54,15 +56,30 @@ void rrc_config_buffer(SRB_INFO *srb_info, uint8_t Lchan_type, uint8_t Role); void openair_rrc_on( const protocol_ctxt_t* const ctxt_pP); +void +openair_rrc_on_ue( + const protocol_ctxt_t* const ctxt_pP); + void rrc_top_cleanup(void); -/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310. +/** \brief Function to update eNB timers every subframe. @param ctxt_pP running context @param enb_index @param CC_id */ RRC_status_t rrc_rx_tx( + protocol_ctxt_t* const ctxt_pP, + const int CC_id +); + +/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310. +@param ctxt_pP running context +@param enb_index +@param CC_id +*/ +RRC_status_t +rrc_rx_tx_ue( protocol_ctxt_t* const ctxt_pP, const uint8_t enb_index, const int CC_id @@ -89,6 +106,14 @@ rrc_ue_decode_dcch( const uint8_t eNB_indexP ); +#ifdef Rel14 +int decode_SL_Discovery_Message( + const protocol_ctxt_t* const ctxt_pP, + const uint8_t eNB_index, + const uint8_t* Sdu, + const uint8_t Sdu_len); +#endif + /** \brief Generate/Encodes RRCConnnectionRequest message at UE \param ctxt_pP Running context \param eNB_index Index of corresponding eNB/CH*/ @@ -164,6 +189,28 @@ void rrc_ue_process_radioResourceConfigDedicated( uint8_t eNB_index, RadioResourceConfigDedicated_t *radioResourceConfigDedicated); + +/** \brief Process a RadioResourceConfig and configure PHY/MAC for SL communication/discovery + \param Mod_idP + \param eNB_index Index of corresponding CH/eNB + \param sib18 Pointer to SIB18 from SI message + \param sib19 Pointer to SIB19 from SI message + \param sl_CommConfig Pointer to SL_CommConfig RRCConnectionConfiguration + \param sl_DiscConfig Pointer to SL_DiscConfig RRCConnectionConfiguration */ +void rrc_ue_process_sidelink_radioResourceConfig( + module_id_t Mod_idP, + uint8_t eNB_index, + SystemInformationBlockType18_r12_t *sib18, + SystemInformationBlockType19_r12_t *sib19, + SL_CommConfig_r12_t* sl_CommConfig, + SL_DiscConfig_r12_t* sl_DiscConfig); + +/** \brief Init control socket to listen to incoming packets from ProSe App + * + */ +void rrc_control_socket_init(void); + + // eNB/CH RRC Procedures /**\brief Function to get the next transaction identifier. @@ -254,6 +301,15 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration( const uint8_t ho_state ); + +void +flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + const uint8_t ho_state, + agent_reconf_rrc * trig_param + ); + int freq_to_arfcn10(int band, unsigned long freq); void @@ -301,6 +357,54 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( const uint32_t nas_length ); +/**\brief Generate/decode the RRCConnectionReconfiguration for Sidelink at eNB + \param ctxt_pP Running context + \param ue_context_pP RRC UE context + \param destinationInfoList List of the destinations + \param n_discoveryMessages Number of discovery messages*/ +int +rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + SL_DestinationInfoList_r12_t *destinationInfoList, + int n_discoveryMessages +); + +/** \brief process the received SidelinkUEInformation message at eNB + \param ctxt_pP Running context + \param sidelinkUEInformation sidelinkUEInformation message from UE*/ +uint8_t +rrc_eNB_process_SidelinkUEInformation( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* ue_context_pP, + SidelinkUEInformation_r12_t* sidelinkUEInformation +); + +/** \brief Get a Resource Pool to transmit SL communication + \param ctxt_pP Running context + \param ue_context_pP UE context + \param destinationInfoList Pointer to the list of SL destinations*/ +SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + SL_DestinationInfoList_r12_t *destinationInfoList +); + +/** \brief Get a Resource Pool for Discovery + \param ctxt_pP Running context + \param ue_context_pP UE context + \param n_discoveryMessages Number of discovery messages*/ +SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + int n_discoveryMessages +); + +/** \brief Process request from control socket + * \param arg + */ +void *rrc_control_socket_thread_fct(void *arg); + //L2_interface.c int8_t mac_rrc_data_req( @@ -310,8 +414,6 @@ mac_rrc_data_req( const rb_id_t Srb_id, const uint8_t Nb_tb, uint8_t* const buffer_pP, - const eNB_flag_t enb_flagP, - const uint8_t eNB_index, const uint8_t mbsfn_sync_area ); @@ -325,15 +427,39 @@ mac_rrc_data_ind( const rb_id_t srb_idP, const uint8_t* sduP, const sdu_size_t sdu_lenP, - const eNB_flag_t eNB_flagP, + const uint8_t mbsfn_sync_areaP +); + +int8_t +mac_rrc_data_req_ue( + const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const rb_id_t Srb_id, + const uint8_t Nb_tb, + uint8_t* const buffer_pP, + const mac_enb_index_t eNB_indexP, + const uint8_t mbsfn_sync_area +); + +int8_t +mac_rrc_data_ind_ue( + const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const rnti_t rntiP, + const rb_id_t srb_idP, + const uint8_t* sduP, + const sdu_size_t sdu_lenP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP ); void mac_sync_ind( module_id_t Mod_instP, uint8_t status); -void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_id, +void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, + const int CC_id, const frame_t frameP, const sub_frame_t subframeP, const rnti_t rnti); @@ -361,6 +487,19 @@ rrc_data_req( const pdcp_transmission_mode_t modeP ); +uint8_t + +rrc_data_req_ue( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP +); + + void rrc_data_ind( const protocol_ctxt_t* const ctxt_pP, @@ -428,7 +567,7 @@ rrc_eNB_generate_SecurityModeCommand( void rrc_eNB_process_MeasurementReport( const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + rrc_eNB_ue_context_t* ue_context_pP, const MeasResults_t* const measResults2 ); diff --git a/openair2/RRC/LITE/rrc_rrm_interface.c b/openair2/RRC/LTE/rrc_rrm_interface.c similarity index 100% rename from openair2/RRC/LITE/rrc_rrm_interface.c rename to openair2/RRC/LTE/rrc_rrm_interface.c diff --git a/openair2/RRC/LITE/rrc_rrm_interface.h b/openair2/RRC/LTE/rrc_rrm_interface.h similarity index 100% rename from openair2/RRC/LITE/rrc_rrm_interface.h rename to openair2/RRC/LTE/rrc_rrm_interface.h diff --git a/openair2/RRC/LITE/rrc_types.h b/openair2/RRC/LTE/rrc_types.h similarity index 100% rename from openair2/RRC/LITE/rrc_types.h rename to openair2/RRC/LTE/rrc_types.h diff --git a/openair2/RRC/LTE/rrc_types_NB_IoT.h b/openair2/RRC/LTE/rrc_types_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..0266572cd01dd91fc327eadcd579c7b069e63592 --- /dev/null +++ b/openair2/RRC/LTE/rrc_types_NB_IoT.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 rrc_types.h +* \brief rrc types and subtypes +* \author Navid Nikaein and Raymond Knopp +* \date 2011 - 2014 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr +*/ + +#ifndef RRC_TYPES_NB_IOT_H_ +#define RRC_TYPES_NB_IOT_H_ + +typedef enum Rrc_State_NB_IoT_e { + RRC_STATE_INACTIVE_NB_IoT=0, + RRC_STATE_IDLE_NB_IoT, + RRC_STATE_CONNECTED_NB_IoT, + + RRC_STATE_FIRST_NB_IoT = RRC_STATE_INACTIVE_NB_IoT, + RRC_STATE_LAST_NB_IoT = RRC_STATE_CONNECTED_NB_IoT, +} Rrc_State_NB_IoT_t; + +typedef enum Rrc_Sub_State_NB_IoT_e { + RRC_SUB_STATE_INACTIVE_NB_IoT=0, + + RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT, + RRC_SUB_STATE_IDLE_RECEIVING_SIB_NB_IoT, + RRC_SUB_STATE_IDLE_SIB_COMPLETE_NB_IoT, + RRC_SUB_STATE_IDLE_CONNECTING_NB_IoT, + RRC_SUB_STATE_IDLE_NB_IoT, + + RRC_SUB_STATE_CONNECTED_NB_IoT, + + RRC_SUB_STATE_INACTIVE_FIRST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT, + RRC_SUB_STATE_INACTIVE_LAST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT, + + RRC_SUB_STATE_IDLE_FIRST_NB_IoT = RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT, + RRC_SUB_STATE_IDLE_LAST_NB_IoT = RRC_SUB_STATE_IDLE_NB_IoT, + + RRC_SUB_STATE_CONNECTED_FIRST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT, + RRC_SUB_STATE_CONNECTED_LAST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT, +} Rrc_Sub_State_NB_IoT_t; + +#endif /* RRC_TYPES_H_ */ diff --git a/openair2/RRC/LITE/vars.h b/openair2/RRC/LTE/rrc_vars.h similarity index 93% rename from openair2/RRC/LITE/vars.h rename to openair2/RRC/LTE/rrc_vars.h index e3bab5f5eb48aa577400a62d92d1397ab2ed25cf..8a718581014a8c9d87fbf5ccffa8c76b1e7db732 100644 --- a/openair2/RRC/LITE/vars.h +++ b/openair2/RRC/LTE/rrc_vars.h @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file vars.hles +/*! \file rrc_vars.h * \brief rrc variables * \author Raymond Knopp and Navid Nikaein * \date 2013 @@ -31,15 +31,15 @@ #ifndef __OPENAIR_RRC_VARS_H__ #define __OPENAIR_RRC_VARS_H__ -#include "defs.h" +#include "rrc_defs.h" #include "LAYER2/RLC/rlc.h" #include "COMMON/mac_rrc_primitives.h" -#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/mac.h" -UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; pthread_mutex_t ue_pf_po_mutex; UE_RRC_INST *UE_rrc_inst; -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac_extern.h" #define MAX_U32 0xFFFFFFFF uint8_t DRB2LCHAN[8]; @@ -59,7 +59,7 @@ struct LogicalChannelConfig__ul_SpecificParameters LCSRB2 = {3, }; -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) struct LogicalChannelConfig__ext1 logicalChannelSR_Mask_r9_ext1 = { logicalChannelSR_Mask_r9: &logicalChannelSR_Mask_r9 }; @@ -67,14 +67,14 @@ struct LogicalChannelConfig__ext1 logicalChannelSR_Mask_r9_ext1 = { // These are the default SRB configurations from 36.331 (Chapter 9, p. 176-179 in v8.6) LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB1 -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , ext1: &logicalChannelSR_Mask_r9_ext1 #endif }; LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB2 -#if defined(Rel10) || defined(Rel14) +#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , ext1: &logicalChannelSR_Mask_r9_ext1 #endif @@ -242,6 +242,6 @@ float RSRQ_meas_mapping[35] = { // [0]: current C-RNTI, [1]: prior C-RNTI // insert one when eNB received RRCConnectionReestablishmentRequest message // delete one when eNB received RRCConnectionReestablishmentComplete message -uint16_t reestablish_rnti_map[NUMBER_OF_UE_MAX][2] = {{0}}; +uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2] = {{0}}; #endif diff --git a/openair2/RRC/LITE/rrm_2_rrc_msg.c b/openair2/RRC/LTE/rrm_2_rrc_msg.c similarity index 100% rename from openair2/RRC/LITE/rrm_2_rrc_msg.c rename to openair2/RRC/LTE/rrm_2_rrc_msg.c diff --git a/openair2/RRC/LITE/utils.c b/openair2/RRC/LTE/utils.c similarity index 100% rename from openair2/RRC/LITE/utils.c rename to openair2/RRC/LTE/utils.c diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c index 1a3701ed5cc043ccb69b4c6c8a7b899158cb6409..b178d3a5d665d7d2864f762a2a39e3b7888cf2bd 100644 --- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c +++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c @@ -117,7 +117,7 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority) { return 0; } -message_queue_t destroy_message_queue(message_queue_t *queue) { +void destroy_message_queue(message_queue_t *queue) { struct lfds700_misc_prng_state ls; message_t *m; diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h index 185d23daf59d136e69c9293f9ffac722fb210047..04414cbbb2b9618379ad1284a056943e04539c23 100644 --- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h +++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h @@ -48,6 +48,6 @@ typedef struct { message_queue_t * new_message_queue(int size); int message_put(message_queue_t *queue, void *data, int size, int priority); int message_get(message_queue_t *queue, void **data, int *size, int *priority); -message_queue_t destroy_message_queue(message_queue_t *queue); +void destroy_message_queue(message_queue_t *queue); #endif /* RINGBUFFER_QUEUE_H */ diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index 579cd675c173a788596e9ba9b47ce4c049e4ed23..48e606522c61665a73c084f85e41bb6c929280d4 100644 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -34,6 +34,7 @@ #define COMPONENT_LOG #define COMPONENT_LOG_IF #include <ctype.h> +#define LOG_MAIN #include "log.h" #include "vcd_signal_dumper.h" #include "assertions.h" @@ -46,7 +47,7 @@ # include <string.h> #include "common/config/config_userapi.h" // main log variables -log_t *g_log; + typedef struct { char* buf_p; @@ -1692,7 +1693,7 @@ int set_log(int component, int level, int interval) component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, LOG_EMERG); - DevCheck((interval > 0) && (interval <= 0xFF), interval, 0, 0xFF); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); g_log->log_component[component].level = level; @@ -1726,7 +1727,7 @@ int set_comp_log(int component, int level, int verbosity, int interval) component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, LOG_EMERG); - DevCheck((interval > 0) && (interval <= 0xFF), interval, 0, 0xFF); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); #if 0 if ((verbosity == LOG_NONE) || (verbosity == LOG_LOW) || diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 120262c6218eb0b7055e8a5c5f8ec0340848d8d9..e47270c8cd0777a5828f2681e771d77f0189529f 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -258,6 +258,17 @@ void log_set_instance_type (log_instance_type_t instance); int logInit_log_mem(void); void output_log_mem(void); +#ifdef LOG_MAIN +log_t *g_log; +#else +#ifdef __cplusplus + extern "C" { +#endif +extern log_t *g_log; +#ifdef __cplusplus +} +#endif +#endif /*--- INCLUDES ---------------------------------------------------------------*/ # include "log_if.h" /*----------------------------------------------------------------------------*/ @@ -283,9 +294,9 @@ void *log_thread_function(void * list); * @brief Macro used to call tr_log_full_ex with file, function and line information * @{*/ #ifdef LOG_NO_THREAD -#define logIt(component, level, format, args...) logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) +#define logIt(component, level, format, args...) (g_log->log_component[component].interval?logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0) #else //default -#define logIt(component, level, format, args...) logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) +#define logIt(component, level, format, args...) (g_log->log_component[component].interval?logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0) #endif /* @}*/ @@ -367,9 +378,9 @@ void *log_thread_function(void * list); /* @}*/ static __inline__ uint64_t rdtsc(void) { - uint64_t a, d; + uint32_t a, d; __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); - return (d<<32) | a; + return (((uint64_t)d)<<32) | ((uint64_t)a); } #define DEBUG_REALTIME 1 diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c index b18d2a25ffd714c778e16a96a971db1e081694d9..a026cfb081a70e1ffd8ab833dd711c329b6ee33e 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.c +++ b/openair2/UTIL/LOG/vcd_signal_dumper.c @@ -191,6 +191,9 @@ const char* eurecomVariablesNames[] = { "ue0_trx_write_ns", "ue0_trx_read_ns_missing", "ue0_trx_write_ns_missing", + "enb_thread_rxtx_CPUID", + "ru_thread_CPUID", + "ru_thread_tx_CPUID" }; const char* eurecomFunctionsNames[] = { diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h index a4c8cd2476e08f0b234e47540b54b89b1d6b52fd..a47cdc059d1a8236b78255b28d457ad8979613e5 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.h +++ b/openair2/UTIL/LOG/vcd_signal_dumper.h @@ -167,6 +167,9 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING, VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING, + VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX, + VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD, + VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX, VCD_SIGNAL_DUMPER_VARIABLES_END } vcd_signal_dump_variables; diff --git a/openair2/UTIL/MEM/mem_block.c b/openair2/UTIL/MEM/mem_block.c index cfc8081a4b1a33f59e45df3c40d2b82aaa5ea082..6d1a289f08ea4ac93583a8fb910d6999ac565382 100644 --- a/openair2/UTIL/MEM/mem_block.c +++ b/openair2/UTIL/MEM/mem_block.c @@ -33,8 +33,8 @@ #include "mem_block.h" #include "mem_pool.h" #include "list.h" -#include "LAYER2/MAC/extern.h" - +#include "LAYER2/MAC/mac_extern.h" +#include "assertions.h" /* all function calls are protected by a mutex * to ensure that many threads calling them at * the same time don't mess up. diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index 855b7a99fdde30ef25bfb70c7c78c8a523104a2b..0495b139ce363e548346c83d9d22213ea32647e3 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -36,7 +36,7 @@ #ifndef __OCG_H__ #define __OCG_H__ -#include "PHY/defs.h" +#include "PHY/defs_common.h" #include "PHY/impl_defs_top.h" #include "platform_types.h" diff --git a/openair2/UTIL/OTG/otg_defs.h b/openair2/UTIL/OTG/otg_defs.h index fad0d9510ece3fc190b76889f819cb71aab4d080..6c9944014fd99f08e01e53f2ef4e4330446bf8e3 100644 --- a/openair2/UTIL/OTG/otg_defs.h +++ b/openair2/UTIL/OTG/otg_defs.h @@ -33,7 +33,7 @@ #ifndef __OTG_DEFS_H__ # define __OTG_DEFS_H__ -/* \brief To define the NUMBER_OF_eNB_MAX and NUMBER_OF_UE_MAX */ +/* \brief To define the NUMBER_OF_eNB_MAX and MAX_MOBILES_PER_ENB */ #if STANDALONE==1 #include "openairinterface5g_limits.h" #else @@ -313,13 +313,13 @@ typedef struct { /*this structure constitutes a whole bg-stream with multiple bg typedef struct { int application_type[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][MAX_NUM_APPLICATION]; /*!\brief It identify the application of the simulated traffic, could be cbr, m2m, gaming,etc*/ - int trans_proto[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - int ip_v[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + int trans_proto[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + int ip_v[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; - int flow_start[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief Duration of traffic generation or use the emuulation time instead */ - int flow_duration[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief Duration of traffic generation or use the emuulation time instead */ + int flow_start[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief Duration of traffic generation or use the emuulation time instead */ + int flow_duration[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief Duration of traffic generation or use the emuulation time instead */ - int idt_dist[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief Inter Departure Time distribution */ + int idt_dist[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief Inter Departure Time distribution */ int idt_min[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][MAX_NUM_APPLICATION]; /*!\brief Min Inter Departure Time, for uniform distrib */ int idt_max[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX][MAX_NUM_APPLICATION]; /*!\brief idt, Max Inter Departure Time, for uniform distrib */ @@ -338,69 +338,69 @@ typedef struct { */ typedef struct { int max_nb_frames; /*!< \brief Max Number of frames*/ - int application_type[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief It identify the application of the simulated traffic, could be cbr, m2m, gaming,etc*/ + int application_type[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief It identify the application of the simulated traffic, could be cbr, m2m, gaming,etc*/ /*!\header info */ - int trans_proto[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief Transport Protocol*/ - int ip_v[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief Ip version */ + int trans_proto[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief Transport Protocol*/ + int ip_v[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief Ip version */ //int header_compression; /*!\brief Specify if header compression is used or not */ int num_nodes; /*!\brief Number of used nodes in the simulation */ int packet_gen_type; /*!\brief define how the payload is generated: fixed, predefined, random position, random see ALPHABET_GEN */ - unsigned int background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief enable or disable background traffic */ - unsigned int aggregation_level[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /* define packet aggregation level for the case of gateway*/ + unsigned int background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief enable or disable background traffic */ + unsigned int aggregation_level[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /* define packet aggregation level for the case of gateway*/ // src id , dst id, and state // think to the case of several streams per node !!!!! - int idt_dist[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Inter Departure Time distribution */ - int idt_min[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Min Inter Departure Time, for uniform distrib */ - int idt_max[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief idt, Max Inter Departure Time, for uniform distrib */ + int idt_dist[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Inter Departure Time distribution */ + int idt_min[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Min Inter Departure Time, for uniform distrib */ + int idt_max[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief idt, Max Inter Departure Time, for uniform distrib */ - double idt_std_dev[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief idt, Standard Deviation, for guassian distrib */ - double idt_lambda[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief idt, lambda, for exponential/poisson distrib */ - double idt_scale[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief scale :parameter for Pareto, Gamma, Weibull and Cauchy distribution*/ - double idt_shape[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief shape :parameter for Pareto, Gamma, Weibull and Cauchy distribution*/ + double idt_std_dev[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief idt, Standard Deviation, for guassian distrib */ + double idt_lambda[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief idt, lambda, for exponential/poisson distrib */ + double idt_scale[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief scale :parameter for Pareto, Gamma, Weibull and Cauchy distribution*/ + double idt_shape[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief shape :parameter for Pareto, Gamma, Weibull and Cauchy distribution*/ - int size_dist[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Paylolad size distribution */ - int size_min[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Min Payload size, for uniform distrib */ - int size_max[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief payload, Max Inter Departure Time, for uniform distrib */ - double size_std_dev[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief payload, Standard Deviation, for guassian distrib */ - double size_lambda[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief payload, lambda, for exponential/poisson distrib */ + int size_dist[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Paylolad size distribution */ + int size_min[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief Min Payload size, for uniform distrib */ + int size_max[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief payload, Max Inter Departure Time, for uniform distrib */ + double size_std_dev[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief payload, Standard Deviation, for guassian distrib */ + double size_lambda[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief payload, lambda, for exponential/poisson distrib */ - double size_scale[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief scale :parameter for Pareto, Gamma, Weibull and Cauchy distribution */ - double size_shape[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief shape :parameter for Pareto, Gamma, Weibull and Cauchy distribution*/ + double size_scale[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief scale :parameter for Pareto, Gamma, Weibull and Cauchy distribution */ + double size_shape[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION][MAX_NUM_TRAFFIC_STATE]; /*!\brief shape :parameter for Pareto, Gamma, Weibull and Cauchy distribution*/ // info for state-based traffic gen - int num_state [NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!\brief Number of states for source node*/ - // int state_dist[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_TRAFFIC_STATE]; /*!\brief States distribution */ - double state_prob[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_TRAFFIC_STATE]; /*!\brief State probablity: prob to move from one state to the other one */ + int num_state [NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!\brief Number of states for source node*/ + // int state_dist[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_TRAFFIC_STATE]; /*!\brief States distribution */ + double state_prob[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_TRAFFIC_STATE]; /*!\brief State probablity: prob to move from one state to the other one */ // num stream for each src - // int stream [NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; // this requires multi thread for parallel stream for a givcen src + // int stream [NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; // this requires multi thread for parallel stream for a givcen src // emu info - int flow_start_flag[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief flow start time flag for traffic generation or use the emuulation time instead */ - int flow_start[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief flow start time of traffic generation or use the emuulation time instead */ - int flow_duration[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!\brief flow duration of traffic generation or use the emuulation time instead */ + int flow_start_flag[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief flow start time flag for traffic generation or use the emuulation time instead */ + int flow_start[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief flow start time of traffic generation or use the emuulation time instead */ + int flow_duration[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!\brief flow duration of traffic generation or use the emuulation time instead */ int seed; /*!\brief The seed used to generate the random positions*/ - int dst_port[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!\brief Destination port number, for the socket mode*/ - char *dst_ip[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!\brief Destination IP address, for the socket mode*/ + int dst_port[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!\brief Destination port number, for the socket mode*/ + char *dst_ip[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!\brief Destination IP address, for the socket mode*/ - int trans_proto_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!\brief define the transport protocol and IP version for background traffic*/ + int trans_proto_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!\brief define the transport protocol and IP version for background traffic*/ - double prob_off_pu[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - double prob_off_ed[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - double prob_off_pe[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - double prob_pu_ed[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - double prob_pu_pe[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - double prob_ed_pe[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - double prob_ed_pu[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int holding_time_off_ed[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int holding_time_off_pu[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int holding_time_off_pe[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int holding_time_pe_off[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int pu_size_pkts[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int ed_size_pkts[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int m2m[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + double prob_off_pu[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + double prob_off_ed[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + double prob_off_pe[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + double prob_pu_ed[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + double prob_pu_pe[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + double prob_ed_pe[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + double prob_ed_pu[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int holding_time_off_ed[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int holding_time_off_pu[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int holding_time_off_pe[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int holding_time_pe_off[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int pu_size_pkts[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int ed_size_pkts[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int m2m[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; unsigned int throughput_metric; @@ -409,7 +409,7 @@ typedef struct { unsigned int curve; unsigned int owd_radio_access; unsigned int background_stats; - unsigned int application_idx[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; + unsigned int application_idx[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; } otg_t; @@ -485,8 +485,8 @@ typedef struct { unsigned int rx_total_bytes_dl; /*TARMA parameteres*/ - tarmaStream_t *mtarma_stream[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - tarmaVideo_t *mtarma_video[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + tarmaStream_t *mtarma_stream[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + tarmaVideo_t *mtarma_video[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; } otg_multicast_info_t; @@ -505,71 +505,71 @@ typedef struct { int ctime; /*!< \brief Simulation time in ms*/ int ptime_background_ul; /*!< \brief time of last sent background UL data (time in ms)*/ int ptime_background_dl; /*!< \brief time of last sent background DL data (time in ms)*/ - int ptime[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!< \brief time of last sent data (time in ms)*/ - int seq_num[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief the sequence number of the sender */ - int seq_num_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief the sequence number for background traffic of the sender */ - int seq_num_rx[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief the sequence number of the receiver */ - int seq_num_rx_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief the sequence number for background traffic of the receiver */ + int ptime[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!< \brief time of last sent data (time in ms)*/ + int seq_num[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief the sequence number of the sender */ + int seq_num_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief the sequence number for background traffic of the sender */ + int seq_num_rx[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief the sequence number of the receiver */ + int seq_num_rx_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief the sequence number for background traffic of the receiver */ - int idt_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Inter Departure Time for background traffic in ms*/ - int size_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief payload size for background traffic*/ - int idt[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!< \brief Inter Departure Time in ms*/ - int header_type[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Define the type of header: Transport layer + IP version*/ + int idt_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Inter Departure Time for background traffic in ms*/ + int size_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief payload size for background traffic*/ + int idt[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!< \brief Inter Departure Time in ms*/ + int header_type[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Define the type of header: Transport layer + IP version*/ /*!< \brief Statics part: vars updated at each iteration of otg_tx */ - int tx_num_pkt[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packet in the tx*/ - int tx_num_bytes[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Number of bytes in the tx*/ // get the size and calculate the avg throughput + int tx_num_pkt[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packet in the tx*/ + int tx_num_bytes[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Number of bytes in the tx*/ // get the size and calculate the avg throughput // vars updated at each iteration of otg_rx - int rx_num_pkt[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packet in the rx */ - int rx_num_bytes[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Number of bytes in the rx */ - float rx_pkt_owd[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief One way delay: rx_ctime - tx_ctime, */ - float rx_owd_min[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ - float rx_owd_max[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ - float rx_pkt_owd_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief One way delay: rx_ctime - tx_ctime, */ - float rx_owd_min_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ - float rx_owd_max_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ - float rx_pkt_owd_history[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][2]; /*!< \brief One way delay histoy used for jitter calculation: rx_ctime - tx_ctime, [2] to keep the owd for the current and previous pkt */ - float rx_pkt_owd_history_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][2]; /*!< \brief One way delay histoy used for jitter calculation: rx_ctime - tx_ctime, [2] to keep the owd for the current and previous pkt */ - float rx_pkt_jitter[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief One way delay: rx_ctime - tx_ctime */ - float rx_jitter_min[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ - float rx_jitter_max[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ - float rx_jitter_avg[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ - float rx_pkt_jitter_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief One way delay: rx_ctime - tx_ctime */ - float rx_jitter_min_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ - float rx_jitter_max_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ - float rx_jitter_avg_e2e[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ - int rx_jitter_sample[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ - int nb_loss_pkts_ul[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packets losses for UL*/ - int nb_loss_pkts_dl[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packets losses for DL*/ - float owd_const[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!< \brief One way delay constant*/ + int rx_num_pkt[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packet in the rx */ + int rx_num_bytes[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Number of bytes in the rx */ + float rx_pkt_owd[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief One way delay: rx_ctime - tx_ctime, */ + float rx_owd_min[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ + float rx_owd_max[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ + float rx_pkt_owd_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief One way delay: rx_ctime - tx_ctime, */ + float rx_owd_min_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ + float rx_owd_max_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ + float rx_pkt_owd_history[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][2]; /*!< \brief One way delay histoy used for jitter calculation: rx_ctime - tx_ctime, [2] to keep the owd for the current and previous pkt */ + float rx_pkt_owd_history_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][2]; /*!< \brief One way delay histoy used for jitter calculation: rx_ctime - tx_ctime, [2] to keep the owd for the current and previous pkt */ + float rx_pkt_jitter[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief One way delay: rx_ctime - tx_ctime */ + float rx_jitter_min[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ + float rx_jitter_max[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ + float rx_jitter_avg[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ + float rx_pkt_jitter_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief One way delay: rx_ctime - tx_ctime */ + float rx_jitter_min_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay min*/ + float rx_jitter_max_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ + float rx_jitter_avg_e2e[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ + int rx_jitter_sample[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief One way delay max*/ + int nb_loss_pkts_ul[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packets losses for UL*/ + int nb_loss_pkts_dl[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Number of data packets losses for DL*/ + float owd_const[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!< \brief One way delay constant*/ /*!< \brief KPI part: calculate the KPIs, total */ - double tx_throughput[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Tx throughput: (size of transmitted data)/ctime*/ - double rx_goodput[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Rx goodput: (size of received data)/ctime*/ - float rx_loss_rate[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_EMU_TRAFFIC]; /*!< \brief Rx Loss Rate: ratio, unit: bytes*/ - //int rx_latency[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Rx Latency */ + double tx_throughput[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Tx throughput: (size of transmitted data)/ctime*/ + double rx_goodput[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Rx goodput: (size of received data)/ctime*/ + float rx_loss_rate[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_EMU_TRAFFIC]; /*!< \brief Rx Loss Rate: ratio, unit: bytes*/ + //int rx_latency[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Rx Latency */ /*!< \brief Background traffic part: SATS + KPIs */ - int tx_num_pkt_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Number of background data packet in the rx */ - int tx_num_bytes_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Number of background bytes in the rx */ - int rx_num_pkt_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Number of background data packet in the tx */ - int rx_num_bytes_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Number of background bytes in the tx */ - int nb_loss_pkts_background_ul[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Number of background packets losses for UL*/ - int nb_loss_pkts_background_dl[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Number of background packets losses for DL*/ - double tx_throughput_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Tx throughput: (size of transmitted data)/ctime*/ - double rx_goodput_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Rx goodput: (size of received data)/ctime*/ - float rx_loss_rate_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; /*!< \brief Rx Loss Rate: ratio, unit: bytes*/ - - float radio_access_delay[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - int nb_loss_pkts_otg[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - unsigned int aggregation_level[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - - unsigned int state[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; /*!< \brief current state of src node */ - float state_transition_prob[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int start_holding_time_off[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int c_holding_time_off[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int c_holding_time_pe_off[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int start_holding_time_pe_off[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + int tx_num_pkt_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Number of background data packet in the rx */ + int tx_num_bytes_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Number of background bytes in the rx */ + int rx_num_pkt_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Number of background data packet in the tx */ + int rx_num_bytes_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Number of background bytes in the tx */ + int nb_loss_pkts_background_ul[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Number of background packets losses for UL*/ + int nb_loss_pkts_background_dl[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Number of background packets losses for DL*/ + double tx_throughput_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Tx throughput: (size of transmitted data)/ctime*/ + double rx_goodput_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Rx goodput: (size of received data)/ctime*/ + float rx_loss_rate_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; /*!< \brief Rx Loss Rate: ratio, unit: bytes*/ + + float radio_access_delay[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + int nb_loss_pkts_otg[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + unsigned int aggregation_level[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + + unsigned int state[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*!< \brief current state of src node */ + float state_transition_prob[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int start_holding_time_off[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int c_holding_time_off[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int c_holding_time_pe_off[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int start_holding_time_pe_off[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; unsigned int tx_total_bytes_dl; unsigned int tx_total_bytes_ul; unsigned int rx_total_bytes_dl; @@ -582,32 +582,32 @@ typedef struct { float average_jitter_ul_e2e; /* VOIP tarffic parameters*/ - float voip_transition_prob[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int voip_state[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int start_voip_silence[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int c_holding_time_silence[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int start_voip_talk[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int c_holding_time_talk[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int silence_time[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int simple_talk_time[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + float voip_transition_prob[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int voip_state[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int start_voip_silence[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int c_holding_time_silence[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int start_voip_talk[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int c_holding_time_talk[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int silence_time[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int simple_talk_time[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*TARMA parameteres*/ - tarmaStream_t *tarma_stream[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - tarmaVideo_t *tarma_video[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; + tarmaStream_t *tarma_stream[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + tarmaVideo_t *tarma_video[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; /*BACKGROUND_USERS parameters*/ - backgroundStream_t *background_stream[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - - unsigned int header_size_app[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; - unsigned int header_size[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - unsigned int m2m_aggregation[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - unsigned int flow_id[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - unsigned int traffic_type[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - unsigned int traffic_type_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; + backgroundStream_t *background_stream[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + + unsigned int header_size_app[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; + unsigned int header_size[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + unsigned int m2m_aggregation[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + unsigned int flow_id[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + unsigned int traffic_type[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + unsigned int traffic_type_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; // unsigned int traffic_type_multicast[NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_SERVICE_MAX]; - unsigned int hdr_size[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - unsigned int header_type_app[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_NUM_APPLICATION]; ; + unsigned int hdr_size[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + unsigned int header_type_app[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_NUM_APPLICATION]; ; unsigned int gen_pkts; - unsigned int header_size_background[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; + unsigned int header_size_background[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; } otg_info_t; @@ -640,14 +640,14 @@ typedef struct { int init_forms; int is_data_plot_ul; int is_data_plot_dl; - float data_owd_ul[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_SAMPLES]; - float data_throughput_ul[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_SAMPLES]; - float data_ctime_ul[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_SAMPLES]; - int idx_ul[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; - float data_owd_dl[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_SAMPLES]; - float data_throughput_dl[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_SAMPLES]; - float data_ctime_dl[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][MAX_SAMPLES]; - int idx_dl[NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX]; + float data_owd_ul[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_SAMPLES]; + float data_throughput_ul[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_SAMPLES]; + float data_ctime_ul[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_SAMPLES]; + int idx_ul[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; + float data_owd_dl[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_SAMPLES]; + float data_throughput_dl[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_SAMPLES]; + float data_ctime_dl[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][MAX_SAMPLES]; + int idx_dl[NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB][NUMBER_OF_eNB_MAX + MAX_MOBILES_PER_ENB]; } otg_forms_info_t; diff --git a/openair2/X2AP/x2ap.c b/openair2/X2AP/x2ap.c index bde21c0dbe1e57cc0d5abeac07d3f5a9b2e8fc8d..8002867e15c31c8b78ada0894c9bbef20ae2cef1 100644 --- a/openair2/X2AP/x2ap.c +++ b/openair2/X2AP/x2ap.c @@ -49,6 +49,7 @@ void *x2ap_task(void *arg) switch (ITTI_MSG_ID(received_msg)) { case TERMINATE_MESSAGE: + X2AP_WARN(" *** Exiting X2AP thread\n"); itti_exit_task(); break; diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 4234bc373d70a725414c60706b97aa9b5bbe63ea..784245c0d36cb1ef4e1902af160fb3bf4a9fab2e 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -53,6 +53,7 @@ #undef GTP_DUMP_SOCKET +/* extern boolean_t pdcp_data_req( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, @@ -61,8 +62,15 @@ extern boolean_t pdcp_data_req( const confirm_t confirmP, const sdu_size_t sdu_buffer_sizeP, unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP); + const pdcp_transmission_mode_t modeP +#ifdef Rel14 + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + ); + const pdcp_transmission_mode_t modeP); +*/ extern unsigned char NB_eNB_INST; extern RAN_CONTEXT_t RC; @@ -289,6 +297,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL; protocol_ctxt_t ctxt; + NwGtpv1uRcT rc; switch(pUlpApi->apiType) { /* Here there are two type of messages handled: @@ -313,6 +322,12 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( gtpv1u_eNB_write_dump_socket(buffer,buffer_len); #endif + rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, + pUlpApi->apiInfo.recvMsgInfo.hMsg); + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); + } + //----------------------- // GTPV1U->PDCP mapping //----------------------- @@ -347,7 +362,11 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( SDU_CONFIRM_NO, // confirm buffer_len, buffer, - PDCP_TRANSMISSION_MODE_DATA); + PDCP_TRANSMISSION_MODE_DATA +#ifdef Rel14 + ,NULL, NULL +#endif + ); if ( result == FALSE ) { @@ -1219,6 +1238,7 @@ void *gtpv1u_eNB_task(void *args) hashtable_destroy (RC.gtpv1u_data_g->teid_mapping); } + LOG_W(GTPU, " *** Exiting GTPU thread\n"); itti_exit_task(); } break; diff --git a/openair3/GTPV1-U/gtpv1u_task.c b/openair3/GTPV1-U/gtpv1u_task.c index a6dd6fa06151ae08e6373e5d78d9005bbd37db6d..287c22b7e7ab28d162f6b36815b11eb14b629588 100644 --- a/openair3/GTPV1-U/gtpv1u_task.c +++ b/openair3/GTPV1-U/gtpv1u_task.c @@ -423,6 +423,7 @@ static void *gtpv1u_thread(void *args) switch (ITTI_MSG_ID(received_message_p)) { case TERMINATE_MESSAGE: { + GTPU_WARN(" *** Exiting GTPU thread\n"); itti_exit_task(); } break; diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h index 003bdd2d62345371bf57fb520bf4ce545330bafb..a327e18b02a61fbd0893f2219da33edd99d4f4ed 100644 --- a/openair3/S1AP/s1ap_common.h +++ b/openair3/S1AP/s1ap_common.h @@ -333,7 +333,7 @@ inline void ASN_DEBUG(const char *fmt, ...); #include "S1ap-IE.h" #include "S1AP-PDU.h" -#if defined (UPDATE_RELEASE_9) +#if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) # include "S1ap-BroadcastCancelledAreaList.h" # include "S1ap-CancelledCellinEAI.h" # include "S1ap-CancelledCellinEAI-Item.h" @@ -364,9 +364,9 @@ inline void ASN_DEBUG(const char *fmt, ...); # include "S1ap-UplinkUEAssociatedLPPaTransport.h" # include "S1ap-DownlinkNonUEAssociatedLPPaTransport.h" # include "S1ap-UplinkNonUEAssociatedLPPaTransport.h" -#endif /* (UPDATE_RELEASE_9) */ +#endif /* #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) */ -#if defined(UPDATE_RELEASE_10) +#if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) # include "S1ap-PagingPriority.h" # include "S1ap-RelayNode-Indicator.h" # include "S1ap-GWContextReleaseIndication.h" @@ -375,7 +375,7 @@ inline void ASN_DEBUG(const char *fmt, ...); # include "S1ap-PrivacyIndicator.h" # include "S1ap-TrafficLoadReductionIndication.h" # include "S1ap-GUMMEIList.h" -#endif /* (UPDATE_RELEASE_10) */ +#endif /* #if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) */ /* Checking version of ASN1C compiler */ #if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 301df6e81600fdff0e6f3ffae37e69e2d8d13019..8085c239c304d85cdefeb6671fe57b3e2561c18c 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -307,6 +307,7 @@ void *s1ap_eNB_task(void *arg) switch (ITTI_MSG_ID(received_msg)) { case TERMINATE_MESSAGE: + S1AP_WARN(" *** Exiting S1AP thread\n"); itti_exit_task(); break; diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c index eac52c53ba6fc52cf13340267630a41d1de68c8c..447ca2c81bf2ece7a4032ff63cdc9721dea968e1 100644 --- a/openair3/S1AP/s1ap_eNB_decoder.c +++ b/openair3/S1AP/s1ap_eNB_decoder.c @@ -168,6 +168,22 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message, S1AP_INFO("TODO E_RABRelease nitiating message\n"); break; + case S1ap_ProcedureCode_id_ErrorIndication: + ret = s1ap_decode_s1ap_errorindicationies( + &message->msg.s1ap_ErrorIndicationIEs, &initiating_p->value); + s1ap_xer_print_s1ap_errorindication(s1ap_xer__print2sp, message_string, message); + message_id = S1AP_E_RAB_ERROR_INDICATION_LOG; + message_string_size = strlen(message_string); + message_p = itti_alloc_new_message_sized(TASK_S1AP, + message_id, + message_string_size + sizeof (IttiMsgText)); + message_p->ittiMsg.s1ap_e_rab_release_request_log.size = message_string_size; + memcpy(&message_p->ittiMsg.s1ap_error_indication_log.text, message_string, message_string_size); + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + free(message_string); + S1AP_INFO("ErrorIndication initiating message\n"); + break; + default: S1AP_ERROR("Unknown procedure ID (%d) for initiating message\n", (int)initiating_p->procedureCode); diff --git a/openair3/S1AP/s1ap_eNB_encoder.c b/openair3/S1AP/s1ap_eNB_encoder.c index 9a5f422158dc592d685935d01bdbff06c17095c0..7bd8bc09aabf6165dffe649bc2700678fd90a03b 100644 --- a/openair3/S1AP/s1ap_eNB_encoder.c +++ b/openair3/S1AP/s1ap_eNB_encoder.c @@ -470,7 +470,7 @@ int s1ap_eNB_encode_initial_ue_message( return s1ap_generate_initiating_message(buffer, length, S1ap_ProcedureCode_id_initialUEMessage, - S1ap_Criticality_reject, + S1ap_Criticality_ignore, &asn_DEF_S1ap_InitialUEMessage, initialUEMessage_p); } diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 0b02fc6db9ee4c0580ec108bdeb50bd162372d52..ab5f93a16d8883b7b49f66043f82212837b3607b 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -141,7 +141,7 @@ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* eNBConfigurationTransfer */ { 0, 0, 0 }, /* MMEConfigurationTransfer */ { 0, 0, 0 }, /* CellTrafficTrace */ -#if defined(UPDATE_RELEASE_9) +#if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) { 0, 0, 0 }, /* Kill */ { 0, 0, 0 }, /* DownlinkUEAssociatedLPPaTransport */ { 0, 0, 0 }, /* UplinkUEAssociatedLPPaTransport */ diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 7771cab712f22b747f7dbc451e98c01495250004..256bee0cd12ecca1d8c8cd28a42f105e745da12d 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -841,6 +841,7 @@ void *sctp_eNB_task(void *arg) break; case TERMINATE_MESSAGE: + SCTP_WARN("*** Exiting SCTP thread\n"); itti_exit_task(); break; diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index f10126d5b55928aaba1641fc24c606e1e4fabf32..95df0fc306c0bf2ee72ca6275da11363166f693e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -1089,6 +1089,7 @@ void *et_s1ap_eNB_task(void *arg) switch (ITTI_MSG_ID(received_msg)) { case TERMINATE_MESSAGE: + S1AP_WARN("*** Exiting S1AP thread\n"); itti_exit_task(); break; diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index 868d86ad9cec84dcb97a55749ce8131256b296ca..4d6bd6e033a45417a2044e2cfb39ffff3ac8d1c8 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -270,10 +270,21 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP) n, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); #endif - if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { + /* TODO: this is a hack. Let's accept failures and do nothing when + * it happens. Since itti_send_msg_to_task crashes when the message + * queue is full we wrote itti_try_send_msg_to_task that returns -1 + * if the queue is full. + */ + /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ + //if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { + if (itti_try_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { +#if 0 LOG_I(UDP_, "Failed to send message %d to task %d\n", UDP_DATA_IND, udp_sock_pP->task_id); +#endif + itti_free(TASK_UDP, message_p); + itti_free(TASK_UDP, forwarded_buffer); return; } } @@ -389,7 +400,7 @@ void *udp_eNB_task(void *args_p) break; case TERMINATE_MESSAGE: { - LOG_W(UDP_, "Received TERMINATE_MESSAGE\n"); + LOG_W(UDP_, " *** Exiting UDP thread\n"); itti_exit_task(); } break; diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index eb9f80872e0093ec237ff34a3064cc8c332e8d95..7ff3b820dca5e121f585bd3b9c5a5827ddea1e95 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -36,6 +36,7 @@ #include <string.h> #include "common_lib.h" +#include "common/utils/load_module_shlib.h" int set_device(openair0_device *device) { @@ -85,52 +86,26 @@ int set_transport(openair0_device *device) { } } - +typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *); /* look for the interface library and load it */ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) { - void *lib_handle; - oai_device_initfunc_t dp ; - oai_transport_initfunc_t tp ; + loader_shlibfunc_t shlib_fdesc[1]; int ret=0; - + char *libname; if (flag == RAU_LOCAL_RADIO_HEAD) { - lib_handle = dlopen(OAI_RF_LIBNAME, RTLD_LAZY); - if (!lib_handle) { - fprintf(stderr,"Unable to locate %s: HW device set to NONE_DEV.\n", OAI_RF_LIBNAME); - fprintf(stderr,"%s\n",dlerror()); - return -1; - } - - dp = dlsym(lib_handle,"device_init"); - - if (dp != NULL ) { - ret = dp(device,openair0_cfg); - if (ret<0) { - fprintf(stderr, "%s %d:oai device intialization failed %s\n", __FILE__, __LINE__, dlerror()); - } - } else { - fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); - return -1; - } + libname=OAI_RF_LIBNAME; + shlib_fdesc[0].fname="device_init"; } else { - lib_handle = dlopen(OAI_TP_LIBNAME, RTLD_LAZY); - if (!lib_handle) { - printf( "Unable to locate %s: transport protocol set to NONE_TP.\n", OAI_TP_LIBNAME); - printf( "%s\n",dlerror()); - return -1; - } - - tp = dlsym(lib_handle,"transport_init"); - - if (tp != NULL ) { - tp(device,openair0_cfg,cfg); - } else { - fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); - return -1; - } + libname=OAI_TP_LIBNAME; + shlib_fdesc[0].fname="transport_init"; } - + ret=load_module_shlib(libname,shlib_fdesc,1); + if (ret < 0) { + fprintf(stderr,"Library %s couldn't be loaded\n",libname); + } else { + ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); + } return ret; } @@ -142,7 +117,7 @@ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cf rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD ); if ( rc >= 0) { - if ( set_device(device) < 0) { + if ( set_device(device) < 0) { fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); return -1; } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 2dc1650bfd719208ef5e182b0b79f76e5f12ff55..433e29e97db7b15322b51d8f3282daa91b922c09 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -36,9 +36,9 @@ #include <sys/types.h> /* name of shared library implementing the radio front end */ -#define OAI_RF_LIBNAME "liboai_device.so" +#define OAI_RF_LIBNAME "oai_device" /* name of shared library implementing the transport */ -#define OAI_TP_LIBNAME "liboai_transpro.so" +#define OAI_TP_LIBNAME "oai_transpro" /* flags for BBU to determine whether the attached radio head is local or remote */ #define RAU_LOCAL_RADIO_HEAD 0 diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 3e58f281b4396acd8b0ac2b52aab10b4c87de55d..d704b9604ca75d05aa97d92c23a48e0e5724b9fa 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -987,15 +987,20 @@ extern "C" { // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); -// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; uhd::device_addrs_t device_adds = uhd::device::find(args); if(device_adds.size() == 0) { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; + args += ",addr=192.168.30.2"; + + uhd::device_addrs_t device_adds = uhd::device::find(args); + + if(device_adds.size() == 0) { + + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } } LOG_I(PHY,"Found USRP X300\n"); s->usrp = uhd::usrp::multi_usrp::make(args); @@ -1021,6 +1026,20 @@ extern "C" { LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); switch ((int)openair0_cfg[0].sample_rate) { + case 122880000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; //to be checked + openair0_cfg[0].tx_bw = 80e6; + openair0_cfg[0].rx_bw = 80e6; + break; + case 61440000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 40e6; + openair0_cfg[0].rx_bw = 40e6; + break; case 30720000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; diff --git a/targets/ARCH/tcp_bridge/README.tcp_bridge_oai b/targets/ARCH/tcp_bridge/README.tcp_bridge_oai new file mode 100644 index 0000000000000000000000000000000000000000..ef0588ddee4fecf4a765a2b42b18fb047c2df96a --- /dev/null +++ b/targets/ARCH/tcp_bridge/README.tcp_bridge_oai @@ -0,0 +1,41 @@ +The driver tcp_bridge_oai.c is to be used with the basic simulator. + +To build the basic simulator: + cd [openair top directory] + . oaienv + cd cmake_targets + ./build_oai --basic-simulator + cd ../common/utils/T/tracer + make + +To use it, you need to run the eNB and the UE. + +The eNB requires the T tracer. +Open two terminals. +In one terminal, run: + cd [openair top directory] + cd common/utils/T/tracer + ./enb -d ../T_messages.txt +In the other terminal, run: + cd [openair top directory] + cd cmake_targets/basic_simulator/enb + export ENODEB=1 + sudo -E ./lte-softmodem -O [configuration file] +[configuration file] is just a regular configuration file. +The eNB needs an EPC. + +To run the UE, open a terminal and run: + cd [openair top directory] + cd cmake_targets/basic_simulator/ue + sudo ./lte-uesoftmodem -C 2680000000 -r 25 +Adapt the value of -r, it has to match the value N_RB_DL in the configuration +file of the eNB. (Same for -C which should match the value downlink_frequency +in the configuration file.) + +The UE configuration (security keys) is generated from the file +openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf. You need to configure +your EPC to know about the UE. If you change the file +openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf then you need to +regenerate the configuration files using the program targets/bin/conf2uedata. +You run it as: + $OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o $OPENAIR_DIR/cmake_targets/basic_simulator/ue diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c new file mode 100644 index 0000000000000000000000000000000000000000..ba6d96db93372c3407d0d1c41ff666e3a2a85606 --- /dev/null +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -0,0 +1,320 @@ +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +int fullread(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) return -1; + count -= l; + buf += l; + ret += l; + } + return ret; +} + +int fullwrite(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = write(fd, buf, count); + if (l <= 0) return -1; + count -= l; + buf += l; + ret += l; + } + return ret; +} + +#include "common_lib.h" + +typedef struct { + int sock; + int samples_per_subframe; + uint64_t timestamp; + int is_enb; +} tcp_bridge_state_t; + +void verify_connection(int fd, int is_enb) +{ + char c = is_enb; + if (fullwrite(fd, &c, 1) != 1) exit(1); + if (fullread(fd, &c, 1) != 1) exit(1); + if (c == is_enb) { + printf("\x1b[31mtcp_bridge: error: you have to run one UE and one eNB" + " (did you run 'export ENODEB=1' in the eNB terminal?)\x1b[m\n"); + exit(1); + } +} + +int tcp_bridge_start(openair0_device *device) +{ + int port = 4043; + tcp_bridge_state_t *tcp_bridge = device->priv; + int try; + int max_try = 5; + + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { perror("tcp_bridge: socket"); exit(1); } + + int enable = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) + { perror("tcp_bridge: SO_REUSEADDR"); exit(1); } + + struct sockaddr_in addr = { + sin_family: AF_INET, + sin_port: htons(port), + sin_addr: { s_addr: INADDR_ANY } + }; + + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) { + if (errno == EADDRINUSE) goto client_mode; + { perror("tcp_bridge: bind"); exit(1); } + } + + if (listen(sock, 5)) + { perror("tcp_bridge: listen"); exit(1); } + + printf("tcp_bridge: wait for connection on port %d\n", port); + + socklen_t len = sizeof(addr); + int sock2 = accept(sock, (struct sockaddr *)&addr, &len); + if (sock2 == -1) + { perror("tcp_bridge: accept"); exit(1); } + + close(sock); + + tcp_bridge->sock = sock2; + + printf("tcp_bridge: connection established\n"); + + verify_connection(sock2, tcp_bridge->is_enb); + + return 0; + +client_mode: + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + for (try = 0; try < max_try; try++) { + if (try != 0) sleep(1); + + printf("tcp_bridge: trying to connect to 127.0.0.1:%d (attempt %d/%d)\n", + port, try+1, max_try); + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + printf("tcp_bridge: connection established\n"); + tcp_bridge->sock = sock; + verify_connection(sock, tcp_bridge->is_enb); + return 0; + } + + perror("tcp_bridge"); + } + + printf("tcp_bridge: connection failed\n"); + + exit(1); +} + +int tcp_bridge_request(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; } +int tcp_bridge_reply(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; } +int tcp_bridge_get_stats(openair0_device* device) { return 0; } +int tcp_bridge_reset_stats(openair0_device* device) { return 0; } +void tcp_bridge_end(openair0_device *device) {} +int tcp_bridge_stop(openair0_device *device) { return 0; } +int tcp_bridge_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; } +int tcp_bridge_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { return 0; } + +int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) +{ + if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } + tcp_bridge_state_t *t = device->priv; + int n = fullwrite(t->sock, buff[0], nsamps * 4); + if (n != nsamps * 4) { + printf("tcp_bridge: write error ret %d (wanted %d) error %s\n", n, nsamps*4, strerror(errno)); + abort(); + } + return nsamps; +} + +int tcp_bridge_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) +{ + if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } + tcp_bridge_state_t *t = device->priv; + int n = fullread(t->sock, buff[0], nsamps * 4); + if (n != nsamps * 4) { + printf("tcp_bridge: read error ret %d nsamps*4 %d error %s\n", n, nsamps * 4, strerror(errno)); + abort(); + } + *timestamp = t->timestamp; + t->timestamp += nsamps; + return nsamps; +} + +int tcp_bridge_read_ue(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) +{ + if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } + tcp_bridge_state_t *t = device->priv; + int n; + + /* In synch mode, UE does not write, but we need to + * send something to the eNodeB. + * We know that UE is in synch mode when it reads + * 10 subframes at a time. + */ + if (nsamps == t->samples_per_subframe * 10) { + uint32_t b[nsamps]; + memset(b, 0, nsamps * 4); + n = fullwrite(t->sock, b, nsamps * 4); + if (n != nsamps * 4) { + printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); + abort(); + } + } + + return tcp_bridge_read(device, timestamp, buff, nsamps, cc); +} + +/* To startup proper communcation between eNB and UE, + * we need to understand that: + * - eNodeB starts reading subframe 0 + * - then eNodeB starts sending subframe 4 + * and then repeats read/write for each subframe. + * The UE: + * - reads 10 subframes at a time until it is synchronized + * - then reads subframe n and writes subframe n+2 + * We also want to enforce that the subframe 0 is read + * at the beginning of the UE RX buffer, not in the middle + * of it. + * So it means: + * - for the eNodeB: let it run as in normal mode (as with a B210) + * - for the UE, on its very first read: + * - we want this read to get data from subframe 0 + * but the first write of eNodeB is subframe 4 + * so we first need to read and ignore 6 subframes + * - the UE will start its TX only at the subframe 2 + * corresponding to the subframe 0 it just read, + * so we need to write 12 subframes before anything + * (the function tcp_bridge_read_ue takes care to + * insert dummy TX data during the synch phase) + * + * Here is a drawing of the beginning of things to make + * this logic clearer. + * + * We see that eNB starts RX at subframe 0, starts TX at subfram 4, + * and that UE starts RX at subframe 10 and TX at subframe 12. + * + * We understand that the UE has to transmit 12 empty + * subframes for the eNodeB to start its processing. + * + * And because the eNodeB starts its TX at subframe 4 and we + * want the UE to start its RX at subframe 10, we need to + * read and ignore 6 subframes in the UE. + * + * ------------------------------------------------------------------------- + * eNB RX: | *0* | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ... + * ------------------------------------------------------------------------- + * + * ------------------------------------------------------------------------- + * eNB TX: | 0 | 1 | 2 | 3 | *4* | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ... + * ------------------------------------------------------------------------- + * + * ------------------------------------------------------------------------- + * UE RX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *10* | 11 | 12 | 13 | 14 ... + * ------------------------------------------------------------------------- + * + * ------------------------------------------------------------------------- + * UE TX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | *12* | 13 | 14 ... + * ------------------------------------------------------------------------- + * + * As a final note, we do TX before RX to ensure that the eNB will + * get some data and send us something so there is no deadlock + * at the beginning of things. Hopefully the kernel buffers for + * the sockets are big enough so that the first (big) TX can + * return to user mode before the buffers are full. If this + * is wrong in some environment, we will need to work by smaller + * units of data at a time. + */ +int tcp_bridge_ue_first_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) +{ + if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } + tcp_bridge_state_t *t = device->priv; + + uint32_t b[t->samples_per_subframe * 12]; + memset(b, 0, nsamps * 4); + int n = fullwrite(t->sock, b, t->samples_per_subframe * 12 * 4); + if (n != t->samples_per_subframe * 12 * 4) { + printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); + abort(); + } + n = fullread(t->sock, b, t->samples_per_subframe * 6 * 4); + if (n != t->samples_per_subframe * 6 * 4) { + printf("tcp_bridge: read error ret %d error %s\n", n, strerror(errno)); + abort(); + } + + device->trx_read_func = tcp_bridge_read_ue; + + return tcp_bridge_read_ue(device, timestamp, buff, nsamps, cc); +} + +__attribute__((__visibility__("default"))) +int device_init(openair0_device* device, openair0_config_t *openair0_cfg) +{ + tcp_bridge_state_t *tcp_bridge = (tcp_bridge_state_t*)malloc(sizeof(tcp_bridge_state_t)); + memset(tcp_bridge, 0, sizeof(tcp_bridge_state_t)); + + tcp_bridge->is_enb = getenv("ENODEB") != NULL; + + printf("tcp_bridge: running as %s\n", tcp_bridge->is_enb ? "eNB" : "UE"); + + /* only 25, 50 or 100 PRBs handled for the moment */ + if (openair0_cfg[0].sample_rate != 30720000 && + openair0_cfg[0].sample_rate != 15360000 && + openair0_cfg[0].sample_rate != 7680000) { + printf("tcp_bridge: ERROR: only 25, 50 or 100 PRBs supported\n"); + exit(1); + } + + device->trx_start_func = tcp_bridge_start; + device->trx_get_stats_func = tcp_bridge_get_stats; + device->trx_reset_stats_func = tcp_bridge_reset_stats; + device->trx_end_func = tcp_bridge_end; + device->trx_stop_func = tcp_bridge_stop; + device->trx_set_freq_func = tcp_bridge_set_freq; + device->trx_set_gains_func = tcp_bridge_set_gains; + device->trx_write_func = tcp_bridge_write; + + if (tcp_bridge->is_enb) { + device->trx_read_func = tcp_bridge_read; + } else { + device->trx_read_func = tcp_bridge_ue_first_read; + } + + device->priv = tcp_bridge; + + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: tcp_bridge->samples_per_subframe = 30720; break; + case 15360000: tcp_bridge->samples_per_subframe = 15360; break; + case 7680000: tcp_bridge->samples_per_subframe = 7680; break; + } + + /* let's pretend to be a b2x0 */ + device->type = USRP_B200_DEV; + + device->openair0_cfg=&openair0_cfg[0]; + + return 0; +} diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index b911fbc5a4a38a7b322a218e3962ce29832240c1..391e448deb590584e9a4b917edd4a6210b1fa1a5 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -36,13 +36,15 @@ # include "lteRALue.h" # include "lteRALenb.h" # endif -# include "RRC/LITE/defs.h" +# include "RRC/LTE/rrc_defs.h" # endif # include "enb_app.h" -int create_tasks(uint32_t enb_nb, uint32_t ue_nb) +extern int emulate_rf; + +int create_tasks(uint32_t enb_nb) { - LOG_D(ENB_APP, "%s(enb_nb:%d ue_nb:%d)\n", __FUNCTION__, enb_nb, ue_nb); + LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb); itti_wait_ready(1); if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { @@ -58,11 +60,7 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) } } - -# ifdef OPENAIR2 - { # if defined(ENABLE_USE_MME) - { if (enb_nb > 0) { if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); @@ -73,10 +71,11 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) LOG_E(S1AP, "Create task for S1AP failed\n"); return -1; } - - if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { - LOG_E(UDP_, "Create task for UDP failed\n"); - return -1; + if(!emulate_rf){ + if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { + LOG_E(UDP_, "Create task for UDP failed\n"); + return -1; + } } if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) { @@ -85,19 +84,7 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) } } -# if defined(NAS_BUILT_IN_UE) - if (ue_nb > 0) { - nas_user_container_t *users = calloc(1, sizeof(*users)); - if (users == NULL) abort(); - users->count = ue_nb; - if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { - LOG_E(NAS, "Create task for NAS UE failed\n"); - return -1; - } - } # endif - } -# endif if (enb_nb > 0) { LOG_I(RRC,"Creating RRC eNB Task\n"); @@ -106,27 +93,8 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) LOG_E(RRC, "Create task for RRC eNB failed\n"); return -1; } - } - if (ue_nb > 0) { - if (itti_create_task (TASK_RRC_UE, rrc_ue_task, NULL) < 0) { - LOG_E(RRC, "Create task for RRC UE failed\n"); - return -1; - } - -# if ENABLE_RAL - - if (itti_create_task (TASK_RAL_UE, mRAL_task, NULL) < 0) { - LOG_E(RAL_UE, "Create task for RAL UE failed\n"); - return -1; - } - -# endif - } - } -# endif // openair2: NN: should be openair3 - itti_wait_ready(0); diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h index 493c441f59adbd6bfe2d544e835abb066f58e8f6..ff1d9ace5199fbc0dbf3bf8b9cc7a52f1db983c5 100644 --- a/targets/COMMON/create_tasks.h +++ b/targets/COMMON/create_tasks.h @@ -26,7 +26,8 @@ /* External declaration of L2L1 task that depend on the target */ extern void *l2l1_task(void *arg); -int create_tasks(uint32_t enb_nb, uint32_t ue_nb); +int create_tasks(uint32_t enb_nb); +int create_tasks_ue(uint32_t ue_nb); #endif #endif /* CREATE_TASKS_H_ */ diff --git a/targets/COMMON/create_tasks_ue.c b/targets/COMMON/create_tasks_ue.c new file mode 100644 index 0000000000000000000000000000000000000000..db531b0e9ddd73294530a337909d04c8878039fd --- /dev/null +++ b/targets/COMMON/create_tasks_ue.c @@ -0,0 +1,80 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 + */ + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# include "create_tasks.h" +# include "log.h" + +# ifdef OPENAIR2 +# if defined(ENABLE_USE_MME) +# include "sctp_eNB_task.h" +# include "s1ap_eNB.h" +# include "nas_ue_task.h" +# include "udp_eNB_task.h" +# include "gtpv1u_eNB_task.h" +# endif +# if ENABLE_RAL +# include "lteRALue.h" +# include "lteRALenb.h" +# endif +# include "RRC/LTE/rrc_defs.h" +# endif +# include "enb_app.h" + +int create_tasks_ue(uint32_t ue_nb) +{ + LOG_D(ENB_APP, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); + + itti_wait_ready(1); + if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { + LOG_E(PDCP, "Create task for L2L1 failed\n"); + return -1; + } + +# if defined(ENABLE_USE_MME) +# if defined(NAS_BUILT_IN_UE) + if (ue_nb > 0) { + nas_user_container_t *users = calloc(1, sizeof(*users)); + if (users == NULL) abort(); + users->count = ue_nb; + if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { + LOG_E(NAS, "Create task for NAS UE failed\n"); + return -1; + } + } +# endif +# endif + + if (ue_nb > 0) { + if (itti_create_task (TASK_RRC_UE, rrc_ue_task, NULL) < 0) { + LOG_E(RRC, "Create task for RRC UE failed\n"); + return -1; + } + + } + + + itti_wait_ready(0); + + return 0; +} +#endif diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index b7fdc5e69152fb92ec8e2973f6f64bd184323ca1..1c27f655851f12b0d58eab503ca6e4e52346fc4a 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -4,24 +4,23 @@ #if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) # define NUMBER_OF_eNB_MAX 1 # define NUMBER_OF_RU_MAX 2 -#ifndef UE_EXPANSION -# define NUMBER_OF_UE_MAX 16 -# define NUMBER_OF_CONNECTED_eNB_MAX 3 -#else -# define NUMBER_OF_UE_MAX 256 -# define NUMBER_OF_CONNECTED_eNB_MAX 1 -#endif +# ifndef UE_EXPANSION +# define NUMBER_OF_UE_MAX 16 +# define NUMBER_OF_CONNECTED_eNB_MAX 3 +# else +# define NUMBER_OF_UE_MAX 256 +# define NUMBER_OF_CONNECTED_eNB_MAX 1 +# endif #else # define NUMBER_OF_eNB_MAX 7 # define NUMBER_OF_RU_MAX 32 -#ifndef UE_EXPANSION -# define NUMBER_OF_UE_MAX 20 -# define NUMBER_OF_CONNECTED_eNB_MAX 3 -#else -# define NUMBER_OF_UE_MAX 256 -# define NUMBER_OF_CONNECTED_eNB_MAX 1 -#endif - +# ifndef UE_EXPANSION +# define NUMBER_OF_UE_MAX 20 +# define NUMBER_OF_CONNECTED_eNB_MAX 3 +# else +# define NUMBER_OF_UE_MAX 256 +# define NUMBER_OF_CONNECTED_eNB_MAX 1 +# endif # if defined(STANDALONE) && STANDALONE==1 # undef NUMBER_OF_eNB_MAX # undef NUMBER_OF_UE_MAX @@ -30,7 +29,6 @@ # define NUMBER_OF_UE_MAX 3 # define NUMBER_OF_RU_MAX 3 # endif - # if defined(LARGE_SCALE) && LARGE_SCALE # undef NUMBER_OF_eNB_MAX # undef NUMBER_OF_UE_MAX diff --git a/targets/DOCS/nfapi-L2-emulator-setup.txt b/targets/DOCS/nfapi-L2-emulator-setup.txt new file mode 100644 index 0000000000000000000000000000000000000000..3e502e2137edcf25450b06bef409b71bbac9882b --- /dev/null +++ b/targets/DOCS/nfapi-L2-emulator-setup.txt @@ -0,0 +1,31 @@ + +#Build instructions +source oaienv +cd cmake_targets + +#Create lte-uesoftmodem-nos1 (UE) and lte-softmodem-nos1 (eNB) executables +./build_oai --UE --noS1 -x -t ETHERNET + +./build_oai --eNB --noS1 -x -t ETHERNET + +------------------------------------------------------------------------------------------------------------------------------------------------------- + +#Execution instuctions (Currently running eNB (VNF) and UE side (PNF) on the same machine using the loopback interface) +cd cmake_targets/tools + +# Loading nasmesh +source init_nas_nos1 + +# Add a new loopback interface address +sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up + +cd .. +cd lte_noS1_build_oai/build/ + +# Run the eNB process on one terminal (VNF) +sudo ./lte-softmodem-nos1 -O PATH_OF:rcc.band7.tm1.50PRB.nfapi.conf + +# Run the UE process on the other terminal (PNF) (--L2-emul specifying the operation in nfapi-L2-emulation mode +# and it has to be equal to 3, --num_ues specifying the number of UEs) +sudo ./lte-uesoftmodem-nos1 -U -O PATH_OF:oaiL1.nfapi.usrpb210.conf --L2-emul 3 --num-ues 5 > debug_log.txt + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf new file mode 100644 index 0000000000000000000000000000000000000000..38e471ac545b36c4ee469867efa646d0e3d24780 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf @@ -0,0 +1,175 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2600000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 32; + rx_gain = 116; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -16; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="debug"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf new file mode 100644 index 0000000000000000000000000000000000000000..2c11ea318701019d3e7a2e81b4889890b4f426a2 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf @@ -0,0 +1,175 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2600000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 32; + rx_gain = 116; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -16; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="debug"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf new file mode 100644 index 0000000000000000000000000000000000000000..6c7c319a11239189d7c314f3d01c829441301cf2 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -0,0 +1,209 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 116; + eNB_instances = [0]; + + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf new file mode 100644 index 0000000000000000000000000000000000000000..087f379c4d7afa36127e4a9bbf506f386eb1689c --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf @@ -0,0 +1,245 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf80"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 3; + rxPool_ResourceConfig_prb_Start = 4; + rxPool_ResourceConfig_prb_End = 9; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 3; + rxPool_ResourceConfig_subframeBitmap_present = "prBs16"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "1100110011001100"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 16; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf64" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 3; + discRxPool_ResourceConfig_prb_Start = 4; + discRxPool_ResourceConfig_prb_End = 5; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 4; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs16"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "1001100110011001"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 16; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.3"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.4/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index ff302811e9d7eb89baab3b2648e7d8766f966090..614a85d54ce536b6cbe05c2e2f302385a945751d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; @@ -105,6 +105,40 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } ); @@ -151,9 +185,9 @@ eNBs = { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; } @@ -164,6 +198,7 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; + phy_test_mode = 1; } ); @@ -189,6 +224,16 @@ RUs = ( } ); +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + log_config : { global_log_level ="info"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf index 9393872b308ad72f67f4128a47a64e5460193b02..b13962aee90335a968e72b594dc5b02b20edbaf6 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf @@ -4,28 +4,47 @@ log_config = { hw_log_level ="info"; hw_log_verbosity ="medium"; phy_log_level ="info"; - phy_log_verbosity ="low"; - mac_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="debug"; mac_log_verbosity ="medium"; rlc_log_level ="info"; rlc_log_verbosity ="medium"; pdcp_log_level ="info"; pdcp_log_verbosity ="medium"; - rrc_log_level ="info"; - rrc_log_verbosity ="medium"; + rrc_log_level ="debug"; + rrc_log_verbosity ="full"; }; + +#L1s = ( +# { +# num_cc = 1; +# tr_n_preference = "nfapi"; +# local_n_if_name = "eno1"; +# remote_n_address = "192.168.1.28"; +# local_n_address = "192.168.1.74"; +# local_n_portc = 50000; +# remote_n_portc = 50001; +# local_n_portd = 50010; +# remote_n_portd = 50011; +# } +#); + + L1s = ( { num_cc = 1; tr_n_preference = "nfapi"; - local_n_if_name = "lo"; + #local_n_if_name = "enp0s31f6"; + #remote_n_address = "10.0.0.2"; + #local_n_address = "10.0.0.1"; + local_n_if_name = "lo"; remote_n_address = "127.0.0.2"; - local_n_address = "127.0.0.1"; - local_n_portc = 50000; - remote_n_portc = 50001; - local_n_portd = 50010; - remote_n_portd = 50011; + local_n_address = "127.0.0.1"; + local_n_portc = 50000; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; } ); @@ -34,11 +53,10 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 0 + att_tx = 90 att_rx = 0; bands = [7,38,42,43]; max_pdschReferenceSignalPower = -27; max_rxgain = 125; - eNB_instances = [0]; } -); +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf new file mode 100644 index 0000000000000000000000000000000000000000..4de676ec9a42b41a83d2eaa1eda524cd60a1cb0d --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf @@ -0,0 +1,201 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + #mobile_network_code = "93"; + mobile_network_code = "92"; + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + #N_RB_DL = 50; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 115; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + #pdsch_referenceSignalPower = -27; + pdsch_referenceSignalPower = -30; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + #rach_preambleInitialReceivedTargetPower = -108; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.56.102"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "vboxnet0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.56.1/24"; + ENB_INTERFACE_NAME_FOR_S1U = "vboxnet0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.56.1/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "eno1"; + remote_s_address = "10.0.0.2"; + #local_s_address = "192.168.1.78"; + local_s_address = "10.0.0.1"; + local_s_portc = 50001; + remote_s_portc = 50000; + local_s_portd = 50011; + remote_s_portd = 50010; + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +); + + log_config : + { + global_log_level ="debug"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="debug"; + mac_log_verbosity ="high"; + rlc_log_level ="debug"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="high"; + }; + + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index 1c9ad09141dfed017836dd27a63c85d71f19a7d9..03241ec694a8ea75b99cb2b06a5ba360eb002a7b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; @@ -105,6 +105,40 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf index 772e13fe6fd0f3e563f0839c146e028cf9c5e748..42ab1e81c73435fd281af578355a27dcbc81b1ff 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -13,7 +13,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index 048f2fcc358fa6de5fc02e48d7223b8b5a202514..771bf094997b62110b0394945f74f3acec5c103d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -13,7 +13,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; @@ -73,8 +73,7 @@ eNBs = srs_SubframeConfig =; srs_ackNackST =; srs_MaxUpPts =;*/ - - pusch_p0_Nominal = -96; + pusch_p0_Nominal = -104; pusch_alpha = "AL1"; pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; @@ -197,13 +196,13 @@ RUs = ( ); log_config = { - global_log_level ="debug"; + global_log_level ="info"; global_log_verbosity ="medium"; hw_log_level ="info"; hw_log_verbosity ="medium"; - phy_log_level ="debug"; + phy_log_level ="info"; phy_log_verbosity ="medium"; - mac_log_level ="debug"; + mac_log_level ="info"; mac_log_verbosity ="high"; rlc_log_level ="info"; rlc_log_verbosity ="medium"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf index 24ae36a0a4c7c671f0cc4ad4754f1d6b233397a6..8a0f5feb58687406028e6c81b78a9b4175c3adec 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf @@ -11,7 +11,7 @@ RUs = ( tr_preference = "udp_if4p5"; nb_tx = 1; nb_rx = 1; - max_pdschReferenceSignalPower = -29; + max_pdschReferenceSignalPower = -15; max_rxgain = 120; bands = [7,13]; } diff --git a/targets/RT/USER/eNB_usrp.gtkw b/targets/RT/USER/eNB_usrp.gtkw index 838ec54383f4de0dc6f6165fc374013a3f80e3b8..e50c1831b69ba1e7e49ab33f79f0df523cb15ec0 100644 --- a/targets/RT/USER/eNB_usrp.gtkw +++ b/targets/RT/USER/eNB_usrp.gtkw @@ -1,19 +1,19 @@ [*] [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Tue Jul 25 20:26:12 2017 +[*] Thu Feb 22 14:46:40 2018 [*] [dumpfile] "/tmp/openair_dump_eNB.vcd" -[dumpfile_mtime] "Tue Jul 25 20:11:55 2017" -[dumpfile_size] 19201475 -[savefile] "/home/papillon/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw" -[timestart] 29023604000 -[size] 1236 578 -[pos] 309 0 -*-20.793451 29026062100 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[dumpfile_mtime] "Thu Feb 22 14:44:26 2018" +[dumpfile_size] 3482761 +[savefile] "/homes/wangts/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw" +[timestart] 4525000000 +[size] 1920 1018 +[pos] 0 22 +*-21.506693 4530514310 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [sst_width] 386 -[signals_width] 262 +[signals_width] 344 [sst_expanded] 1 -[sst_vpaned_height] 146 +[sst_vpaned_height] 303 @28 functions.trx_read functions.trx_write @@ -25,12 +25,42 @@ functions.eNB_thread_rxtx0 @24 variables.frame_number_RX0_RU[63:0] variables.subframe_number_RX0_RU[63:0] -@25 variables.frame_number_TX0_RU[63:0] -@24 variables.subframe_number_TX0_RU[63:0] @28 +functions.mac_schedule_dlsch +functions.macxface_eNB_dlsch_ulsch_scheduler +functions.macxface_ue_scheduler +functions.phy_eNB_ofdm_mod_l +@24 +variables.frame_number_RX0_eNB[63:0] +@25 +variables.subframe_number_RX0_eNB[63:0] +@24 +variables.frame_number_TX0_eNB[63:0] +variables.subframe_number_TX0_eNB[63:0] +variables.frame_number_RX1_eNB[63:0] +variables.subframe_number_RX1_eNB[63:0] +variables.frame_number_TX1_eNB[63:0] +variables.subframe_number_TX1_eNB[63:0] +@28 +functions.phy_eNB_dlsch_modulation +functions.phy_eNB_dlsch_encoding +functions.phy_eNB_dlsch_scrambling +functions.phy_eNB_beam_precoding +functions.phy_enb_pdcch_tx +functions.phy_enb_prach_rx +functions.phy_procedures_ru_feprx0 +functions.phy_procedures_eNb_rx_uespec0 +functions.phy_procedures_eNb_rx_uespec1 +functions.phy_enb_sfgen functions.phy_procedures_eNb_tx0 +functions.phy_procedures_eNb_tx1 +functions.phy_procedures_ru_feprx1 +functions.phy_procedures_ru_feptx_ofdm0 +functions.phy_procedures_ru_feptx_ofdm1 +functions.phy_procedures_ru_feptx_prec0 +functions.phy_procedures_ru_feptx_prec1 functions.eNB_thread_rxtx1 functions.phy_enb_sfgen functions.phy_enb_prach_rx diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index f9fc5d676b2bd1a7fda5b508b18717d6628727c1..a418d09a0f586f6752abf54e48097c64ee9e78db 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -44,7 +44,12 @@ #include "PHY/types.h" -#include "PHY/defs.h" +#include "PHY/INIT/phy_init.h" + +#include "PHY/defs_eNB.h" +#include "SCHED/sched_eNB.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" + #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -55,22 +60,14 @@ #include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if5_tools.h" -#include "PHY/extern.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/extern.h" - -#include "../../SIMU/USER/init_lte.h" - -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/proto.h" -#include "RRC/LITE/extern.h" -#include "PHY_INTERFACE/extern.h" -#include "PHY_INTERFACE/defs.h" -#ifdef SMBV -#include "PHY/TOOLS/smbv.h" -unsigned short config_frames[4] = {2,9,11,13}; -#endif +#include "PHY/phy_extern.h" + + +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface.h" #include "UTIL/LOG/log_extern.h" #include "UTIL/OTG/otg_tx.h" #include "UTIL/OTG/otg_externs.h" @@ -78,7 +75,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "enb_config.h" -//#include "PHY/TOOLS/time_meas.h" + #ifndef OPENAIR2 #include "UTIL/OTG/otg_extern.h" @@ -95,7 +92,6 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "T.h" - //#define DEBUG_THREADS 1 //#define USRP_DEBUG 1 @@ -122,7 +118,9 @@ extern int transmission_mode; extern int oaisim_flag; -uint16_t sf_ahead=4; +//uint16_t sf_ahead=4; +extern uint16_t sf_ahead; + //pthread_t main_eNB_thread; @@ -149,11 +147,13 @@ void exit_fun(const char* s); void init_eNB(int,int); void stop_eNB(int nb_inst); - +int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); +int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif +extern int codingw; extern uint8_t nfapi_mode; extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); @@ -212,7 +212,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam // if this is IF5 or 3GPP_eNB if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx); #endif } @@ -221,7 +221,16 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam // UE-specific RX processing for subframe n if (nfapi_mode == 0 || nfapi_mode == 1) { - phy_procedures_eNB_uespec_RX(eNB, proc, no_relay ); + phy_procedures_eNB_uespec_RX(eNB, proc); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 ); + + if(get_nprocs() >= 8){ + if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) { + LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx); + return(-1); + } + if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) return(-1); } pthread_mutex_lock(&eNB->UL_INFO_mutex); @@ -234,6 +243,9 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam eNB->if_inst->UL_indication(&eNB->UL_INFO); pthread_mutex_unlock(&eNB->UL_INFO_mutex); +#if 0 +/* TODO: find a correct solution for this conflict */ +<<<<<<< HEAD // ***************************************** // TX processing for subframe n+sf_ahead @@ -247,6 +259,27 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1); #endif if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); +======= + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 ); + if(oai_exit) return(-1); + if(get_nprocs() <= 4){ + phy_procedures_eNB_TX(eNB, proc, 1); + } +>>>>>>> origin/develop +#endif /* #if 0 */ + /* this conflict resolution may be totally wrong, to be tested */ + /* CONFLICT RESOLUTION: BEGIN */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 ); + if(oai_exit) return(-1); + if(get_nprocs() <= 4){ +#ifndef PHY_TX_THREAD + phy_procedures_eNB_TX(eNB, proc, 1); +#endif + } + /* CONFLICT RESOLUTION: what about this release_thread call, has it to be done? if yes, where? */ + //if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); + /* CONFLICT RESOLUTION: END */ stop_meas( &softmodem_stats_rxtx_sf ); @@ -298,6 +331,50 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam } +static void* tx_thread(void* param) { + + eNB_proc_t *eNB_proc = (eNB_proc_t*)param; + eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1]; + PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; + + char thread_name[100]; + sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); + thread_top_init(thread_name,1,470000,500000,500000); + + //wait_sync("tx_thread"); + + while (!oai_exit) { + + + if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + if (oai_exit) break; + // ***************************************** + // TX processing for subframe n+4 + // run PHY TX procedures the one after the other for all CCs to avoid race conditions + // (may be relaxed in the future for performance reasons) + // ***************************************** + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX1_ENB,proc->subframe_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX1_ENB,proc->subframe_rx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB,proc->frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,proc->frame_rx); + + phy_procedures_eNB_TX(eNB, proc, 1); + if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + + pthread_mutex_lock( &proc->mutex_rxtx ); + proc->pipe_ready++; + // the thread can now be woken up + if (pthread_cond_signal(&proc->cond_rxtx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + } + pthread_mutex_unlock( &proc->mutex_rxtx ); + wakeup_txfh(proc,eNB_proc->ru_proc); + } + + return 0; +} + /*! * \brief The RX UE-specific and TX thread of eNB. * \param param is a \ref eNB_proc_t structure which contains the info what to process. @@ -307,42 +384,83 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam static void* eNB_thread_rxtx( void* param ) { static int eNB_thread_rxtx_status; + //eNB_proc_t *eNB_proc = (eNB_proc_t*)param; + eNB_rxtx_proc_t *proc; + + // Working + if(nfapi_mode ==2){ + proc = (eNB_rxtx_proc_t*)param; + } + else{ + eNB_proc_t *eNB_proc = (eNB_proc_t*)param; + proc = &eNB_proc->proc_rxtx[0]; + } + - eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param; PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; + //RU_proc_t *ru_proc = NULL; char thread_name[100]; + cpu_set_t cpuset; + CPU_ZERO(&cpuset); // set default return value eNB_thread_rxtx_status = 0; - sprintf(thread_name,"RXn_TXnp4_%d",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); - thread_top_init(thread_name,1,850000L,1000000L,2000000L); + sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); + thread_top_init(thread_name,1,470000,500000,500000); + pthread_setname_np( pthread_self(),"rxtx processing"); + LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid)); + + while (!oai_exit) { + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); + T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu()); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB,proc->subframe_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB,proc->subframe_rx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB,proc->frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB,proc->frame_rx); + if (oai_exit) break; if (eNB->CC_id==0) { if (rxtx(eNB,proc,thread_name) < 0) break; - } if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + pthread_mutex_lock( &proc->mutex_rxtx ); + proc->pipe_ready++; + // the thread can now be woken up + if (pthread_cond_signal(&proc->cond_rxtx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + } + pthread_mutex_unlock( &proc->mutex_rxtx ); + if(get_nprocs() >= 8) wakeup_tx(eNB,eNB->proc.ru_proc); + else + { + phy_procedures_eNB_TX(eNB, proc, 1); + wakeup_txfh(proc,eNB->proc.ru_proc); + } } // while !oai_exit VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); - printf( "Exiting eNB thread RXn_TXnp4\n"); + LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n"); eNB_thread_rxtx_status = 0; return &eNB_thread_rxtx_status; @@ -372,10 +490,12 @@ static void wait_system_ready (char *message, volatile int *start_flag) { -void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) +void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) { eNB_proc_t *proc = &eNB->proc; eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0]; + LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; + RU_proc_t *ru_proc=&ru->proc; proc->frame_rx = frame_rx; proc->subframe_rx = subframe_rx; @@ -383,23 +503,115 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) if (!oai_exit) { T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); - proc_rxtx->subframe_rx = proc->subframe_rx; - proc_rxtx->frame_rx = proc->frame_rx; - proc_rxtx->subframe_tx = (proc->subframe_rx+sf_ahead)%10; - proc_rxtx->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (1+proc->frame_rx)&1023 : proc->frame_rx; - proc->frame_tx = proc_rxtx->frame_tx; - proc_rxtx->timestamp_tx = proc->timestamp_tx; + proc_rxtx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); + proc_rxtx->frame_rx = ru_proc->frame_rx; + proc_rxtx->subframe_rx = ru_proc->subframe_rx; + proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; + proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); + ru_proc->timestamp_tx = proc_rxtx->timestamp_tx; + ru_proc->subframe_tx = proc_rxtx->subframe_tx; + ru_proc->frame_tx = proc_rxtx->frame_tx; } } +int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) { + + if(ru_proc == NULL) + return(0); + struct timespec wait; + wait.tv_sec=0; + wait.tv_nsec=5000000L; + + + if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx); + return(-1); + } + if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1); + + if (ru_proc->instance_cnt_eNBs == 0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); + return(-1); + } + if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); + exit_fun( "error locking mutex_eNB" ); + return(-1); + } + + ++ru_proc->instance_cnt_eNBs; + ru_proc->timestamp_tx = proc->timestamp_tx; + ru_proc->subframe_tx = proc->subframe_tx; + ru_proc->frame_tx = proc->frame_tx; + + // the thread can now be woken up + if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &ru_proc->mutex_eNBs ); + + return(0); +} + +int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) { + + eNB_proc_t *proc=&eNB->proc; + + eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1]; + eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0]; + + + struct timespec wait; + wait.tv_sec=0; + wait.tv_nsec=5000000L; + + + + if (proc_rxtx1->instance_cnt_rxtx == 0) { + LOG_E(PHY,"Frame %d, subframe %d: TX1 thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx); + return(-1); + } + + if (pthread_mutex_timedlock(&proc_rxtx1->mutex_rxtx,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", proc_rxtx1->subframe_rx&1,proc_rxtx1->instance_cnt_rxtx ); + exit_fun( "error locking mutex_tx" ); + return(-1); + } + + ++proc_rxtx1->instance_cnt_rxtx; + + + proc_rxtx1->subframe_rx = proc_rxtx0->subframe_rx; + proc_rxtx1->frame_rx = proc_rxtx0->frame_rx; + proc_rxtx1->subframe_tx = proc_rxtx0->subframe_tx; + proc_rxtx1->frame_tx = proc_rxtx0->frame_tx; + proc_rxtx1->timestamp_tx = proc_rxtx0->timestamp_tx; + + // the thread can now be woken up + if (pthread_cond_signal(&proc_rxtx1->cond_rxtx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &proc_rxtx1->mutex_rxtx ); + + return(0); +} int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { eNB_proc_t *proc=&eNB->proc; + RU_proc_t *ru_proc=&ru->proc; - eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1]; + eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1]; + //eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1]; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; @@ -431,25 +643,28 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { wait.tv_sec=0; wait.tv_nsec=5000000L; - /* accept some delay in processing - up to 5ms */ - for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { - LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx); - usleep(500); + + if(wait_on_condition(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->cond_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) { + LOG_E(PHY,"Frame %d, subframe %d: RXTX0 not ready\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx); + return(-1); } - if (proc_rxtx->instance_cnt_rxtx == 0) { - exit_fun( "TX thread busy" ); + if (release_thread(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) return(-1); + + if (proc_rxtx0->instance_cnt_rxtx == 0) { + LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx); return(-1); } // wake up TX for subframe n+sf_ahead // lock the TX mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); + if (pthread_mutex_timedlock(&proc_rxtx0->mutex_rxtx,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx0->subframe_rx&1,proc_rxtx0->instance_cnt_rxtx ); exit_fun( "error locking mutex_rxtx" ); return(-1); } - ++proc_rxtx->instance_cnt_rxtx; + + ++proc_rxtx0->instance_cnt_rxtx; // We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired @@ -457,20 +672,20 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, // and proc->subframe_tx = proc->subframe_rx+sf_ahead - proc_rxtx->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); - proc_rxtx->frame_rx = proc->frame_rx; - proc_rxtx->subframe_rx = proc->subframe_rx; - proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; - proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; + proc_rxtx0->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); + proc_rxtx0->frame_rx = ru_proc->frame_rx; + proc_rxtx0->subframe_rx = ru_proc->subframe_rx; + proc_rxtx0->frame_tx = (proc_rxtx0->subframe_rx > (9-sf_ahead)) ? (proc_rxtx0->frame_rx+1)&1023 : proc_rxtx0->frame_rx; + proc_rxtx0->subframe_tx = (proc_rxtx0->subframe_rx + sf_ahead)%10; // the thread can now be woken up - if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { + if (pthread_cond_signal(&proc_rxtx0->cond_rxtx) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); + pthread_mutex_unlock( &proc_rxtx0->mutex_rxtx ); return(0); } @@ -506,7 +721,7 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { if (is_prach_subframe(fp,frame,subframe)>0) { LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe); if (proc->instance_cnt_prach == 0) { - //LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe); + LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe); return; } @@ -534,7 +749,7 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { eNB_proc_t *proc = &eNB->proc; @@ -566,7 +781,7 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { if (is_prach_subframe(fp,frame,subframe)>0) { LOG_D(PHY,"Triggering prach br processing, frame %d, subframe %d\n",frame,subframe); if (proc->instance_cnt_prach_br == 0) { - //LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe); + LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe); return; } @@ -611,8 +826,9 @@ static void* eNB_thread_prach( void* param ) { // set default return value eNB_thread_prach_status = 0; - thread_top_init("eNB_thread_prach",1,500000L,1000000L,20000000L); + thread_top_init("eNB_thread_prach",1,500000,1000000,20000000); + //wait_sync("eNB_thread_prach"); while (!oai_exit) { @@ -623,7 +839,7 @@ static void* eNB_thread_prach( void* param ) { LOG_D(PHY,"Running eNB prach procedures\n"); prach_procedures(eNB -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif ); @@ -637,7 +853,7 @@ static void* eNB_thread_prach( void* param ) { return &eNB_thread_prach_status; } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /*! * \brief The prach receive thread of eNB for BL/CE UEs. * \param param is a \ref eNB_proc_t structure which contains the info what to process. @@ -653,7 +869,7 @@ static void* eNB_thread_prach_br( void* param ) { // set default return value eNB_thread_prach_status = 0; - thread_top_init("eNB_thread_prach_br",1,500000L,1000000L,20000000L); + thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000); while (!oai_exit) { @@ -677,8 +893,40 @@ static void* eNB_thread_prach_br( void* param ) { #endif -extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); -extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); + +extern void init_td_thread(PHY_VARS_eNB *); +extern void init_te_thread(PHY_VARS_eNB *); +extern void kill_td_thread(PHY_VARS_eNB *); +extern void kill_te_thread(PHY_VARS_eNB *); +//////////////////////////////////////need to modified////////////////***** + +static void* process_stats_thread(void* param) { + + PHY_VARS_eNB *eNB = (PHY_VARS_eNB*)param; + + wait_sync("process_stats_thread"); + + while (!oai_exit) { + sleep(1); + if (opp_enabled == 1) { + if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL); + if (eNB->te) + { + print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL); + print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_signal_stats,"coding_signal",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_main_stats,"coding_main",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL); + } + print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL); + } + } + return(NULL); +} + void init_eNB_proc(int inst) { @@ -688,8 +936,7 @@ void init_eNB_proc(int inst) { eNB_proc_t *proc; eNB_rxtx_proc_t *proc_rxtx; pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; - //*attr_td=NULL,*attr_te=NULL; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_attr_t *attr_prach_br=NULL; #endif @@ -705,8 +952,11 @@ void init_eNB_proc(int inst) { proc_rxtx = proc->proc_rxtx; proc_rxtx[0].instance_cnt_rxtx = -1; proc_rxtx[1].instance_cnt_rxtx = -1; + proc_rxtx[0].pipe_ready = 0; + proc_rxtx[1].pipe_ready = 0; proc->instance_cnt_prach = -1; proc->instance_cnt_asynch_rxtx = -1; + proc->instance_cnt_synch = -1; proc->CC_id = CC_id; proc->first_rx=1; @@ -730,11 +980,9 @@ void init_eNB_proc(int inst) { pthread_attr_init( &proc->attr_prach); pthread_attr_init( &proc->attr_asynch_rxtx); - // pthread_attr_init( &proc->attr_td); - // pthread_attr_init( &proc->attr_te); pthread_attr_init( &proc_rxtx[0].attr_rxtx); pthread_attr_init( &proc_rxtx[1].attr_rxtx); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) proc->instance_cnt_prach_br = -1; proc->RU_mask_prach_br=0; pthread_mutex_init( &proc->mutex_prach_br, NULL); @@ -746,13 +994,31 @@ void init_eNB_proc(int inst) { attr0 = &proc_rxtx[0].attr_rxtx; attr1 = &proc_rxtx[1].attr_rxtx; attr_prach = &proc->attr_prach; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) attr_prach_br = &proc->attr_prach_br; #endif // attr_td = &proc->attr_td; // attr_te = &proc->attr_te; #endif + //////////////////////////////////////need to modified////////////////***** + if(get_nprocs() > 2 && codingw) + { + init_te_thread(eNB); + init_td_thread(eNB); + } + //////////////////////////////////////need to modified////////////////***** + //pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); + + //pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc_rxtx ); + + + // Panos: Should we also include here the case where single_thread_flag = 1 ? + if(nfapi_mode!=2){ + pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); + pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); + } + LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); @@ -761,7 +1027,7 @@ void init_eNB_proc(int inst) { pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); } pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); #endif char name[16]; @@ -773,6 +1039,9 @@ void init_eNB_proc(int inst) { } AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); + + + if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void*)eNB); } @@ -798,6 +1067,8 @@ void init_eNB_proc(int inst) { pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); sync_phy_proc.phy_proc_CC_id = 0; + + } @@ -811,49 +1082,50 @@ void kill_eNB_proc(int inst) { PHY_VARS_eNB *eNB; eNB_proc_t *proc; eNB_rxtx_proc_t *proc_rxtx; + int i; for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { eNB=RC.eNB[inst][CC_id]; proc = &eNB->proc; proc_rxtx = &proc->proc_rxtx[0]; - + kill_td_thread(eNB); + kill_te_thread(eNB); LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); - - if (eNB->single_thread_flag==0) { - proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race! - proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race! - pthread_cond_signal( &proc_rxtx[0].cond_rxtx ); - pthread_cond_signal( &proc_rxtx[1].cond_rxtx ); + for (i=0; i<2; i++) { + pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx); + proc_rxtx[i].instance_cnt_rxtx = 0; + proc_rxtx[i].pipe_ready = 0; + pthread_cond_signal(&proc_rxtx[i].cond_rxtx); + pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx); } proc->instance_cnt_prach = 0; pthread_cond_signal( &proc->cond_prach ); + pthread_cond_signal( &proc->cond_asynch_rxtx ); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); + + LOG_D(PHY, "joining pthread_prach\n"); pthread_join( proc->pthread_prach, (void**)&status ); LOG_I(PHY, "Destroying prach mutex/cond\n"); pthread_mutex_destroy( &proc->mutex_prach ); pthread_cond_destroy( &proc->cond_prach ); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) proc->instance_cnt_prach_br = 0; pthread_cond_signal( &proc->cond_prach_br ); pthread_join( proc->pthread_prach_br, (void**)&status ); pthread_mutex_destroy( &proc->mutex_prach_br ); pthread_cond_destroy( &proc->cond_prach_br ); #endif - LOG_I(PHY, "Destroying UL_INFO mutex\n"); pthread_mutex_destroy(&eNB->UL_INFO_mutex); - int i; - if (eNB->single_thread_flag==0) { - for (i=0;i<2;i++) { - LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); - pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); - LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); - pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); - pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); - } + for (i=0;i<2;i++) { + LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); + pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); + LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); + pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); + pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); } } } @@ -886,6 +1158,21 @@ void print_opp_meas(void) { } } +void free_transport(PHY_VARS_eNB *eNB) +{ + int i; + int j; + + for (i=0; i<NUMBER_OF_UE_MAX; i++) { + LOG_I(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i); + for (j=0; j<2; j++) free_eNB_dlsch(eNB->dlsch[i][j]); + + LOG_I(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); + free_eNB_ulsch(eNB->ulsch[1+i]); + } + free_eNB_ulsch(eNB->ulsch[0]); +} + void init_transport(PHY_VARS_eNB *eNB) { int i; @@ -974,7 +1261,7 @@ void init_eNB_afterRU(void) { LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]); eNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*)); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (int ce_level=0;ce_level<4;ce_level++) { LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]); eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*)); @@ -997,7 +1284,7 @@ void init_eNB_afterRU(void) { for (i=0;i<eNB->RU_list[ru_id]->nb_rx;aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (int ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; #endif @@ -1050,7 +1337,9 @@ void init_eNB_afterRU(void) { RC.ru[ru_id]->wakeup_rxtx = wakeup_rxtx; RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_eNB; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; +#endif RC.ru[ru_id]->eNB_top = eNB_top; } } @@ -1080,8 +1369,8 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { #endif - eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + eNB->td = ulsch_decoding_data_all;//(get_nprocs()<=4) ? ulsch_decoding_data : ulsch_decoding_data_2thread; + eNB->te = dlsch_encoding_all;//(get_nprocs()<=4) ? dlsch_encoding : dlsch_encoding_2threads; LOG_I(PHY,"Registering with MAC interface module\n"); diff --git a/targets/RT/USER/lte-ran.c b/targets/RT/USER/lte-ran.c deleted file mode 100644 index 597ceb0654c6a621df341e84637990efb1aa1b74..0000000000000000000000000000000000000000 --- a/targets/RT/USER/lte-ran.c +++ /dev/null @@ -1,1747 +0,0 @@ -/******************************************************************************* - 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 - -*******************************************************************************/ - -/*! \file lte-enb.c - * \brief Top-level threads for eNodeB - * \author R. Knopp, F. Kaltenberger, Navid Nikaein - * \date 2012 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr - * \note - * \warning - */ -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <sched.h> -#include <linux/sched.h> -#include <signal.h> -#include <execinfo.h> -#include <getopt.h> -#include <sys/sysinfo.h> -#include "rt_wrapper.h" - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "assertions.h" -#include "msc.h" - -#include "PHY/types.h" - -#include "PHY/defs.h" -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "../../ARCH/COMMON/common_lib.h" - -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" - -#include "PHY/extern.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/extern.h" - -#include "../../SIMU/USER/init_lte.h" - -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/proto.h" -#include "RRC/LITE/extern.h" -#include "PHY_INTERFACE/extern.h" - -#ifdef SMBV -#include "PHY/TOOLS/smbv.h" -unsigned short config_frames[4] = {2,9,11,13}; -#endif -#include "UTIL/LOG/log_extern.h" -#include "UTIL/OTG/otg_tx.h" -#include "UTIL/OTG/otg_externs.h" -#include "UTIL/MATH/oml.h" -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "enb_config.h" -//#include "PHY/TOOLS/time_meas.h" - -#ifndef OPENAIR2 -#include "UTIL/OTG/otg_extern.h" -#endif - -#if defined(ENABLE_ITTI) -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -#ifdef PDCP_USE_NETLINK -# include "SIMULATION/ETH_TRANSPORT/proto.h" -#endif -# endif -#endif - -#include "T.h" - -//#define DEBUG_THREADS 1 - -//#define USRP_DEBUG 1 -struct timing_info_t { - //unsigned int frame, hw_slot, last_slot, next_slot; - RTIME time_min, time_max, time_avg, time_last, time_now; - //unsigned int mbox0, mbox1, mbox2, mbox_target; - unsigned int n_samples; -} timing_info; - -// Fix per CC openair rf/if device update -// extern openair0_device openair0; - -#if defined(ENABLE_ITTI) -extern volatile int start_eNB; -extern volatile int start_UE; -#endif -extern volatile int oai_exit; - -extern openair0_config_t openair0_cfg[MAX_CARDS]; - -extern pthread_cond_t sync_cond; -extern pthread_mutex_t sync_mutex; -extern int sync_var; - -//pthread_t main_eNB_thread; - -time_stats_t softmodem_stats_mt; // main thread -time_stats_t softmodem_stats_hw; // hw acquisition -time_stats_t softmodem_stats_rxtx_sf; // total tx time -time_stats_t softmodem_stats_rx_sf; // total rx time -int32_t **rxdata; -int32_t **txdata; - -uint8_t seqno; //sequence number - -static int time_offset[4] = {0,0,0,0}; - -/* mutex, cond and variable to serialize phy proc TX calls - * (this mechanism may be relaxed in the future for better - * performances) - */ -static struct { - pthread_mutex_t mutex_phy_proc_tx; - pthread_cond_t cond_phy_proc_tx; - volatile uint8_t phy_proc_CC_id; -} sync_phy_proc; - -void exit_fun(const char* s); - -void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *,int); -void stop_eNB(int nb_inst); -void init_RU(RAN_CONTEXT *rc, eNB_func_t node_function, RU_if_in_t ru_if_in[], RU_if_timing_t ru_if_timing[], eth_params_t *eth_params); -void stop_RU(); - -// Generic thread initialisation function -static inline void thread_top_init(char *thread_name, - int affinity, - uint64_t runtime, - uint64_t deadline, - uint64_t period) { - - MSC_START_USE(); - -#ifdef DEADLINE_SCHEDULER - struct sched_attr attr; - - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = runtime; - attr.sched_deadline = deadline; - attr.sched_period = period; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] eNB tx thread: sched_setattr failed\n"); - exit_fun("Error setting deadline scheduler"); - } - - LOG_I( HW, "[SCHED] eNB %s deadline thread started on CPU %d\n", thread_name,sched_getcpu() ); - -#else //LOW_LATENCY - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; - - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ - /* CPU 1 is reserved for all RX_TX threads */ - /* Enable CPU Affinity only if number of CPUs >2 */ - CPU_ZERO(&cpuset); - -#ifdef CPU_AFFINITY - if (get_nprocs() > 2) - { - if (affinity == 0) - CPU_SET(0,&cpuset); - else - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - } -#endif //CPU_AFFINITY - - /* Check the actual affinity mask assigned to the thread */ - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity,0,sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) { - char temp[1024]; - sprintf (temp, " CPU_%d", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0, sizeof(sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - } - - LOG_I(HW, "[SCHED][eNB] %s started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - sparam.sched_priority, cpu_affinity ); - -#endif //LOW_LATENCY - - mlockall(MCL_CURRENT | MCL_FUTURE); - -} - -static inline void wait_sync(char *thread_name) { - - printf( "waiting for sync (%s)\n",thread_name); - pthread_mutex_lock( &sync_mutex ); - - while (sync_var<0) - pthread_cond_wait( &sync_cond, &sync_mutex ); - - pthread_mutex_unlock(&sync_mutex); - - printf( "got sync (%s)\n", thread_name); - -} - -// RU OFDM Modulator, used in IF4p5 RRU, RCC/RAU with IF5, eNodeB - -void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) { - - unsigned int aa,slot_offset, slot_offset_F; - int dummy_tx_b[7680*4] __attribute__((aligned(32))); - int i,j, tx_offset; - int slot_sizeF = (phy_vars_eNB->frame_parms.ofdm_symbol_size)* - ((phy_vars_eNB->frame_parms.Ncp==1) ? 6 : 7); - int len,len2; - int16_t *txdata; -// int CC_id = phy_vars_eNB->proc.CC_id; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 ); - - slot_offset_F = (subframe<<1)*slot_sizeF; - - slot_offset = subframe*phy_vars_eNB->frame_parms.samples_per_tti; - - if ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_DL)|| - ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) { - // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); - - for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) { - if (phy_vars_eNB->frame_parms.Ncp == EXTENDED) { - PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F], - dummy_tx_b, - phy_vars_eNB->frame_parms.ofdm_symbol_size, - 6, - phy_vars_eNB->frame_parms.nb_prefix_samples, - CYCLIC_PREFIX); - PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF], - dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1), - phy_vars_eNB->frame_parms.ofdm_symbol_size, - 6, - phy_vars_eNB->frame_parms.nb_prefix_samples, - CYCLIC_PREFIX); - } else { - normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F], - dummy_tx_b, - 7, - &(phy_vars_eNB->frame_parms)); - // if S-subframe generate first slot only - if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) - normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF], - dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1), - 7, - &(phy_vars_eNB->frame_parms)); - } - - // if S-subframe generate first slot only - if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) - len = phy_vars_eNB->frame_parms.samples_per_tti>>1; - else - len = phy_vars_eNB->frame_parms.samples_per_tti; - /* - for (i=0;i<len;i+=4) { - dummy_tx_b[i] = 0x100; - dummy_tx_b[i+1] = 0x01000000; - dummy_tx_b[i+2] = 0xff00; - dummy_tx_b[i+3] = 0xff000000; - }*/ - - if (slot_offset+time_offset[aa]<0) { - txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)+tx_offset]; - len2 = -(slot_offset+time_offset[aa]); - len2 = (len2>len) ? len : len2; - for (i=0; i<(len2<<1); i++) { - txdata[i] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift; - } - if (len2<len) { - txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][0]; - for (j=0; i<(len<<1); i++,j++) { - txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift; - } - } - } - else if ((slot_offset+time_offset[aa]+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) { - tx_offset = (int)slot_offset+time_offset[aa]; - txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset]; - len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; - for (i=0; i<(len2<<1); i++) { - txdata[i] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift; - } - txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][0]; - for (j=0; i<(len<<1); i++,j++) { - txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift; - } - } - else { - tx_offset = (int)slot_offset+time_offset[aa]; - txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset]; - - for (i=0; i<(len<<1); i++) { - txdata[i] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift; - } - } - - // if S-subframe switch to RX in second subframe - /* - if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) { - for (i=0; i<len; i++) { - phy_vars_eNB->common_vars.txdata[0][aa][tx_offset++] = 0x00010001; - } - } - */ - if ((((phy_vars_eNB->frame_parms.tdd_config==0) || - (phy_vars_eNB->frame_parms.tdd_config==1) || - (phy_vars_eNB->frame_parms.tdd_config==2) || - (phy_vars_eNB->frame_parms.tdd_config==6)) && - (subframe==0)) || (subframe==5)) { - // turn on tx switch N_TA_offset before - //LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset); - for (i=0; i<phy_vars_eNB->N_TA_offset; i++) { - tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2; - if (tx_offset<0) - tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; - - if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) - tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; - - phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000; - } - } - } - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 ); -} - - - -void proc_tx_high0(RU_t *ru, - eNB_rxtx_proc_t *proc, - relaying_type_t r_type, - PHY_VARS_RN *rn) { - - int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx ); - - phy_procedures_eNB_TX(eNB,proc,r_type,rn,1); - - /* we're done, let the next one proceed */ - if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { - LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX proc\n"); - exit_fun("nothing to add"); - } - sync_phy_proc.phy_proc_CC_id++; - sync_phy_proc.phy_proc_CC_id %= MAX_NUM_CCs; - pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { - LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n"); - exit_fun("nothing to add"); - } - -} - -/* -void proc_tx_high(RU_t *ru, - eNB_rxtx_proc_t *proc, - relaying_type_t r_type, - PHY_VARS_RN *rn) { - - - // do PHY high - proc_tx_high0(eNB,proc,r_type,rn); - - // if TX fronthaul go ahead - if (eNB->tx_fh) eNB->tx_fh(eNB,proc); - -} - -void proc_tx_full(RU_t *ru, - eNB_rxtx_proc_t *proc, - relaying_type_t r_type, - PHY_VARS_RN *rn) { - - - // do PHY high - proc_tx_high0(eNB,proc,r_type,rn); - - - - -} -*/ - -// RU IF5 TX fronthaul for 16-bit OAI format -static inline void tx_rcc_if5(PHY_vars_eNB_t *ru,ru_proc_t *proc) { - if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, eNB->timestamp_tx&0xffffffff ); - send_IF5(ru, proc->timestamp_txp proc->subframe_tx, &seqno, IF5_RRH_GW_DL); -} - -// RCC IF5 TX fronthaul for Mobipass packet format -static inline void tx_rcc_if5_mobipass(PHY_VARS_eNB_t *eNB,ru_proc_t *proc) { - if (eNB == RC.eNB[0][p]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, eNB->timestamp_tx&0xffffffff ); - send_IF5(ru, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS); -} - -// RCC IF4p5 TX fronthaul -static inline void tx_rcc_if4p5(PHY_VARS_eNB_t *eNB,eNB_rxtx_proc_t *proc) { - send_IF4p5(eNB,proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0); -} - -// RAU IF5 TX fronthaul for 16-bit OAI format -static inline void tx_ru_if5(RU_t *ru) { - if (ru == RC.ru_list[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(eNB, ru->proc.timestamp_txp ru->proc.subframe_tx, &seqno, IF5_RRH_GW_DL); -} - -// RAU IF5 TX fronthaul for Mobipass packet format -static inline void tx_ru_if5_mobipass(RU_t *ru) { - if (ru == RC.ru_list[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(eNB, ru->proc.timestamp_tx, ru->proc.subframe_tx, &seqno, IF5_MOBIPASS); -} - -// RAU IF4p5 TX fronthaul -static inline void tx_fh_if4p5(RU_t *ru) { - send_IF4p5(eNB,proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0); -} - - -// RRU/RAU IF4p5 TX fronthaul receiver. Assumes an if_device on input and if or rf device on output -// receives one subframe's worth of IF4p5 OFDM symbols and precodes (if required for RAU function) modulates via IDFT + prefix insertion (if required for RRU function) -void proc_tx_ru_if4p5(RU_t *ru) { - - uint32_t symbol_number=0; - uint32_t symbol_mask, symbol_mask_full; - uint16_t packet_type; - ru_proc_t = &ru->proc; - - // dump VCD output for first RU in list - if (ru == RC.ru_list[0]) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB, proc->frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB, proc->subframe_tx ); - } - /// **** incoming IF4p5 from remote RCC/RAU **** /// - symbol_number = 0; - symbol_mask = 0; - symbol_mask_full = (1<<ru->frame_parms.symbols_per_tti)-1; - - for (PHY_VARS_eNB *eNB_tx = ru->eNB_list[0],i=0; eNB_tx[i] != NULL ; i++) { - do { - recv_IF4p5(ru, &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number); - symbol_mask = symbol_mask | (1<<symbol_number); - } while (symbol_mask != symbol_mask_full); - if (ru->do_precoding) ru->do_precoding(i,ru); - } - // do OFDM modulation if needed - if (ru->do_OFDM_mod) ru->do_OFDM_mod(ru); - - // do outgoing TX fronthaul if needed - if (ru->tx_fh) ru->tx_fh(ru); -} - -void proc_tx_ru_if5(RU_t *ru) { - - - if (ru == RC.ru_list[0]) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB, ru->proc.frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB, ru->proc.subframe_tx ); - } - - /// **** recv_IF5 of txdata from BBU **** /// - recv_IF5(eNB, &ru->timestamp_tx, proc->subframe_tx, IF5_RRH_GW_DL); - - // do OFDM modulation if needed - if (ru->do_OFDM_mod) ru->do_OFDM_mod(ru); - - // do outgoing TX fronthaul if needed - if (ru->tx_fh) ru->tx_fh(ru); -} - -int wait_CCs(eNB_rxtx_proc_t *proc) { - - struct timespec wait; - - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx,&wait) != 0) { - LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n"); - exit_fun("nothing to add"); - return(-1); - } - - // wait for our turn or oai_exit - while (sync_phy_proc.phy_proc_CC_id != proc->CC_id && !oai_exit) { - pthread_cond_wait(&sync_phy_proc.cond_phy_proc_tx, - &sync_phy_proc.mutex_phy_proc_tx); - } - - if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { - LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX\n"); - exit_fun("nothing to add"); - return(-1); - } - return(0); -} - -static inline int rxtx(PHY_VARS_eNB eNB_t *eNB,eNB_rxtx_proc_t *proc, char *thread_name) { - - start_meas(&softmodem_stats_rxtx_sf); - // **************************************** - // Common RX procedures subframe n - phy_procedures_eNB_common_RX(eNB); - - // UE-specific RX processing for subframe n - if (eNB->proc_uespec_rx) eNB->proc_uespec_rx(eNB, proc, no_relay ); - - // ***************************************** - // TX processing for subframe n+4 - // run PHY TX procedures the one after the other for all CCs to avoid race conditions - // (may be relaxed in the future for performance reasons) - // ***************************************** - //if (wait_CCs(proc)<0) return(-1); - - if (oai_exit) return(-1); - - if (eNB->proc_tx) eNB->proc_tx(eNB, proc, no_relay, NULL ); - - if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); - - stop_meas( &softmodem_stats_rxtx_sf ); - - return(0); -} - -/*! - * \brief The RX UE-specific and TX thread of eNB. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -static void* eNB_thread_rxtx( void* param ) { - - static int eNB_thread_rxtx_status; - - eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param; - PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; - - char thread_name[100]; - - - // set default return value - eNB_thread_rxtx_status = 0; - - sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); - thread_top_init(thread_name,1,850000L,1000000L,2000000L); - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); - - if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); - - - - if (oai_exit) break; - - if (rxtx(eNB,proc,thread_name) < 0) break; - - } // while !oai_exit - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); - - printf( "Exiting eNB thread RXn_TXnp4\n"); - - eNB_thread_rxtx_status = 0; - return &eNB_thread_rxtx_status; -} - -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) -/* Wait for eNB application initialization to be complete (eNB registration to MME) */ -static void wait_system_ready (char *message, volatile int *start_flag) { - - static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....", - " ....", " ...", " ..", " .", " "}; - int i = 0; - - while ((!oai_exit) && (*start_flag == 0)) { - LOG_N(EMU, message, indicator[i]); - fflush(stdout); - i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0])); - usleep(200000); - } - - LOG_D(EMU,"\n"); -} -#endif - - -// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU) -void fh_if5_asynch_UL(RU_t *ru,int *frame,int *subframe) { - - eNB_proc_t *proc = &eNB->proc; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - - recv_IF5(eNB, &ru->timestamp_rx, *subframe, IF5_RRH_GW_UL); - - proc->subframe_rx = (ru->timestamp_rx/fp->samples_per_tti)%10; - proc->frame_rx = (ru->timestamp_rx/(10*fp->samples_per_tti))&1023; - - if (proc->first_rx != 0) { - proc->first_rx = 0; - *subframe = proc->subframe_rx; - *frame = proc->frame_rx; - } - else { - if (proc->subframe_rx != *subframe) { - LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); - exit_fun("Exiting"); - } - if (proc->frame_rx != *frame) { - LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->frame_rx,*frame); - exit_fun("Exiting"); - } - } -} // eNodeB_3GPP_BBU - -// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU) -void fh_if4p5_asynch_UL(RU_t *ru,int *frame,int *subframe) { - - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; - - uint16_t packet_type; - uint32_t symbol_number,symbol_mask,symbol_mask_full,prach_rx; - - - symbol_number = 0; - symbol_mask = 0; - symbol_mask_full = (1<<fp->symbols_per_tti)-1; - prach_rx = 0; - - do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); - if (proc->first_rx != 0) { - *frame = proc->frame_rx; - *subframe = proc->subframe_rx; - proc->first_rx = 0; - } - else { - if (proc->frame_rx != *frame) { - LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); - exit_fun("Exiting"); - } - if (proc->subframe_rx != *subframe) { - LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); - exit_fun("Exiting"); - } - } - if (packet_type == IF4p5_PULFFT) { - symbol_mask = symbol_mask | (1<<symbol_number); - prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0; - } else if (packet_type == IF4p5_PRACH) { - prach_rx = 0; - } - } while( (symbol_mask != symbol_mask_full) || (prach_rx == 1)); - - -} - - -void fh_if5_asynch_DL(RU_t *ru,int *frame,int *subframe) { - - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; - int subframe_tx,frame_tx; - openair0_timestamp timestamp_tx; - - recv_IF5(eNB, ×tamp_tx, *subframe, IF5_RRH_GW_DL); - // printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); - - subframe_tx = (timestamp_tx/fp->samples_per_tti)%10; - frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; - - if (proc->first_tx != 0) { - *subframe = subframe_tx; - *frame = frame_tx; - proc->first_tx = 0; - } - else { - if (subframe_tx != *subframe) { - LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); - exit_fun("Exiting"); - } - if (frame_tx != *frame) { - LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame); - exit_fun("Exiting"); - } - } -} - -void fh_if4p5_asynch_DL(RU_t *ru,int *frame,int *subframe) { - - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; - - uint16_t packet_type; - uint32_t symbol_number,symbol_mask,symbol_mask_full; - int subframe_tx,frame_tx; - - symbol_number = 0; - symbol_mask = 0; - symbol_mask_full = (1<<fp->symbols_per_tti)-1; - - do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - recv_IF4p5(eNB, &frame_tx, &subframe_tx, &packet_type, &symbol_number); - if (proc->first_tx != 0) { - *frame = frame_tx; - *subframe = subframe_tx; - proc->first_tx = 0; - } - else { - if (frame_tx != *frame) { - LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame); - exit_fun("Exiting"); - } - if (subframe_tx != *subframe) { - LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); - exit_fun("Exiting"); - } - } - if (packet_type == IF4p5_PDLFFT) { - symbol_mask = symbol_mask | (1<<symbol_number); - } - else { - LOG_E(PHY,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type); - exit_fun("Exiting"); - } - } while (symbol_mask != symbol_mask_full); - - do_OFDM_mod_rt(subframe_tx, eNB); -} - -/*! - * \brief The Asynchronous RX/TX FH thread of RAU/RCC/eNB/RRU. - * This handles the RX FH for an asynchronous RRU/UE - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -static void* eNB_thread_asynch_rxtx( void* param ) { - - static int eNB_thread_asynch_rxtx_status; - - eNB_proc_t *proc = (eNB_proc_t*)param; - PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; - - - int subframe=0, frame=0; - - thread_top_init("thread_asynch",1,870000L,1000000L,1000000L); - - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - - wait_sync("thread_asynch"); - - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - printf( "waiting for devices (eNB_thread_asynch_rx)\n"); - - wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch"); - - printf( "devices ok (eNB_thread_asynch_rx)\n"); - - - while (!oai_exit) { - - if (oai_exit) break; - - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } - - if (eNB->fh_asynch) eNB->fh_asynch(eNB,&frame,&subframe); - else AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function); - - } - - eNB_thread_asynch_rxtx_status=0; - return(&eNB_thread_asynch_rxtx_status); -} - - - - - -void rx_rf(RU_t *ru,int *frame,int *subframe) { - - eNB_proc_t *proc = &eNB->proc; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; - unsigned int rxs,txs; - int i; - int tx_sfoffset = 3;//(eNB->single_thread_flag == 1) ? 3 : 3; - if (proc->first_rx==0) { - - // Transmit TX buffer based on timestamp from RX - // printf("trx_write -> USRP TS %llu (sf %d)\n", (ru->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (ru->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - // prepare tx buffer pointers - - for (i=0; i<fp->nb_antennas_tx; i++) - txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti]; - - txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, - ru->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance, - txp, - fp->samples_per_tti, - fp->nb_antennas_tx, - 1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - - - - if (txs != fp->samples_per_tti) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); - exit_fun( "problem transmitting samples" ); - } - } - - for (i=0; i<fp->nb_antennas_rx; i++) - rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - - rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, - &(ru->timestamp_rx), - rxp, - fp->samples_per_tti, - fp->nb_antennas_rx); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - if (proc->first_rx == 1) - eNB->ts_offset = ru->timestamp_rx; - - proc->frame_rx = ((ru->timestamp_rx-eNB->ts_offset) / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = ((ru->timestamp_rx-eNB->ts_offset) / fp->samples_per_tti)%10; - // synchronize first reception to frame 0 subframe 0 - - ru->timestamp_tx = ru->timestamp_rx+(4*fp->samples_per_tti); - //printf("trx_read <- USRP TS %llu (sf %d, f %d, first_rx %d)\n", ru->timestamp_rx,proc->subframe_rx,proc->frame_rx,proc->first_rx); - - if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",ru->timestamp_rx,proc->subframe_rx,*subframe); - exit_fun("Exiting"); - } - - if (proc->frame_rx != *frame) { - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",ru->timestamp_rx,proc->frame_rx,*frame); - exit_fun("Exiting"); - } - } else { - proc->first_rx = 0; - *frame = proc->frame_rx; - *subframe = proc->subframe_rx; - } - - //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, ru->timestamp_rx&0xffffffff ); - - if (rxs != fp->samples_per_tti) - exit_fun( "problem receiving samples" ); - - - -} - -void rx_fh_if5(RU_t *ru,int *frame, int *subframe) { - - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; - - recv_IF5(eNB, &ru->timestamp_rx, *subframe, IF5_RRH_GW_UL); - - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - - if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); - exit_fun("Exiting"); - } - - if (proc->frame_rx != *frame) { - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); - exit_fun("Exiting"); - } - } else { - proc->first_rx = 0; - *frame = proc->frame_rx; - *subframe = proc->subframe_rx; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - -} - - -void rx_fh_if4p5(RU_t *ru,int *frame,int *subframe) { - - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; - - int prach_rx; - - uint16_t packet_type; - uint32_t symbol_number=0; - uint32_t symbol_mask, symbol_mask_full; - - symbol_mask = 0; - symbol_mask_full = (1<<fp->symbols_per_tti)-1; - prach_rx = 0; - - do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); - - if (packet_type == IF4p5_PULFFT) { - symbol_mask = symbol_mask | (1<<symbol_number); - prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0; - } else if (packet_type == IF4p5_PRACH) { - prach_rx = 0; - } - - } while( (symbol_mask != symbol_mask_full) || (prach_rx == 1)); - - //caculate timestamp_rx, timestamp_tx based on frame and subframe - proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ; - proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); - - - if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d,CCid %d)\n",proc->subframe_rx,*subframe,eNB->CC_id); - exit_fun("Exiting"); - } - if (proc->frame_rx != *frame) { - LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d,CCid %d)\n",proc->frame_rx,*frame,eNB->CC_id); - exit_fun("Exiting"); - } - } else { - proc->first_rx = 0; - *frame = proc->frame_rx; - *subframe = proc->subframe_rx; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - -} - -void rx_fh_slave(RU_t *ru,int *frame,int *subframe) { - // This case is for synchronization to another thread - // it just waits for an external event. The actual rx_fh is handle by the asynchronous RX thread - eNB_proc_t *proc=&eNB->proc; - - if (wait_on_condition(&proc->mutex_FH,&proc->cond_FH,&proc->instance_cnt_FH,"rx_fh_slave") < 0) - return; - - release_thread(&proc->mutex_FH,&proc->instance_cnt_FH,"rx_fh_slave"); - - -} - - -int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *fp) { - - int i; - struct timespec wait; - - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - /* accept some delay in processing - up to 5ms */ - for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { - LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx); - usleep(500); - } - if (proc_rxtx->instance_cnt_rxtx == 0) { - exit_fun( "TX thread busy" ); - return(-1); - } - - // wake up TX for subframe n+4 - // lock the TX mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); - exit_fun( "error locking mutex_rxtx" ); - return(-1); - } - - ++proc_rxtx->instance_cnt_rxtx; - - // We have just received and processed the common part of a subframe, say n. - // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired - // transmitted timestamp of the next TX slot (first). - // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, - // we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti, - // and proc->subframe_tx = proc->subframe_rx+4 - proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); - proc_rxtx->frame_rx = proc->frame_rx; - proc_rxtx->subframe_rx = proc->subframe_rx; - proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; - proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10; - - // the thread can now be woken up - if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); - - return(0); -} - -void wakeup_slaves(ru_proc_t *proc) { - - int i; - struct timespec wait; - - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - for (i=0;i<proc->num_slaves;i++) { - ru_proc_t *slave_proc = proc->slave_proc[i]; - // wake up slave FH thread - // lock the FH mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id); - exit_fun( "error locking mutex_rxtx" ); - break; - } - - int cnt_slave = ++slave_proc->instance_cnt_FH; - slave_proc->frame_rx = proc->frame_rx; - slave_proc->subframe_rx = proc->subframe_rx; - slave_proc->timestamp_rx = proc->timestamp_rx; - slave_proc->timestamp_tx = proc->timestamp_tx; - - pthread_mutex_unlock( &slave_proc->mutex_FH ); - - if (cnt_slave == 0) { - // the thread was presumably waiting where it should and can now be woken up - if (pthread_cond_signal(&slave_proc->cond_FH) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id); - exit_fun( "ERROR pthread_cond_signal" ); - break; - } - } else { - LOG_W( PHY,"[RU] Frame %d, slave CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave); - exit_fun( "FH thread busy" ); - break; - } - } -} - -/*! - * \brief The Fronthaul thread of RRU/RAU/RCC/eNB - * In the case of RRU/eNB, handles interface with external RF - * In the case of RAU/RCC, handles fronthaul interface with RRU/RAU - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ - -/*! - * \brief The prach receive thread of eNB. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -static void* eNB_thread_prach( void* param ) { - static int eNB_thread_prach_status; - - eNB_proc_t *proc = (eNB_proc_t*)param; - PHY_VARS_eNB *eNB= PHY_vars_eNB_g[0][proc->CC_id]; - - // set default return value - eNB_thread_prach_status = 0; - - thread_top_init("eNB_thread_prach",1,500000L,1000000L,20000000L); - - while (!oai_exit) { - - if (oai_exit) break; - - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; - - prach_procedures(eNB); - - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; - } - - printf( "Exiting eNB thread PRACH\n"); - - eNB_thread_prach_status = 0; - return &eNB_thread_prach_status; -} - -static void* ru_thread( void* param ) { - - static int ru_thread_status; - - RU_t *ru=(RU_t*)param; - ru_proc_t *proc=ru->proc; - int subframe=0, frame=0; - - // set default return value - ru_thread_status = 0; - - thread_top_init("ru_thread",0,870000,1000000,1000000); - - wait_sync("ru_thread"); - - /* -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - if (eNB->node_function < NGFI_RRU_IF5) - wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB); -#endif - */ - - // wakeup asnych_rxtx thread because the devices are ready at this point - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx=0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); - - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices - while (!oai_exit) { - - // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. - // They are set on the first rx/tx in the underly FH routines. - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } - - LOG_D(PHY,"RU thread %p (proc %p), frame %d (%p), subframe %d (%p)\n", - pthread_self(), proc, frame,&frame,subframe,&subframe); - - // synchronization on FH interface, acquire signals/data and block - if (ru->rx_fh) ru->rx_fh(ru,&frame,&subframe); - else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function); - - T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); - /* - // wakeup correct eNB processes - proc_rxtx->subframe_rx = proc->subframe_rx; - proc_rxtx->frame_rx = proc->frame_rx; - proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10; - proc_rxtx->frame_tx = (proc->subframe_rx < 6) ? proc->frame_rx : (proc->frame_rx+1)&1023; - proc_rxtx->timestamp_tx = proc->timestamp_tx; - */ - // At this point, all information for subframe has been received on FH interface - // If this proc is to provide synchronization, do so - wakeup_slaves(proc); - - // wait until eNBs are finished subframe RX n and TX n+4 - - // if (rxtx(eNB,proc_rxtx,"eNB_thread_single") < 0) break; - } - - - printf( "Exiting ru_thread \n"); - - ru_thread_status = 0; - return &ru_thread_status; - -} - -extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *);_ -extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); -extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); - -void init_eNB_proc(int inst) { - - int i; - int CC_id; - PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *proc_rxtx; - pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te; - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - eNB = PHY_vars_eNB_g[inst][CC_id]; - LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]); - proc = &eNB->proc; - - proc_rxtx = proc->proc_rxtx; - proc_rxtx[0].instance_cnt_rxtx = -1; - proc_rxtx[1].instance_cnt_rxtx = -1; - proc->instance_cnt_prach = -1; - proc->instance_cnt_asynch_rxtx = -1; - proc->CC_id = CC_id; - - proc->first_rx=1; - proc->first_tx=1; - - pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); - pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); - pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); - pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); - - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - - pthread_attr_init( &proc->attr_prach); - pthread_attr_init( &proc->attr_asynch_rxtx); - pthread_attr_init( &proc->attr_single); - pthread_attr_init( &proc->attr_fep); - pthread_attr_init( &proc->attr_td); - pthread_attr_init( &proc->attr_te); - pthread_attr_init( &proc_rxtx[0].attr_rxtx); - pthread_attr_init( &proc_rxtx[1].attr_rxtx); -#ifndef DEADLINE_SCHEDULER - attr0 = &proc_rxtx[0].attr_rxtx; - attr1 = &proc_rxtx[1].attr_rxtx; - attr_prach = &proc->attr_prach; - attr_asynch = &proc->attr_asynch_rxtx; - attr_single = &proc->attr_single; - attr_fep = &proc->attr_fep; - attr_td = &proc->attr_td; - attr_te = &proc->attr_te; -#endif - - if (eNB->single_thread_flag==0) { - pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); - pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); - } - else { - pthread_create(&proc->pthread_single, attr_single, eNB_thread_single, &eNB->proc); - init_fep_thread(eNB,attr_fep); - init_td_thread(eNB,attr_td); - init_te_thread(eNB,attr_te); - } - pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc ); - if ((eNB->node_timing == synch_to_other) || - (eNB->node_function == NGFI_RRU_IF5) || - (eNB->node_function == NGFI_RRU_IF4p5)) - pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, eNB_thread_asynch_rxtx, &eNB->proc ); - - char name[16]; - if (eNB->single_thread_flag == 0) { - snprintf( name, sizeof(name), "RXTX0 %d", i ); - pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); - snprintf( name, sizeof(name), "RXTX1 %d", i ); - pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); - } - else { - snprintf( name, sizeof(name), " %d", i ); - pthread_setname_np( proc->pthread_single, name ); - } - } - - //for multiple CCs: setup master and slaves - /* - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - eNB = PHY_vars_eNB_g[inst][CC_id]; - - if (eNB->node_timing == synch_to_ext_device) { //master - eNB->proc.num_slaves = MAX_NUM_CCs-1; - eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*)); - - for (i=0; i< eNB->proc.num_slaves; i++) { - if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc); - if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc); - } - } - }*/ - - - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; -} - - - -/*! - * \brief Terminate eNB TX and RX threads. - */ -void kill_eNB_proc(int inst) { - - int *status; - PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *proc_rxtx; - for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - eNB=PHY_vars_eNB_g[inst][CC_id]; - - proc = &eNB->proc; - proc_rxtx = &proc->proc_rxtx[0]; - -#ifdef DEBUG_THREADS - printf( "Killing TX CC_id %d thread %d\n", CC_id, i ); -#endif - - proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race! - proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race! - proc->instance_cnt_prach = 0; - pthread_cond_signal( &proc_rxtx[0].cond_rxtx ); - pthread_cond_signal( &proc_rxtx[1].cond_rxtx ); - pthread_cond_signal( &proc->cond_prach ); - pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - - pthread_join( proc->pthread_FH, (void**)&status ); - pthread_mutex_destroy( &proc->mutex_FH ); - pthread_cond_destroy( &proc->cond_FH ); - - pthread_join( proc->pthread_prach, (void**)&status ); - pthread_mutex_destroy( &proc->mutex_prach ); - pthread_cond_destroy( &proc->cond_prach ); - - int i; - for (i=0;i<2;i++) { - pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); - pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); - pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); - } - } -} - - -/* this function maps the phy_vars_eNB tx and rx buffers to the available rf chains. - Each rf chain is is addressed by the card number and the chain on the card. The - rf_map specifies for each CC, on which rf chain the mapping should start. Multiple - antennas are mapped to successive RF chains on the same card. */ -int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg) { - - int i, CC_id; - int j; - - uint16_t N_TA_offset = 0; - - LTE_DL_FRAME_PARMS *frame_parms; - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (phy_vars_eNB[CC_id]) { - frame_parms = &(phy_vars_eNB[CC_id]->frame_parms); - printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms); - } else { - printf("phy_vars_eNB[%d] not initialized\n", CC_id); - return(-1); - } - - if (frame_parms->frame_type == TDD) { - if (frame_parms->N_RB_DL == 100) - N_TA_offset = 624; - else if (frame_parms->N_RB_DL == 50) - N_TA_offset = 624/2; - else if (frame_parms->N_RB_DL == 25) - N_TA_offset = 624/4; - } - - - - if (openair0_cfg[CC_id].mmapped_dma == 1) { - // replace RX signal buffers with mmaped HW versions - - for (i=0; i<frame_parms->nb_antennas_rx; i++) { - printf("Mapping eNB CC_id %d, rx_ant %d\n",CC_id,i); - free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]); - phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[CC_id].rxbase[i]; - - - - printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]); - - for (j=0; j<16; j++) { - printf("rxbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j]); - phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j] = 16-j; - } - } - - for (i=0; i<frame_parms->nb_antennas_tx; i++) { - printf("Mapping eNB CC_id %d, tx_ant %d\n",CC_id,i); - free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); - phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[CC_id].txbase[i];//(int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].dac_head[rf_map[CC_id].chain+i]; - - printf("txdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); - - for (j=0; j<16; j++) { - printf("txbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j]); - phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j] = 16-j; - } - } - } - else { // not memory-mapped DMA - - - rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); - txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*)); - - for (i=0; i<frame_parms->nb_antennas_rx; i++) { - free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]); - rxdata[i] = (int32_t*)(32 + malloc16(32+frame_parms->samples_per_tti*10*sizeof(int32_t))); // FIXME broken memory allocation - phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory - memset(rxdata[i], 0, frame_parms->samples_per_tti*10*sizeof(int32_t)); - printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i],rxdata[i],N_TA_offset); - } - - for (i=0; i<frame_parms->nb_antennas_tx; i++) { - free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); - txdata[i] = (int32_t*)(32 + malloc16(32 + frame_parms->samples_per_tti*10*sizeof(int32_t))); // FIXME broken memory allocation - phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = txdata[i]; - memset(txdata[i],0, frame_parms->samples_per_tti*10*sizeof(int32_t)); - printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); - } - } - } - - return(0); -} - - -void reset_opp_meas(void) { - - int sfn; - reset_meas(&softmodem_stats_mt); - reset_meas(&softmodem_stats_hw); - - for (sfn=0; sfn < 10; sfn++) { - reset_meas(&softmodem_stats_rxtx_sf); - reset_meas(&softmodem_stats_rx_sf); - } -} - - -void print_opp_meas(void) { - - int sfn=0; - print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL); - print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL); - - for (sfn=0; sfn < 10; sfn++) { - print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL); - print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL); - } -} - -int start_if(PHY_VARS_eNB *eNB) { - return(eNB->ifdevice.trx_start_func(&eNB->ifdevice)); -} - -int start_rf(PHY_VARS_eNB *eNB) { - return(eNB->rfdevice.trx_start_func(&eNB->rfdevice)); -} - -extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB); -extern void eNB_fep_full(PHY_VARS_eNB *eNB); -extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB); -extern void do_prach(PHY_VARS_eNB *eNB); - -void init_RU(RAN_CONTEXT *rc, eNB_func_t node_function, RU_if_in_t ru_if_in[], RU_if_timing_t ru_if_timing[], eth_params_t *eth_params) { - - int ru_id; - - for (ru_id=0;ru_id<rc->nb_RU;ru_id++) { - ru = &rc.ru_desc[ru_id]; - ru->RU_if_in[ru_id] = ru_if_in[ru_id]; - ru->RU_if_timing = ru_if_timing[ru_id]; - LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s)\n",ru_id,ru_if_types[ru_if_in[ru_id]],eNB_timing[ru_timing[ru_id]]); - - switch (ru->RU_if_in[ru_id]) { - case LOCAL_RF: // this is an RRU or eNB with integrated RF - if (node_function == NGFI_RRU_IF5) { - ru->do_prach = NULL; // no prach processing - ru->fep_rx = eNB_fep_rru_if5; // need only to do send_IF5 - ru->fep_tx = NULL; // nothing (this is a time-domain signal) - ru->fh_asynch = fh_if5_asynch_DL; // TX packets come asynchronously - ru->start_if = start_if; // need to start the if interface for if5 - ru->ifdevice.host_type = RRH_HOST; - ru->rfdevice.host_type = RRH_HOST; - } - else if (node_function == NGFI_RRU_IF4p5) { - ru->do_prach = do_prach; // IF4p5 needs to do part of prach processing in RRU - ru->fep_rx = ru_fep_full; // this is DFTs + send_IF4p5 - ru->fep_tx = ru_fep_idft; // this is fep with idft only (no precoding in RRU) - ru->fh_asynch = fh_if4p5_asynch_DL; // TX packets come asynchronously - ru->start_if = start_if; // need to start the if interface for if4p5 - ru->ifdevice.host_type = RRH_HOST; - ru->rfdevice.host_type = RRH_HOST; - } - else if (node_function == eNodeB_3GPP) { - ru->do_prach = NULL; // prach is done completely in eNB processing - ru->fep_rx = eNB_fep_full; // this is DFTs only - ru->fep_tx = pc_fep_idft_prec; // this is fep with idft and precoding - ru->fh_asynch = NULL; // no incoming fronthaul - ru->start_if = NULL; // no if interface - ru->rfdevice.host_type = BBU_HOST; - } - ru->rx_fh = rx_rf; // local synchronous RF RX - ru->tx_fh = NULL; // nothing connected directly to radio - ru->start_rf = start_rf; // need to start the local RF interface - - ret = openair0_device_load(&ru->rfdevice, &openair0_cfg[ru_id]); - if (setup_RU_buffers(rc,ru_id,&openair0_cfg[ru_id])!=0) { - printf("Exiting, cannot initialize eNodeB Buffers\n"); - exit(-1); - } - break; - - case REMOTE_IF5: // the remote unit is IF5 RRU - ru->do_prach = NULL; // no prach processing in RU - ru->fep_rx = eNB_fep_full; // this is DFTs - ru->fep_tx = pc_fep_tx_rru_if5; // need to do transmit Precoding + FEP + IF5 fronthaul - if (ru->RU_if_timing == synch_to_other) { - ru->rx_fh = rx_fh_slave; // synchronize to master - ru->tx_fh = tx_fh_if5_mobipass; // use send_IF5 for mobipass - ru->fh_asynch = fh_if5_asynch_UL; // UL is asynchronous - } - else { - ru->tx_fh = tx_fh_if5; // synchronous IF5 transmission - ru->rx_fh = rx_fh_if5; // synchronous IF5 reception - ru->fh_asynch = NULL; // no asynchronous UL - } - ru->start_rf = NULL; // no local RF - ru->start_if = start_if; // need to start if interface for IF5 - ru->fh_asynch = fh_if5_asynch_DL; - ru->ifdevice.host_type = BBU_HOST; - - ret = openair0_transport_load(&ru->ifdevice, &openair0_cfg[ru_id], (eth_params+ru_id)); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - break; - - case REMOTE_IF4p5: - ru->do_prach = NULL; // no prach processing in RU - ru->fep_rx = eNB_fep_full; // this is DFTs - ru->fep_tx = proc_tx_high; // need to do transmit Precoding + IF4p5 fronthaul (no IDFTs) - ru->tx_fh = tx_fh_if4p5; // synchronous IF5 transmission - ru->rx_fh = rx_fh_if4p5; // synchronous IF5 reception - ru->fh_asynch = (ru->RU_if_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL; // asynchronous UL if synch_to_other - - ru->start_rf = NULL; // no local RF - ru->start_if = start_if; // need to start if interface for IF4p5 - ru->fh_asynch = fh_if5_asynch_DL; - ru->ifdevice.host_type = BBU_HOST; - - ret = openair0_transport_load(&ru->ifdevice, &openair0_cfg[ru_id], (eth_params+ru_id)); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - - malloc_IF4p5_buffer(eNB); - - break; - - case REMOTE_IF1pp: - LOG_E(PHY,"RU with IF1pp not supported yet\n"); - break; - - } // switch on interface type - - } // for ru_id - - sleep(1); - LOG_D(HW,"[lte-softmodem.c] eNB threads created\n"); - - -} - -void init_RAN(RAN_CONTEXT *rc,eNB_func_t node_function[], eNB_timing_t node_timing[],eth_params_t *eth_params,int single_thread_flag) { - - int CC_id; - int inst; - PHY_VARS_eNB *eNB; - int ret; - - for (inst=0;inst<rc->nb_inst;inst++) { - for (CC_id=0;CC_id<rc->nb_CC;CC_id++) { - eNB = rc->eNB[inst][CC_id]; - if (eNB) { - eNB->node_function = node_function[CC_id]; - eNB->node_timing = node_timing[CC_id]; - eNB->abstraction_flag = 0; - eNB->single_thread_flag = single_thread_flag; - eNB->ts_offset = 0; - LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]); - - switch (node_function[CC_id]) { - case NGFI_RRU_IF5: - eNB->td = NULL; - eNB->te = NULL; - eNB->proc_uespec_rx = NULL; - eNB->proc_tx = NULL; - break; - case NGFI_RRU_IF4p5: - eNB->td = NULL; - eNB->te = NULL; - eNB->proc_uespec_rx = NULL; - eNB->proc_tx = NULL;//proc_tx_rru_if4p5; - break; - case eNodeB_3GPP: - eNB->do_prach = do_prach; - eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; - eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; - eNB->proc_tx = proc_tx_full; - break; - case eNodeB_3GPP_BBU: - eNB->do_prach = do_prach; - eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; - eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; - eNB->proc_tx = proc_tx_full; - break; - case NGFI_RCC_IF4p5: - eNB->do_prach = do_prach; - eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; - eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; - eNB->proc_tx = proc_tx_high; - break; - case NGFI_RAU_IF4p5: - eNB->do_prach = do_prach; - eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; - eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; - eNB->proc_tx = proc_tx_high; - break; - } - // initialize eNB procedure threads if needed - init_eNB_proc(rc,inst); - } - } - } - sleep(1); - LOG_D(HW,"[lte-softmodem.c] eNB threads created\n"); - - -} - - -void stop_eNB(int nb_inst) { - - for (int inst=0;inst<nb_inst;inst++) { - printf("Killing eNB %d processing threads\n",inst); - kill_eNB_proc(inst); - } -} diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 11e421d6f037324ad27d4c45343c45dfe24be79d..0740bc8ed94b56484aba8fba18eaf7fa7942271b 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -60,7 +60,7 @@ #include "PHY/types.h" -#include "PHY/defs.h" +#include "PHY/defs_common.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all @@ -70,22 +70,19 @@ #include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if5_tools.h" -#include "PHY/extern.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/extern.h" +#include "PHY/phy_extern.h" +#include "LAYER2/MAC/mac_extern.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "SCHED/sched_eNB.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" +#include "PHY/INIT/phy_init.h" -#include "../../SIMU/USER/init_lte.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/proto.h" -#include "RRC/LITE/extern.h" -#include "PHY_INTERFACE/extern.h" - -#ifdef SMBV -#include "PHY/TOOLS/smbv.h" -unsigned short config_frames[4] = {2,9,11,13}; -#endif #include "UTIL/LOG/log_extern.h" #include "UTIL/OTG/otg_tx.h" #include "UTIL/OTG/otg_externs.h" @@ -95,6 +92,13 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "enb_config.h" //#include "PHY/TOOLS/time_meas.h" +/* these variables have to be defined before including ENB_APP/enb_paramdef.h */ +static int DEFBANDS[] = {7}; +static int DEFENBS[] = {0}; + +#include "ENB_APP/enb_paramdef.h" +#include "common/config/config_userapi.h" + #ifndef OPENAIR2 #include "UTIL/OTG/otg_extern.h" #endif @@ -113,12 +117,16 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "pdcp.h" extern volatile int oai_exit; +extern int emulate_rf; +extern int numerology; +extern int fepw; extern void phy_init_RU(RU_t*); +extern void phy_free_RU(RU_t*); void init_RU(char*); -void stop_RU(RU_t *ru); +void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); void configure_ru(int idx, @@ -517,7 +525,7 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) { } if (packet_type == IF4p5_PULFFT) symbol_mask &= (~(1<<symbol_number)); else if (packet_type == IF4p5_PRACH) prach_rx &= (~0x1); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) else if (packet_type == IF4p5_PRACH_BR_CE0) prach_rx &= (~0x2); else if (packet_type == IF4p5_PRACH_BR_CE1) prach_rx &= (~0x4); else if (packet_type == IF4p5_PRACH_BR_CE2) prach_rx &= (~0x8); @@ -628,7 +636,8 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { if ((frame_tx == 0)&&(subframe_tx == 0)) proc->frame_tx_unwrap += 1024; - proc->timestamp_tx = (((frame_tx + proc->frame_tx_unwrap) * 10) + subframe_tx) * fp->samples_per_tti; + proc->timestamp_tx = ((((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * 10) + (uint64_t)subframe_tx) * (uint64_t)fp->samples_per_tti; + LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,subframe_tx); // dump VCD output for first RU in list if (ru == RC.ru[0]) { @@ -685,6 +694,34 @@ volatile late_control_e late_control=STATE_BURST_NORMAL; /* add fail safe for late command end */ +static void* emulatedRF_thread(void* param) { + RU_proc_t *proc = (RU_proc_t *) param; + int microsec = 500; // length of time to sleep, in miliseconds + struct timespec req = {0}; + req.tv_sec = 0; + req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2; + cpu_set_t cpuset; + CPU_SET(1,&cpuset); + pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + + int policy; + struct sched_param sparam; + memset(&sparam, 0, sizeof(sparam)); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); + policy = SCHED_FIFO ; + pthread_setschedparam(pthread_self(), policy, &sparam); + + wait_sync("emulatedRF_thread"); + while(!oai_exit){ + nanosleep(&req, (struct timespec *)NULL); + pthread_mutex_lock(&proc->mutex_emulateRF); + ++proc->instance_cnt_emulateRF; + pthread_mutex_unlock(&proc->mutex_emulateRF); + pthread_cond_signal(&proc->cond_emulateRF); + } + return 0; +} + void rx_rf(RU_t *ru,int *frame,int *subframe) { RU_proc_t *proc = &ru->proc; @@ -692,7 +729,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { void *rxp[ru->nb_rx]; unsigned int rxs; int i; - openair0_timestamp ts,old_ts; + openair0_timestamp ts=0,old_ts=0; for (i=0; i<ru->nb_rx; i++) rxp[i] = (void*)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; @@ -700,12 +737,18 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); old_ts = proc->timestamp_rx; - - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, + if(emulate_rf){ + wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); + release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); + rxs = fp->samples_per_tti; + } + else{ + rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, fp->samples_per_tti, ru->nb_rx); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); @@ -724,7 +767,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { } else { if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { - LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset); + //LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset); ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); proc->timestamp_rx = ts-ru->ts_offset; } @@ -739,10 +782,18 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { proc->subframe_phy_tx = (proc->subframe_rx+3)%10; proc->frame_phy_tx = (proc->subframe_rx>6) ? (proc->frame_rx+1)&1023 : proc->frame_rx; #else +#if 0 + /* TODO for Fujitsu: fix this somehow */ proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti); proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10; proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; -#endif +#endif +#endif + + //proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti); + //proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10; + //proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; + LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n", ru->idx, 0, @@ -753,8 +804,6 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { if (ru == RC.ru[0]) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); } if (proc->first_rx == 0) { @@ -837,6 +886,9 @@ void tx_rf(RU_t *ru) { for (i=0; i<ru->nb_tx; i++) txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension]; + +#if 0 + /* TODO for Fujitsu: fix this somehow */ /* add fail safe for late command */ if(late_control!=STATE_BURST_NORMAL){//stop burst switch (late_control) { @@ -864,7 +916,11 @@ void tx_rf(RU_t *ru) { } } /* add fail safe for late command end */ - +#endif + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers @@ -907,7 +963,7 @@ static void* ru_thread_asynch_rxtx( void* param ) { int subframe=0, frame=0; - thread_top_init("ru_thread_asynch_rxtx",1,870000L,1000000L,1000000L); + thread_top_init("ru_thread_asynch_rxtx",1,870000,1000000,1000000); // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe @@ -933,7 +989,7 @@ static void* ru_thread_asynch_rxtx( void* param ) { subframe++; } LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); - // asynchronous receive from south (Mobipass) + // asynchronous receive from south (Mobipass) if (ru->fh_south_asynch_in) ru->fh_south_asynch_in(ru,&frame,&subframe); // asynchronous receive from north (RRU IF4/IF5) else if (ru->fh_north_asynch_in) { @@ -959,6 +1015,7 @@ void wakeup_slaves(RU_proc_t *proc) { wait.tv_nsec=5000000L; for (i=0;i<proc->num_slaves;i++) { + //printf("////////////////////calling for slave thrads\n");////////////////////////******** RU_proc_t *slave_proc = proc->slave_proc[i]; // wake up slave FH thread // lock the FH mutex and make sure the thread is ready @@ -1006,7 +1063,8 @@ static void* ru_thread_prach( void* param ) { // set default return value ru_thread_prach_status = 0; - thread_top_init("ru_thread_prach",1,500000L,1000000L,20000000L); + thread_top_init("ru_thread_prach",1,500000,1000000,20000000); + //wait_sync("ru_thread_prach"); while (RC.ru_mask>0) { usleep(1e6); @@ -1019,13 +1077,27 @@ static void* ru_thread_prach( void* param ) { if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - prach_procedures( + if (ru->eNB_list[0]){ + prach_procedures( ru->eNB_list[0] -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif ); - + } + else { + rx_prach(NULL, + ru, + NULL, + NULL, + NULL, + proc->frame_prach, + 0 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0 +#endif + ); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; } @@ -1036,7 +1108,7 @@ static void* ru_thread_prach( void* param ) { return &ru_thread_prach_status; } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) static void* ru_thread_prach_br( void* param ) { static int ru_thread_prach_status; @@ -1047,7 +1119,8 @@ static void* ru_thread_prach_br( void* param ) { // set default return value ru_thread_prach_status = 0; - thread_top_init("ru_thread_prach_br",1,500000L,1000000L,20000000L); + thread_top_init("ru_thread_prach_br",1,500000,1000000,20000000); + //wait_sync("ru_thread_prach_br"); while (!oai_exit) { @@ -1177,13 +1250,14 @@ void wakeup_eNBs(RU_t *ru) { LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top); - if (ru->num_eNB==1 && ru->eNB_top!=0) { - // call eNB function directly + if (ru->num_eNB==1 && ru->eNB_top!=0 && get_nprocs() <= 4) { + // call eNB function directly + char string[20]; sprintf(string,"Incoming RU %d",ru->idx); LOG_D(PHY,"RU %d Call eNB_top\n",ru->idx); - ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); + ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string,ru); } else { @@ -1192,7 +1266,7 @@ void wakeup_eNBs(RU_t *ru) { for (i=0;i<ru->num_eNB;i++) { LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx); - + eNB_list[i]->proc.ru_proc = &ru->proc; if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) { LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); @@ -1219,9 +1293,10 @@ static inline int wakeup_prach_ru(RU_t *ru) { ru->proc.subframe_prach = ru->proc.subframe_rx; // DJP - think prach_procedures() is looking at eNB frame_prach - ru->eNB_list[0]->proc.frame_prach = ru->proc.frame_rx; - ru->eNB_list[0]->proc.subframe_prach = ru->proc.subframe_rx; - + if (ru->eNB_list[0]) { + ru->eNB_list[0]->proc.frame_prach = ru->proc.frame_rx; + ru->eNB_list[0]->proc.subframe_prach = ru->proc.subframe_rx; + } LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx); // the thread can now be woken up AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n"); @@ -1232,7 +1307,7 @@ static inline int wakeup_prach_ru(RU_t *ru) { return(0); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) static inline int wakeup_prach_ru_br(RU_t *ru) { struct timespec wait; @@ -1268,20 +1343,39 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; openair0_config_t *cfg = &ru->openair0_cfg; + //printf("////////////////numerology in config = %d\n",numerology); if(fp->N_RB_DL == 100) { - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - else { - cfg->sample_rate=30.72e6; + if(numerology == 0){ + if (fp->threequarter_fs) { + cfg->sample_rate=23.04e6; + cfg->samples_per_frame = 230400; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + else { + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + }else if(numerology == 1){ + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + }else if(numerology == 2){ + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 40e6; + cfg->rx_bw = 40e6; + }else{ + printf("Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology); + cfg->sample_rate=30.72e6; cfg->samples_per_frame = 307200; cfg->tx_bw = 10e6; cfg->rx_bw = 10e6; - } + } } else if(fp->N_RB_DL == 50) { cfg->sample_rate=15.36e6; cfg->samples_per_frame = 153600; @@ -1400,7 +1494,7 @@ static void* ru_stats_thread(void* param) { while (!oai_exit) { sleep(1); - if (opp_enabled == 1) { + if (opp_enabled == 1 && fepw) { if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); @@ -1419,6 +1513,60 @@ int first_phy_tx = 1; volatile int16_t phy_tx_txdataF_end; volatile int16_t phy_tx_end; #endif + +static void* ru_thread_tx( void* param ) { + RU_t *ru = (RU_t*)param; + RU_proc_t *proc = &ru->proc; + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + + thread_top_init("ru_thread_tx",1,400000,500000,500000); + + //CPU_SET(5, &cpuset); + //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + //wait_sync("ru_thread_tx"); + + wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); + + printf( "ru_thread_tx ready\n"); + while (!oai_exit) { + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,sched_getcpu()); + if (oai_exit) break; + + + LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); + // wait until eNBs are finished subframe RX n and TX n+4 + wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); + if (oai_exit) break; + + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if(!emulate_rf){ + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if (ru->fh_north_out) ru->fh_north_out(ru); + } + release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); + + pthread_mutex_lock( &proc->mutex_eNBs ); + proc->ru_tx_ready++; + // the thread can now be woken up + if (pthread_cond_signal(&proc->cond_eNBs) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + } + pthread_mutex_unlock( &proc->mutex_eNBs ); + } + release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); + return 0; +} + static void* ru_thread( void* param ) { static int ru_thread_status; @@ -1429,6 +1577,9 @@ static void* ru_thread( void* param ) { int ret; int subframe =9; int frame =1023; + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + // set default return value ru_thread_status = 0; @@ -1441,29 +1592,45 @@ static void* ru_thread( void* param ) { time_req.tv_nsec = 10000; // set default return value - thread_top_init("ru_thread",0,870000,1000000,1000000); + thread_top_init("ru_thread",1,400000,500000,500000); - LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); + //CPU_SET(1, &cpuset); + //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + pthread_setname_np( pthread_self(),"ru thread"); + LOG_I(PHY,"thread ru created id=%ld\n", syscall(__NR_gettid)); + LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); - // Start IF device if any - if (ru->start_if) { - LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); - AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); - if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); - else ret = attach_rru(ru); - AssertFatal(ret==0,"Cannot connect to radio\n"); - } - if (ru->if_south == LOCAL_RF) { // configure RF parameters only - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(&ru->frame_parms,1); - phy_init_RU(ru); - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + if(emulate_rf){ + fill_rf_config(ru,ru->rf_config_file); + init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + } } - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); + else{ + // Start IF device if any + if (ru->start_if) { + LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); + AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); + if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); + else ret = attach_rru(ru); + AssertFatal(ret==0,"Cannot connect to radio\n"); + } + if (ru->if_south == LOCAL_RF) { // configure RF parameters only + fill_rf_config(ru,ru->rf_config_file); + init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); + + + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + } + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + } } LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx); @@ -1472,38 +1639,46 @@ static void* ru_thread( void* param ) { pthread_cond_signal(&RC.ru_cond); pthread_mutex_unlock(&RC.ru_mutex); - wait_sync("ru_thread"); + pthread_mutex_lock(&proc->mutex_FH1); + proc->instance_cnt_FH1 = 0; + pthread_mutex_unlock(&proc->mutex_FH1); + pthread_cond_signal(&proc->cond_FH1); + wait_sync("ru_thread"); - - // Start RF device if any - if (ru->start_rf) { - if (ru->start_rf(ru) != 0) - LOG_E(HW,"Could not start the RF device\n"); - else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); + if(!emulate_rf){ + // Start RF device if any + if (ru->start_rf) { + if (ru->start_rf(ru) != 0) + LOG_E(HW,"Could not start the RF device\n"); + else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); + } + else LOG_I(PHY,"RU %d no rf device\n",ru->idx); + + // if an asnych_rxtx thread exists + // wakeup the thread because the devices are ready at this point + + if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { + pthread_mutex_lock(&proc->mutex_asynch_rxtx); + proc->instance_cnt_asynch_rxtx=0; + pthread_mutex_unlock(&proc->mutex_asynch_rxtx); + pthread_cond_signal(&proc->cond_asynch_rxtx); + } + else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); + + // if this is a slave RRU, try to synchronize on the DL frequency + if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); } - else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - // if an asnych_rxtx thread exists - // wakeup the thread because the devices are ready at this point - - if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx=0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); - } - else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); - - // if this is a slave RRU, try to synchronize on the DL frequency - if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD,sched_getcpu()); + // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. if (subframe==9) { @@ -1543,6 +1718,8 @@ static void* ru_thread( void* param ) { } first_phy_tx = 0; #endif + +/* LOG_D(PHY,"AFTER fh_south_in - SFN/SF:%d%d RU->proc[RX:%d%d TX:%d%d] RC.eNB[0][0]:[RX:%d%d TX(SFN):%d]\n", frame,subframe, proc->frame_rx,proc->subframe_rx, @@ -1554,11 +1731,11 @@ static void* ru_thread( void* param ) { ru->do_prach, is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx), proc->frame_rx,proc->subframe_rx); - +*/ if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) { wakeup_prach_ru(ru); } -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) { wakeup_prach_ru_br(ru); } @@ -1605,11 +1782,30 @@ static void* ru_thread( void* param ) { // wakeup all eNB processes waiting for this RU if (ru->num_eNB>0) wakeup_eNBs(ru); + + if(get_nprocs() <= 4){ + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + if(!emulate_rf){ + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if (ru->fh_north_out) ru->fh_north_out(ru); + } + } +#if 0 + /* TODO for Fujitsu: fix this somehow */ // wait until eNBs are finished subframe RX n and TX n+sf_ahead wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread"); +#endif +#if 0 + /* TODO for Fujitsu: fix this somehow */ #ifndef PHY_TX_THREAD // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1625,12 +1821,19 @@ static void* ru_thread( void* param ) { nanosleep(&time_req,&time_rem); continue; } +#endif #endif } printf( "Exiting ru_thread \n"); - + + if (ru->stop_rf != NULL) { + if (ru->stop_rf(ru) != 0) + LOG_E(HW,"Could not stop the RF device\n"); + else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); + } + ru_thread_status = 0; return &ru_thread_status; @@ -1709,8 +1912,6 @@ void *ru_thread_synch(void *arg) { if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break; } // oai_exit - lte_sync_time_free(); - ru_thread_synch_status = 0; return &ru_thread_synch_status; @@ -1887,6 +2088,12 @@ int start_rf(RU_t *ru) { return(ru->rfdevice.trx_start_func(&ru->rfdevice)); } +int stop_rf(RU_t *ru) +{ + ru->rfdevice.trx_end_func(&ru->rfdevice); + return 0; +} + extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); extern void feptx_ofdm(RU_t *ru); @@ -1899,9 +2106,9 @@ void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; - pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL; + pthread_attr_t *attr_FH=NULL,*attr_FH1=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL,*attr_emulateRF=NULL; //pthread_attr_t *attr_fep=NULL; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_attr_t *attr_prach_br=NULL; #endif char name[100]; @@ -1914,14 +2121,19 @@ void init_RU_proc(RU_t *ru) { proc->ru = ru; proc->instance_cnt_prach = -1; - proc->instance_cnt_synch = -1; ; + proc->instance_cnt_synch = -1; proc->instance_cnt_FH = -1; + proc->instance_cnt_FH1 = -1; + proc->instance_cnt_emulateRF = -1; proc->instance_cnt_asynch_rxtx = -1; + proc->instance_cnt_eNBs = -1; proc->first_rx = 1; proc->first_tx = 1; proc->frame_offset = 0; proc->num_slaves = 0; proc->frame_tx_unwrap = 0; + proc->ru_rx_ready = 0; + proc->ru_tx_ready = 0; for (i=0;i<10;i++) proc->symbol_mask[i]=0; @@ -1929,19 +2141,27 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_synch,NULL); pthread_mutex_init( &proc->mutex_FH,NULL); + pthread_mutex_init( &proc->mutex_FH1,NULL); + pthread_mutex_init( &proc->mutex_emulateRF,NULL); + pthread_mutex_init( &proc->mutex_eNBs, NULL); pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); + pthread_cond_init( &proc->cond_FH1, NULL); + pthread_cond_init( &proc->cond_emulateRF, NULL); pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init( &proc->cond_synch,NULL); + pthread_cond_init( &proc->cond_eNBs, NULL); pthread_attr_init( &proc->attr_FH); + pthread_attr_init( &proc->attr_FH1); + pthread_attr_init( &proc->attr_emulateRF); pthread_attr_init( &proc->attr_prach); pthread_attr_init( &proc->attr_synch); pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init( &proc->attr_fep); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) proc->instance_cnt_prach_br = -1; pthread_mutex_init( &proc->mutex_prach_br, NULL); pthread_cond_init( &proc->cond_prach_br, NULL); @@ -1959,15 +2179,18 @@ void init_RU_proc(RU_t *ru) { #ifndef DEADLINE_SCHEDULER attr_FH = &proc->attr_FH; + attr_FH1 = &proc->attr_FH1; attr_prach = &proc->attr_prach; attr_synch = &proc->attr_synch; attr_asynch = &proc->attr_asynch_rxtx; -#ifdef Rel14 + attr_emulateRF = &proc->attr_emulateRF; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) attr_prach_br = &proc->attr_prach_br; #endif #endif pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru ); + #if defined(PRE_SCD_THREAD) proc->instance_pre_scd = -1; pthread_mutex_init( &proc->mutex_pre_scd, NULL); @@ -1982,9 +2205,15 @@ void init_RU_proc(RU_t *ru) { pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void*)ru ); #endif + if(emulate_rf) + pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc ); + + if (get_nprocs() > 4) + pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru ); + if (ru->function == NGFI_RRU_IF4p5) { pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_create( &proc->pthread_prach_br, attr_prach_br, ru_thread_prach_br, (void*)ru ); #endif if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru); @@ -1992,7 +2221,10 @@ void init_RU_proc(RU_t *ru) { if ((ru->if_timing == synch_to_other) || (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void*)ru ); + (ru->function == NGFI_RRU_IF4p5)) + { + pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void*)ru ); + } snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx ); pthread_setname_np( proc->pthread_FH, name ); @@ -2003,7 +2235,7 @@ void init_RU_proc(RU_t *ru) { pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); } - if (get_nprocs()>=2) { + if (get_nprocs()> 2 && fepw) { if (ru->feprx) init_fep_thread(ru,NULL); if (ru->feptx_ofdm) init_feptx_thread(ru,NULL); } @@ -2011,6 +2243,127 @@ void init_RU_proc(RU_t *ru) { } +void kill_RU_proc(int inst) +{ + RU_t *ru = RC.ru[inst]; + RU_proc_t *proc = &ru->proc; + + pthread_mutex_lock(&proc->mutex_FH); + proc->instance_cnt_FH = 0; + pthread_cond_signal(&proc->cond_FH); + pthread_mutex_unlock(&proc->mutex_FH); + + pthread_mutex_lock(&proc->mutex_FH1); + proc->instance_cnt_FH1 = 0; + pthread_cond_signal(&proc->cond_FH1); + pthread_mutex_unlock(&proc->mutex_FH1); + + pthread_mutex_lock(&proc->mutex_prach); + proc->instance_cnt_prach = 0; + pthread_cond_signal(&proc->cond_prach); + pthread_mutex_unlock(&proc->mutex_prach); + +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + pthread_mutex_lock(&proc->mutex_prach_br); + proc->instance_cnt_prach_br = 0; + pthread_cond_signal(&proc->cond_prach_br); + pthread_mutex_unlock(&proc->mutex_prach_br); +#endif + + pthread_mutex_lock(&proc->mutex_synch); + proc->instance_cnt_synch = 0; + pthread_cond_signal(&proc->cond_synch); + pthread_mutex_unlock(&proc->mutex_synch); + + pthread_mutex_lock(&proc->mutex_eNBs); + proc->ru_tx_ready = 0; + proc->instance_cnt_eNBs = 0; + pthread_cond_signal(&proc->cond_eNBs); + pthread_mutex_unlock(&proc->mutex_eNBs); + + pthread_mutex_lock(&proc->mutex_asynch_rxtx); + proc->instance_cnt_asynch_rxtx = 0; + pthread_cond_signal(&proc->cond_asynch_rxtx); + pthread_mutex_unlock(&proc->mutex_asynch_rxtx); + + LOG_D(PHY, "Joining pthread_FH\n"); + pthread_join(proc->pthread_FH, NULL); + LOG_D(PHY, "Joining pthread_FHTX\n"); + pthread_join(proc->pthread_FH1, NULL); + if (ru->function == NGFI_RRU_IF4p5) { + LOG_D(PHY, "Joining pthread_prach\n"); + pthread_join(proc->pthread_prach, NULL); +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LOG_D(PHY, "Joining pthread_prach_br\n"); + pthread_join(proc->pthread_prach_br, NULL); +#endif + if (ru->is_slave) { + LOG_D(PHY, "Joining pthread_\n"); + pthread_join(proc->pthread_synch, NULL); + } + + if ((ru->if_timing == synch_to_other) || + (ru->function == NGFI_RRU_IF5) || + (ru->function == NGFI_RRU_IF4p5)) { + LOG_D(PHY, "Joining pthread_asynch_rxtx\n"); + pthread_join(proc->pthread_asynch_rxtx, NULL); + } + } + if (get_nprocs() > 2 && fepw) { + if (ru->feprx) { + pthread_mutex_lock(&proc->mutex_fep); + proc->instance_cnt_fep = 0; + pthread_mutex_unlock(&proc->mutex_fep); + pthread_cond_signal(&proc->cond_fep); + LOG_D(PHY, "Joining pthread_fep\n"); + pthread_join(proc->pthread_fep, NULL); + pthread_mutex_destroy(&proc->mutex_fep); + pthread_cond_destroy(&proc->cond_fep); + } + if (ru->feptx_ofdm) { + pthread_mutex_lock(&proc->mutex_feptx); + proc->instance_cnt_feptx = 0; + pthread_mutex_unlock(&proc->mutex_feptx); + pthread_cond_signal(&proc->cond_feptx); + LOG_D(PHY, "Joining pthread_feptx\n"); + pthread_join(proc->pthread_feptx, NULL); + pthread_mutex_destroy(&proc->mutex_feptx); + pthread_cond_destroy(&proc->cond_feptx); + } + } + if (opp_enabled) { + LOG_D(PHY, "Joining ru_stats_thread\n"); + pthread_join(ru->ru_stats_thread, NULL); + } + + pthread_mutex_destroy(&proc->mutex_prach); + pthread_mutex_destroy(&proc->mutex_asynch_rxtx); + pthread_mutex_destroy(&proc->mutex_synch); + pthread_mutex_destroy(&proc->mutex_FH); + pthread_mutex_destroy(&proc->mutex_FH1); + pthread_mutex_destroy(&proc->mutex_eNBs); + + pthread_cond_destroy(&proc->cond_prach); + pthread_cond_destroy(&proc->cond_FH); + pthread_cond_destroy(&proc->cond_FH1); + pthread_cond_destroy(&proc->cond_asynch_rxtx); + pthread_cond_destroy(&proc->cond_synch); + pthread_cond_destroy(&proc->cond_eNBs); + + pthread_attr_destroy(&proc->attr_FH); + pthread_attr_destroy(&proc->attr_FH1); + pthread_attr_destroy(&proc->attr_prach); + pthread_attr_destroy(&proc->attr_synch); + pthread_attr_destroy(&proc->attr_asynch_rxtx); + pthread_attr_destroy(&proc->attr_fep); + +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + pthread_mutex_destroy(&proc->mutex_prach_br); + pthread_cond_destroy(&proc->cond_prach_br); + pthread_attr_destroy(&proc->attr_prach_br); +#endif +} + int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { FH_fmt_options_t fmt = cap->FH_fmt; @@ -2067,7 +2420,6 @@ void configure_ru(int idx, RRU_config_t *config = (RRU_config_t *)arg; RRU_capabilities_t *capabilities = (RRU_capabilities_t*)arg; int ret; - int i; LOG_I(PHY, "Received capabilities from RRU %d\n",idx); @@ -2101,7 +2453,8 @@ void configure_ru(int idx, LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n", config->prach_FreqOffset[0],config->prach_ConfigIndex[0]); -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + int i; for (i=0;i<4;i++) { config->emtc_prach_CElevel_enable[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i]; config->emtc_prach_FreqOffset[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i]; @@ -2137,11 +2490,14 @@ void configure_rru(int idx, ru->frame_parms.threequarter_fs = config->threequarter_fs[0]; ru->frame_parms.pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0]; if (ru->function==NGFI_RRU_IF4p5) { - LOG_I(PHY,"Setting ru->function to NGFI_RRU_IF4p5, prach_FrequOffset %d, prach_ConfigIndex %d\n", - config->prach_FreqOffset[0],config->prach_ConfigIndex[0]); + ru->frame_parms.att_rx = ru->att_rx; + ru->frame_parms.att_tx = ru->att_tx; + + LOG_I(PHY,"Setting ru->function to NGFI_RRU_IF4p5, prach_FrequOffset %d, prach_ConfigIndex %d, att (%d,%d)\n", + config->prach_FreqOffset[0],config->prach_ConfigIndex[0],ru->att_tx,ru->att_rx); ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = config->prach_FreqOffset[0]; ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = config->prach_ConfigIndex[0]; -#ifdef Rel14 +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (int i=0;i<4;i++) { ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] = config->emtc_prach_CElevel_enable[0][i]; ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i] = config->emtc_prach_FreqOffset[0][i]; @@ -2152,6 +2508,8 @@ void configure_rru(int idx, init_frame_parms(&ru->frame_parms,1); + fill_rf_config(ru,ru->rf_config_file); + phy_init_RU(ru); @@ -2187,14 +2545,163 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) { } } +void set_function_spec_param(RU_t *ru) +{ + int ret; + + switch (ru->if_south) { + case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) + if (ru->function == NGFI_RRU_IF5) { // IF5 RRU + ru->do_prach = 0; // no prach processing in RU + ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north + ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously + ru->feprx = NULL; // nothing (this is a time-domain signal) + ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) + ru->feptx_prec = NULL; // nothing (this is a time-domain signal) + ru->start_if = start_if; // need to start the if interface for if5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + } + else if (ru->function == NGFI_RRU_IF4p5) { + ru->do_prach = 1; // do part of prach processing in RU + ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north + ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously + ru->feprx = (get_nprocs()<=2 || !fepw) ? fep_full :ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) + ru->feptx_prec = NULL; + ru->start_if = start_if; // need to start the if interface for if4p5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + malloc_IF4p5_buffer(ru); + } + else if (ru->function == eNodeB_3GPP) { + ru->do_prach = 0; // no prach processing in RU + ru->feprx = (get_nprocs()<=2 || !fepw) ? fep_full : ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding + ru->feptx_prec = feptx_prec; // this is fep with idft and precoding + ru->fh_north_in = NULL; // no incoming fronthaul from north + ru->fh_north_out = NULL; // no outgoing fronthaul to north + ru->start_if = NULL; // no if interface + ru->rfdevice.host_type = RAU_HOST; + } + ru->fh_south_in = rx_rf; // local synchronous RF RX + ru->fh_south_out = tx_rf; // local synchronous RF TX + ru->start_rf = start_rf; // need to start the local RF interface + ru->stop_rf = stop_rf; + printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); +/* + if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise + fill_rf_config(ru,rf_config_file); + init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); + } + + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + }*/ + break; + + case REMOTE_IF5: // the remote unit is IF5 RRU + ru->do_prach = 0; + ru->feprx = (get_nprocs()<=2 || !fepw) ? fep_full : fep_full; // this is frequency-shift + DFTs + ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs + if (ru->if_timing == synch_to_other) { + ru->fh_south_in = fh_slave_south_in; // synchronize to master + ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass + ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous + } + else { + ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception + ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission + ru->fh_south_asynch_in = NULL; // no asynchronous UL + } + ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; + ru->start_if = start_if; // need to start if interface for IF5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; + + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + break; + + case REMOTE_IF4p5: + ru->do_prach = 0; + ru->feprx = NULL; // DFTs + ru->feptx_prec = feptx_prec; // Precoding operation + ru->feptx_ofdm = NULL; // no OFDM mod + ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception + ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission + ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other + ru->fh_north_out = NULL; + ru->fh_north_asynch_in = NULL; + ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; + ru->start_if = start_if; // need to start if interface for IF4p5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; + + ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + + malloc_IF4p5_buffer(ru); + + break; + + default: + LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); + break; + } // switch on interface type +} + extern void RCconfig_RU(void); void init_RU(char *rf_config_file) { int ru_id; RU_t *ru; - int ret; - PHY_VARS_eNB *eNB0; + PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; int i; int CC_id; @@ -2222,22 +2729,23 @@ void init_RU(char *rf_config_file) { // use eNB_list[0] as a reference for RU frame parameters // NOTE: multiple CC_id are not handled here yet! - LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); + if (ru->num_eNB > 0) { + LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); - if (ru->eNB_list[0] == 0) - { - LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__); - ru->eNB_list[0] = RC.eNB[0][0]; - ru->num_eNB=1; + if (ru->eNB_list[0] == 0) + { + LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__); + ru->eNB_list[0] = RC.eNB[0][0]; + ru->num_eNB=1; // // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU // + } + else + { + LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); + } } - else - { - LOG_D(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); - } - eNB0 = ru->eNB_list[0]; LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); LOG_D(PHY, "eNB0:%p\n", eNB0); @@ -2258,154 +2766,9 @@ void init_RU(char *rf_config_file) { } } } - // LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); - - - LOG_D(PHY,"ru->if_south:%d\n", ru->if_south); - - switch (ru->if_south) { - case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) - if (ru->function == NGFI_RRU_IF5) { // IF5 RRU - ru->do_prach = 0; // no prach processing in RU - ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north - ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously - ru->feprx = NULL; // nothing (this is a time-domain signal) - ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) - ru->feptx_prec = NULL; // nothing (this is a time-domain signal) - ru->start_if = start_if; // need to start the if interface for if5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - } - else if (ru->function == NGFI_RRU_IF4p5) { - ru->do_prach = 1; // do part of prach processing in RU - ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north - ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_nprocs()<=2) ? fep_full :ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) - ru->feptx_prec = NULL; - ru->start_if = start_if; // need to start the if interface for if4p5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - malloc_IF4p5_buffer(ru); - } - else if (ru->function == eNodeB_3GPP) { - ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_nprocs()<=2) ? fep_full : ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding - ru->feptx_prec = feptx_prec; // this is fep with idft and precoding - ru->fh_north_in = NULL; // no incoming fronthaul from north - ru->fh_north_out = NULL; // no outgoing fronthaul to north - ru->start_if = NULL; // no if interface - ru->rfdevice.host_type = RAU_HOST; - } - ru->fh_south_in = rx_rf; // local synchronous RF RX - ru->fh_south_out = tx_rf; // local synchronous RF TX - ru->start_rf = start_rf; // need to start the local RF interface - printf("configuring ru_id %d (start_rf %p)\n",ru_id,start_rf); -/* - if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise - fill_rf_config(ru,rf_config_file); - init_frame_parms(&ru->frame_parms,1); - phy_init_RU(ru); - } - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - } - */ - break; - - case REMOTE_IF5: // the remote unit is IF5 RRU - ru->do_prach = 0; - ru->feprx = (get_nprocs()<=2) ? fep_full : fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs - if (ru->if_timing == synch_to_other) { - ru->fh_south_in = fh_slave_south_in; // synchronize to master - ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass - ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous - } - else { - ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission - ru->fh_south_asynch_in = NULL; // no asynchronous UL - } - ru->start_rf = NULL; // no local RF - ru->start_if = start_if; // need to start if interface for IF5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - break; - - case REMOTE_IF4p5: - ru->do_prach = 0; - ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation - ru->feptx_ofdm = NULL; // no OFDM mod - ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception - ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission - ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other - ru->fh_north_out = NULL; - ru->fh_north_asynch_in = NULL; - ru->start_rf = NULL; // no local RF - ru->start_if = start_if; // need to start if interface for IF4p5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - - malloc_IF4p5_buffer(ru); - - break; - - default: - LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); - break; - } // switch on interface type + LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); + set_function_spec_param(ru); LOG_I(PHY,"Starting ru_thread %d\n",ru_id); init_RU_proc(ru); @@ -2451,3 +2814,142 @@ void stop_ru(RU_t *ru) { #endif } +void stop_RU(int nb_ru) +{ + for (int inst = 0; inst < nb_ru; inst++) { + LOG_I(PHY, "Stopping RU %d processing threads\n", inst); + kill_RU_proc(inst); + } +} + + +/* --------------------------------------------------------*/ +/* from here function to use configuration module */ +void RCconfig_RU(void) { + + int j = 0; + int i = 0; + + + paramdef_t RUParams[] = RUPARAMS_DESC; + paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; + + + config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL); + + + if ( RUParamList.numelt > 0) { + + RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*)); + + + + + RC.ru_mask=(1<<NB_RU) - 1; + printf("Set RU mask to %lx\n",RC.ru_mask); + + for (j = 0; j < RC.nb_RU; j++) { + + RC.ru[j] = (RU_t*)malloc(sizeof(RU_t)); + memset((void*)RC.ru[j],0,sizeof(RU_t)); + RC.ru[j]->idx = j; + + printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]); + + RC.ru[j]->if_timing = synch_to_ext_device; + if (RC.nb_L1_inst >0) + RC.ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; + else + RC.ru[j]->num_eNB = 0; + for (i=0;i<RC.ru[j]->num_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; + + + if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { + if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = eNodeB_3GPP; + printf("Setting function for RU %d to eNodeB_3GPP\n",j); + } + else { + RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); + RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); + RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); + RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); + RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); + + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); + } + } + RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; + RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); + RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; + for (i=0;i<RC.ru[j]->num_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; + } //strcmp(local_rf, "yes") == 0 + else { + printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); + + RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); + RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); + RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); + RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); + RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->if_timing = synch_to_other; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS; + } + } /* strcmp(local_rf, "yes") != 0 */ + + RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); + RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); + + RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); + RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); + }// j=0..num_rus + } else { + RC.nb_RU = 0; + } // setting != NULL + + return; + +} diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index c54a27cabc94bb44dd06d75da3c4644d05d69048..73f5797327198d49f2daf9a1959d13058514a811 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -47,7 +47,7 @@ #include "PHY/types.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" #include "common/ran_context.h" #include "common/config/config_userapi.h" #include "common/utils/load_module_shlib.h" @@ -59,17 +59,14 @@ //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "PHY/vars.h" -#include "SCHED/vars.h" -#include "LAYER2/MAC/vars.h" +#include "PHY/phy_vars.h" +#include "SCHED/sched_common_vars.h" +#include "LAYER2/MAC/mac_vars.h" -#include "../../SIMU/USER/init_lte.h" - -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/vars.h" -#include "LAYER2/MAC/proto.h" -#include "RRC/LITE/vars.h" -#include "PHY_INTERFACE/vars.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "RRC/LTE/rrc_vars.h" +#include "PHY_INTERFACE/phy_interface_vars.h" #ifdef SMBV #include "PHY/TOOLS/smbv.h" @@ -93,6 +90,8 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "create_tasks.h" #endif +#include "PHY/INIT/phy_init.h" + #include "system.h" #ifdef XFORMS @@ -100,7 +99,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "stats.h" #endif #include "lte-softmodem.h" - +#include "NB_IoT_interface.h" #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE @@ -118,6 +117,8 @@ int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex uint8_t nfapi_mode = 0; // Default to monolithic mode +uint16_t sf_ahead=4; + pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. @@ -135,16 +136,19 @@ volatile int oai_exit = 0; static clock_source_t clock_source = internal; static int wait_for_sync = 0; -static char UE_flag=0; unsigned int mmapped_dma=0; int single_thread_flag=1; -static char threequarter_fs=0; +static int8_t threequarter_fs=0; uint32_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; char logmem_filename[1024] = {0}; + +// This is a dummy declaration (dlsch_demodulation.c is no longer compiled for eNodeB) +int16_t dlsch_demod_shift = 0; + #if defined(ENABLE_ITTI) static char *itti_dump_file = NULL; #endif @@ -217,6 +221,10 @@ extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, extern void init_eNB_afterRU(void); int transmission_mode=1; +int emulate_rf = 0; +int numerology = 0; +int codingw = 0; +int fepw = 0; @@ -321,7 +329,7 @@ void signal_handler(int sig) { void exit_fun(const char* s) { - int CC_id; + int ru_id; if (s != NULL) { @@ -330,39 +338,26 @@ void exit_fun(const char* s) oai_exit = 1; - if (UE_flag==0) { + + if (RC.ru == NULL) + exit(-1); // likely init not completed, prevent crash or hang, exit now... for (ru_id=0; ru_id<RC.nb_RU;ru_id++) { - if (RC.ru[ru_id]->rfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); + if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) { + RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); RC.ru[ru_id]->rfdevice.trx_end_func = NULL; } - if (RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); + if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { + RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); RC.ru[ru_id]->ifdevice.trx_end_func = NULL; } } - } - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - oai_exit = 1; - - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (UE_flag == 0) { - } else { - if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func) { - PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); - PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func = NULL; - } - } - } #if defined(ENABLE_ITTI) sleep(1); //allow lte-softmodem threads to exit first itti_terminate_tasks (TASK_UNKNOWN); #endif - } } @@ -395,9 +390,9 @@ void reset_stats(FL_OBJECT *button, long arg) } static void *scope_thread(void *arg) { - char stats_buffer[16384]; + # ifdef ENABLE_XFORMS_WRITE_STATS - FILE *UE_stats, *eNB_stats; + FILE *eNB_stats; # endif struct sched_param sched_param; int UE_id, CC_id; @@ -410,47 +405,15 @@ static void *scope_thread(void *arg) { # ifdef ENABLE_XFORMS_WRITE_STATS - if (UE_flag==1) - UE_stats = fopen("UE_stats.txt", "w"); - else - eNB_stats = fopen("eNB_stats.txt", "w"); + eNB_stats = fopen("eNB_stats.txt", "w"); #endif while (!oai_exit) { - if (UE_flag==1) { - dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); - - phy_scope_UE(form_ue[0], - PHY_vars_UE_g[0][0], - 0, - 0,7); - - - } else { - /* - if (RC.eNB[0][0]->mac_enabled==1) { - len = dump_eNB_l2_stats (stats_buffer, 0); - //fl_set_object_label(form_stats_l2->stats_text, stats_buffer); - fl_clear_browser(form_stats_l2->stats_text); - fl_add_browser_line(form_stats_l2->stats_text, stats_buffer); - } - len = dump_eNB_stats (RC.eNB[0][0], stats_buffer, 0); - - if (MAX_NUM_CCs>1) - len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0); - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); - */ ue_cnt=0; for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - // if ((RC.eNB[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) { if ((ue_cnt<scope_enb_num_ue)) { phy_scope_eNB(form_enb[CC_id][ue_cnt], RC.eNB[0][CC_id], @@ -458,12 +421,7 @@ static void *scope_thread(void *arg) { ue_cnt++; } } - } - - } - - //printf("doing forms\n"); - //usleep(100000); // 100 ms + } sleep(1); } @@ -471,19 +429,11 @@ static void *scope_thread(void *arg) { # ifdef ENABLE_XFORMS_WRITE_STATS - if (UE_flag==1) { - if (UE_stats) { - rewind (UE_stats); - fwrite (stats_buffer, 1, len, UE_stats); - fclose (UE_stats); - } - } else { if (eNB_stats) { rewind (eNB_stats); fwrite (stats_buffer, 1, len, eNB_stats); fclose (eNB_stats); } - } # endif @@ -502,7 +452,6 @@ void *l2l1_task(void *arg) { itti_set_task_real_time(TASK_L2L1); itti_mark_task_ready(TASK_L2L1); - if (UE_flag == 0) { /* Wait for the initialize message */ printf("Wait for the ITTI initialize message\n"); do { @@ -523,6 +472,7 @@ void *l2l1_task(void *arg) { case TERMINATE_MESSAGE: printf("received terminate message\n"); oai_exit=1; + start_eNB = 0; itti_exit_task (); break; @@ -534,8 +484,7 @@ void *l2l1_task(void *arg) { result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - +/* ???? no else but seems to be UE only ??? do { // Wait for a message itti_receive_msg (TASK_L2L1, &message_p); @@ -566,17 +515,17 @@ void *l2l1_task(void *arg) { result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } while(!oai_exit); - +*/ return NULL; } #endif static void get_options(void) { - int CC_id; - int tddflag; - char *loopfile=NULL; - int dumpframe; + + int tddflag, nonbiotflag; + + uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; uint32_t start_telnetsrv; @@ -617,97 +566,27 @@ static void get_options(void) { logInit_log_mem(); } - - if (UE_flag > 0) { - uint8_t n_rb_dl; - paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; - paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; - - set_default_frame_parms(frame_parms); - - config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); - config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); - if (loopfile != NULL) { - printf("Input file for hardware emulation: %s",loopfile); - mode=loop_through_memory; - input_fd = fopen(loopfile,"r"); - AssertFatal(input_fd != NULL,"Please provide a valid input file\n"); - } - - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; - if ( (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = debug_prach; - if ( (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = no_L2_connect; - if ( (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = calib_prach_tx; - if (dumpframe > 0) mode = rx_dump_frame; - - if ( downlink_frequency[0][0] > 0) { - printf("Downlink frequency set to %u\n", downlink_frequency[0][0]); - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; - } - UE_scan=0; - } - - if (tddflag > 0) { - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) - frame_parms[CC_id]->frame_type = TDD; - } - - if (n_rb_dl !=0) { - printf("NB_RB set to %d\n",n_rb_dl); - if ( n_rb_dl < 6 ) { - n_rb_dl = 6; - printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",n_rb_dl); - } - if ( n_rb_dl > 100 ) { - n_rb_dl = 100; - printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",n_rb_dl); - } - if ( n_rb_dl > 50 && n_rb_dl < 100 ) { - n_rb_dl = 50; - printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",n_rb_dl); - } - if ( n_rb_dl > 25 && n_rb_dl < 50 ) { - n_rb_dl = 25; - printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",n_rb_dl); - } - UE_scan = 0; - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - frame_parms[CC_id]->N_RB_DL=n_rb_dl; - frame_parms[CC_id]->N_RB_UL=n_rb_dl; - } - } - - for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { - tx_max_power[CC_id]=tx_max_power[0]; - rx_gain[0][CC_id] = rx_gain[0][0]; - tx_gain[0][CC_id] = tx_gain[0][0]; - } - } /* UE_flag > 0 */ - #if T_TRACER paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); #endif if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - if (UE_flag == 0) { memset((void*)&RC,0,sizeof(RC)); /* Read RC configuration file */ RCConfig(); NB_eNB_INST = RC.nb_inst; NB_RU = RC.nb_RU; printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU); - } - } else if (UE_flag == 1 && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) { - // Here the configuration file is the XER encoded UE capabilities - // Read it in and store in asn1c data structures - sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME")); - printf("%s\n",uecap_xer); - uecap_xer_in=1; - } /* UE with config file */ + if (nonbiotflag <= 0) { + load_NB_IoT(); + printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n", + RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst); + } else { + printf("All Nb-IoT instances disabled\n"); + RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0; + } + } } @@ -766,12 +645,12 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { } -void init_openair0(void); -void init_openair0() { +void init_openair0(void) { int card; int i; + for (card=0; card<MAX_CARDS; card++) { @@ -779,6 +658,8 @@ void init_openair0() { openair0_cfg[card].configFilename = NULL; if(frame_parms[0]->N_RB_DL == 100) { + if(numerology == 0) + { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].samples_per_frame = 230400; @@ -790,6 +671,22 @@ void init_openair0() { openair0_cfg[card].tx_bw = 10e6; openair0_cfg[card].rx_bw = 10e6; } + }else if(numerology == 1) + { + openair0_cfg[card].sample_rate=61.44e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 20e6; + openair0_cfg[card].rx_bw = 20e6; + }else if(numerology == 2) + { + openair0_cfg[card].sample_rate=122.88e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 20e6; + openair0_cfg[card].rx_bw = 20e6; + }else + { + printf("Un supported numerology\n"); + } } else if(frame_parms[0]->N_RB_DL == 50) { openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].samples_per_frame = 153600; @@ -808,16 +705,14 @@ void init_openair0() { } - - if (frame_parms[0]->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; else //FDD openair0_cfg[card].duplex_mode = duplex_mode_FDD; printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx), - ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); + RC.eNB[0][0]->frame_parms.nb_antennas_tx , + RC.eNB[0][0]->frame_parms.nb_antennas_rx ); openair0_cfg[card].Mod_id = 0; openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; @@ -825,29 +720,25 @@ void init_openair0() { openair0_cfg[card].clock_source = clock_source; - openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx)); - openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); + openair0_cfg[card].tx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_tx ); + openair0_cfg[card].rx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_rx ); for (i=0; i<4; i++) { if (i<openair0_cfg[card].tx_num_channels) - openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i]; + openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i] ; else openair0_cfg[card].tx_freq[i]=0.0; if (i<openair0_cfg[card].rx_num_channels) - openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i]; + openair0_cfg[card].rx_freq[i] =downlink_frequency[0][i] + uplink_frequency_offset[0][i] ; else openair0_cfg[card].rx_freq[i]=0.0; openair0_cfg[card].autocal[i] = 1; openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; - if (UE_flag == 0) { - openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB; - } - else { - openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; - } + openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB; + openair0_cfg[card].configFilename = rf_config_file; printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", @@ -856,7 +747,7 @@ void init_openair0() { openair0_cfg[card].tx_freq[i], openair0_cfg[card].rx_freq[i]); } - } + } /* for loop on cards */ } @@ -866,13 +757,11 @@ void wait_RUs(void) { // wait for all RUs to be configured over fronthaul pthread_mutex_lock(&RC.ru_mutex); - - - while (RC.ru_mask>0) { pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex); printf("RC.ru_mask:%02lx\n", RC.ru_mask); } + pthread_mutex_unlock(&RC.ru_mutex); LOG_I(PHY,"RUs configured\n"); } @@ -902,7 +791,131 @@ void wait_eNBs(void) { printf("eNB L1 are configured\n"); } -static inline void wait_nfapi_init(char *thread_name) { +#if defined(ENABLE_ITTI) +/* + * helper function to terminate a certain ITTI task + */ +void terminate_task(task_id_t task_id, module_id_t mod_id) +{ + LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + MessageDef *msg; + msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); + itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); +} + +extern void free_transport(PHY_VARS_eNB *); +extern void phy_free_RU(RU_t*); + +int stop_L1L2(module_id_t enb_id) +{ + LOG_W(ENB_APP, "stopping lte-softmodem\n"); + oai_exit = 1; + + if (!RC.ru) { + LOG_F(ENB_APP, "no RU configured\n"); + return -1; + } + + /* stop trx devices, multiple carrier currently not supported by RU */ + if (RC.ru[enb_id]) { + if (RC.ru[enb_id]->rfdevice.trx_stop_func) { + RC.ru[enb_id]->rfdevice.trx_stop_func(&RC.ru[enb_id]->rfdevice); + LOG_I(ENB_APP, "turned off RU rfdevice\n"); + } else { + LOG_W(ENB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceding anyway!\n"); + } + if (RC.ru[enb_id]->ifdevice.trx_stop_func) { + RC.ru[enb_id]->ifdevice.trx_stop_func(&RC.ru[enb_id]->ifdevice); + LOG_I(ENB_APP, "turned off RU ifdevice\n"); + } else { + LOG_W(ENB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceding anyway!\n"); + } + } else { + LOG_W(ENB_APP, "no RU found for index %d\n", enb_id); + return -1; + } + + /* these tasks need to pick up new configuration */ + terminate_task(TASK_RRC_ENB, enb_id); + terminate_task(TASK_L2L1, enb_id); + LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); + kill_eNB_proc(enb_id); + LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); + kill_RU_proc(enb_id); + oai_exit = 0; + for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) { + free_transport(RC.eNB[enb_id][cc_id]); + phy_free_lte_eNB(RC.eNB[enb_id][cc_id]); + } + phy_free_RU(RC.ru[enb_id]); + free_lte_top(); + return 0; +} + +/* + * Restart the lte-softmodem after it has been soft-stopped with stop_L1L2() + */ +int restart_L1L2(module_id_t enb_id) +{ + RU_t *ru = RC.ru[enb_id]; + int cc_id; + MessageDef *msg_p = NULL; + + LOG_W(ENB_APP, "restarting lte-softmodem\n"); + + /* block threads */ + sync_var = -1; + + for (cc_id = 0; cc_id < RC.nb_L1_CC[enb_id]; cc_id++) { + RC.eNB[enb_id][cc_id]->configured = 0; + } + + RC.ru_mask |= (1 << ru->idx); + /* copy the changed frame parameters to the RU */ + /* TODO this should be done for all RUs associated to this eNB */ + memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); + set_function_spec_param(RC.ru[enb_id]); + + LOG_I(ENB_APP, "attempting to create ITTI tasks\n"); + if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { + LOG_E(RRC, "Create task for RRC eNB failed\n"); + return -1; + } else { + LOG_I(RRC, "Re-created task for RRC eNB successfully\n"); + } + if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { + LOG_E(PDCP, "Create task for L2L1 failed\n"); + return -1; + } else { + LOG_I(PDCP, "Re-created task for L2L1 successfully\n"); + } + + /* pass a reconfiguration request which will configure everything down to + * RC.eNB[i][j]->frame_parms, too */ + msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + /* TODO XForms might need to be restarted, but it is currently (09/02/18) + * broken, so we cannot test it */ + + wait_eNBs(); + init_RU_proc(ru); + ru->rf_map.card = 0; + ru->rf_map.chain = 0; /* CC_id + chain_offset;*/ + wait_RUs(); + init_eNB_afterRU(); + + printf("Sending sync to all threads\n"); + pthread_mutex_lock(&sync_mutex); + sync_var=0; + pthread_cond_broadcast(&sync_cond); + pthread_mutex_unlock(&sync_mutex); + + return 0; +} +#endif + +static void wait_nfapi_init(char *thread_name) { printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); pthread_mutex_lock( &nfapi_sync_mutex ); @@ -924,14 +937,10 @@ int main( int argc, char **argv ) int CC_id; int ru_id; - uint8_t abstraction_flag=0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; - #if defined (XFORMS) int ret; #endif - start_background_system(); if ( load_configmodule(argc,argv) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } @@ -941,8 +950,6 @@ int main( int argc, char **argv ) setvbuf(stderr, NULL, _IONBF, 0); #endif - PHY_VARS_UE *UE[MAX_NUM_CCs]; - mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); @@ -950,16 +957,12 @@ int main( int argc, char **argv ) set_latency_target(); - - // set default parameters - //if (UE_flag == 1) set_default_frame_parms(frame_parms); - logInit(); printf("Reading in command-line options\n"); get_options (); - if (CONFIG_ISFLAGSET(CONFIG_ABORT) && UE_flag == 0) { + if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); } @@ -974,32 +977,10 @@ int main( int argc, char **argv ) //randominit (0); set_taus_seed (0); - if (UE_flag==1) { - printf("configuring for UE\n"); + printf("configuring for RAU/RRU\n"); - set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); - set_comp_log(PHY, LOG_INFO, LOG_HIGH, 1); - set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RLC, LOG_INFO, LOG_HIGH | FLAG_THREAD, 1); - set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); - set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); -#if defined(ENABLE_ITTI) - set_comp_log(EMU, LOG_INFO, LOG_MED, 1); -# if defined(ENABLE_USE_MME) - set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); -# endif -#endif - - } else { - printf("configuring for RAU/RRU\n"); - - } if (ouput_vcd) { - if (UE_flag==1) - VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); - else VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd"); } @@ -1009,12 +990,7 @@ int main( int argc, char **argv ) cpuf=get_cpu_freq_GHz(); #if defined(ENABLE_ITTI) - - if (UE_flag == 1) { - log_set_instance_type (LOG_INSTANCE_UE); - } else { - log_set_instance_type (LOG_INSTANCE_ENB); - } + log_set_instance_type (LOG_INSTANCE_ENB); printf("ITTI init\n"); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); @@ -1058,83 +1034,11 @@ int main( int argc, char **argv ) LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - // init the parameters - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - if (UE_flag==1) { - frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; - frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; - frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later - } - } printf("Before CC \n"); - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - - if (UE_flag==1) { - NB_UE_INST=1; - NB_INST=1; - PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)); - PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); - - - - PHY_vars_UE_g[0][CC_id] = init_ue_vars(frame_parms[CC_id], 0,abstraction_flag); - UE[CC_id] = PHY_vars_UE_g[0][CC_id]; - printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]); - - if (phy_test==1) - UE[CC_id]->mac_enabled = 0; - else - UE[CC_id]->mac_enabled = 1; - - if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode - for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { - UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; - UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); - UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; - } - } - - UE[CC_id]->UE_scan = UE_scan; - UE[CC_id]->UE_scan_carrier = UE_scan_carrier; - UE[CC_id]->mode = mode; - printf("UE[%d]->mode = %d\n",CC_id,mode); - - if (UE[CC_id]->mac_enabled == 1) { - UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234; - UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234; - }else { - UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235; - UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235; - } - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; - UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; - - if (frame_parms[CC_id]->frame_type==FDD) { - UE[CC_id]->N_TA_offset = 0; - } - else { - if (frame_parms[CC_id]->N_RB_DL == 100) - UE[CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - UE[CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - UE[CC_id]->N_TA_offset = 624/4; - } - init_openair0(); - } - - } - printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); @@ -1181,15 +1085,13 @@ int main( int argc, char **argv ) #if defined(ENABLE_ITTI) - if ((UE_flag == 1)|| - (RC.nb_inst > 0)) { + if (RC.nb_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP - if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - + if (create_tasks(1) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } printf("ITTI tasks created\n"); } else { @@ -1198,10 +1100,15 @@ int main( int argc, char **argv ) } #endif - // init UE_PF_PO and mutex lock - pthread_mutex_init(&ue_pf_po_mutex, NULL); - memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); - + /* Start the agent. If it is turned off in the configuration, it won't start */ + RCconfig_flexran(); + for (i = 0; i < RC.nb_L1_inst; i++) { + flexran_agent_start(i); + } + + // init UE_PF_PO and mutex lock + pthread_mutex_init(&ue_pf_po_mutex, NULL); + memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs); mlockall(MCL_CURRENT | MCL_FUTURE); @@ -1216,7 +1123,6 @@ int main( int argc, char **argv ) if (do_forms==1) { fl_initialize (&argc, argv, NULL, 0, 0); - if (UE_flag==0) { form_stats_l2 = create_form_stats_form(); fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); form_stats = create_form_stats_form(); @@ -1237,25 +1143,6 @@ int main( int argc, char **argv ) } } // CC_id } // UE_id - } else { - form_stats = create_form_stats_form(); - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - UE_id = 0; - form_ue[UE_id] = create_lte_phy_scope_ue(); - sprintf (title, "LTE DL SCOPE UE"); - fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - /* - if (openair_daq_vars.use_ia_receiver) { - fl_set_button(form_ue[UE_id]->button_0,1); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); - } else { - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - }*/ - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - } ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); @@ -1276,6 +1163,13 @@ int main( int argc, char **argv ) pthread_mutex_init(&sync_mutex, NULL); } + if (nfapi_mode) + { + printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + } + const char *nfapi_mode_str = "<UNKNOWN>"; switch(nfapi_mode) { @@ -1300,23 +1194,7 @@ int main( int argc, char **argv ) printf("START MAIN THREADS\n"); // start the main threads - if (UE_flag == 1) { - int eMBMS_active = 0; - init_UE(1,eMBMS_active,uecap_xer_in); - - if (phy_test==0) { - printf("Filling UE band info\n"); - fill_ue_band_info(); - dl_phy_sync_success (0, 0, 0, 1); - } - number_of_cards = 1; - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_UE_g[0][CC_id]->rf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; - } - } - else { number_of_cards = 1; printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); if (RC.nb_L1_inst > 0) { @@ -1363,42 +1241,10 @@ int main( int argc, char **argv ) } printf("ALL RUs ready - ALL eNBs ready\n"); - } // connect the TX/RX buffers - if (UE_flag==1) { - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - -#ifdef OAI_USRP - UE[CC_id]->hw_timing_advance = timing_advance; -#else - UE[CC_id]->hw_timing_advance = 160; -#endif - } - if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { - printf("Error setting up eNB buffer\n"); - exit(-1); - } - - - - if (input_fd) { - printf("Reading in from file to antenna buffer %d\n",0); - if (fread(UE[0]->common_vars.rxdata[0], - sizeof(int32_t), - frame_parms[0]->samples_per_tti*10, - input_fd) != frame_parms[0]->samples_per_tti*10) - printf("error reading from file\n"); - } - //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; - } else { - - printf("eNB mode\n"); - - } + printf("Sending sync to all threads\n"); @@ -1406,9 +1252,6 @@ int main( int argc, char **argv ) sync_var=0; pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); - printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); - end_configmodule(); - printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); // wait for end of program printf("TYPE <CTRL-C> TO TERMINATE\n"); @@ -1437,10 +1280,6 @@ int main( int argc, char **argv ) fl_hide_form(form_stats->stats_form); fl_free_form(form_stats->stats_form); - if (UE_flag==1) { - fl_hide_form(form_ue[0]->lte_phy_scope_ue); - fl_free_form(form_ue[0]->lte_phy_scope_ue); - } else { fl_hide_form(form_stats_l2->stats_form); fl_free_form(form_stats_l2->stats_form); @@ -1450,7 +1289,6 @@ int main( int argc, char **argv ) fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); } } - } } #endif @@ -1458,14 +1296,28 @@ int main( int argc, char **argv ) printf("stopping MODEM threads\n"); // cleanup - if (UE_flag == 1) { - } else { - for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { - stop_ru(RC.ru[ru_id]); - } - stop_eNB(1); + for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { + stop_ru(RC.ru[ru_id]); } + stop_eNB(NB_eNB_INST); + stop_RU(NB_RU); + /* release memory used by the RU/eNB threads (incomplete), after all + * threads have been stopped (they partially use the same memory) */ + for (int inst = 0; inst < NB_eNB_INST; inst++) { + for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { + free_transport(RC.eNB[inst][cc_id]); + phy_free_lte_eNB(RC.eNB[inst][cc_id]); + } + } + for (int inst = 0; inst < NB_RU; inst++) { + phy_free_RU(RC.ru[inst]); + } + free_lte_top(); + + printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); + end_configmodule(); + printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); @@ -1476,13 +1328,7 @@ int main( int argc, char **argv ) pthread_mutex_destroy(&ue_pf_po_mutex); // *** Handle per CC_id openair0 - if (UE_flag==1) { - if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) { - PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); - PHY_vars_UE_g[0][0]->rfdevice.trx_end_func = NULL; - } - } - else { + for(ru_id=0; ru_id<NB_RU; ru_id++) { if (RC.ru[ru_id]->rfdevice.trx_end_func) { RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); @@ -1493,7 +1339,6 @@ int main( int argc, char **argv ) RC.ru[ru_id]->ifdevice.trx_end_func = NULL; } } - } if (ouput_vcd) VCD_SIGNAL_DUMPER_CLOSE(); @@ -1501,6 +1346,8 @@ int main( int argc, char **argv ) terminate_opt(); logClean(); + + printf("Bye.\n"); return 0; } diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 87a34315b738c78f7c17b5ff094dacaeea8f0144..8aae82faf0622bfbeda1696154985b164fa0aa3c 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -28,9 +28,12 @@ #include "assertions.h" #include "msc.h" #include "PHY/types.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" +#include "flexran_agent.h" + #if defined(ENABLE_ITTI) #if defined(ENABLE_USE_MME) #include "s1ap_eNB.h" @@ -72,6 +75,8 @@ #define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" #define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n" +#define CONFIG_HLP_EMULIFACE "Set the interface name for the multicast transport for emulation mode (e.g. eth0, lo, etc.) \n" +//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation" #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" #define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" #define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" @@ -84,6 +89,12 @@ #define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" +#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" +#define CONFIG_HLP_CODINGW "coding worker thread enable(disable by defult)\n" +#define CONFIG_HLP_FEPW "FEP worker thread enabled(disable by defult)\n" +#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" + +#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument @@ -127,46 +138,54 @@ {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ -{"r" , CONFIG_HLP_PRB, 0, u8ptr:&n_rb_dl, defintval:0, TYPE_UINT8, 0}, \ +{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \ +{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \ +{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \ +{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ +{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ } +#define DEFAULT_DLF 2680000000 -extern int16_t dlsch_demod_shift; /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC { \ -{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ -{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ -{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ -{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ -{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ -{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ -{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ -{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ -{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \ -{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \ -{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \ -{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \ -{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \ -{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \ -{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ -{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ -{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ -{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ -{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ -{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ -{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ -{"U" , CONFIG_HLP_UE, PARAMFLAG_BOOL, i8ptr:&UE_flag, defintval:0, TYPE_INT8, 0}, \ -{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ -{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ -{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ -{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \ -{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&ouput_vcd, defintval:0, TYPE_INT, 0}, \ -{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ -{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ -{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0} \ +{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ +{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ +{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ +{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ +{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ +{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ +{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ +{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ +{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \ +{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \ +{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \ +{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \ +{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \ +{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \ +{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ +{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ +{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ +{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ +{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ +{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ +{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ +{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ +{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ +{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ +{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \ +{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&ouput_vcd, defintval:0, TYPE_INT, 0}, \ +{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ +{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ +{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ +{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ +{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ +{"codingw" , CONFIG_HLP_CODINGW, PARAMFLAG_BOOL, iptr:&codingw, defintval:0, TYPE_INT, 0}, \ +{"fepw" , CONFIG_HLP_FEPW, PARAMFLAG_BOOL, iptr:&fepw, defintval:0, TYPE_INT, 0}, \ +{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ } #define CONFIG_HLP_FLOG "Enable online log \n" @@ -246,24 +265,33 @@ extern void kill_eNB_proc(int inst); // In lte-ru.c extern void init_RU(const char*); extern void stop_ru(RU_t *ru); +extern void init_RU_proc(RU_t *ru); +extern void stop_RU(int nb_ru); +extern void kill_RU_proc(int inst); +extern void set_function_spec_param(RU_t *ru); // In lte-ue.c extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); -extern void init_UE(int,int,int); +extern void init_UE(int,int,int,int); extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name); extern void reset_opp_meas(void); extern void print_opp_meas(void); extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); -extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); -extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); +extern void init_td_thread(PHY_VARS_eNB *); +extern void init_te_thread(PHY_VARS_eNB *); +extern void kill_td_thread(PHY_VARS_eNB *); +extern void kill_te_thread(PHY_VARS_eNB *); PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); void init_eNB_afterRU(void); +extern int stop_L1L2(module_id_t enb_id); +extern int restart_L1L2(module_id_t enb_id); + #endif diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 913ae958fc113af682b1ff17823e2f9bca898855..a0174ea3327ef245f5f1008633adb3f1ef1f462c 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -33,19 +33,24 @@ #include "rt_wrapper.h" -#ifdef OPENAIR2 -#include "LAYER2/MAC/defs.h" -#include "RRC/LITE/extern.h" -#endif -#include "PHY_INTERFACE/extern.h" +#include "LAYER2/MAC/mac.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_stub_UE.h" +#include "PHY_INTERFACE/phy_interface_extern.h" +#include "PHY/INIT/phy_init.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/LTE_ESTIMATION/lte_estimation.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "PHY/extern.h" -#include "SCHED/extern.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/proto.h" +#include "PHY/phy_extern_ue.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "SCHED_UE/sched_UE.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" + +#include <inttypes.h> #include "UTIL/LOG/log_extern.h" #include "UTIL/OTG/otg_tx.h" @@ -54,76 +59,100 @@ #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" + #include "T.h" extern double cpuf; +extern uint8_t nfapi_mode; #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL #define FIFO_PRIORITY 40 typedef enum { - pss=0, - pbch=1, - si=2 + pss=0, + pbch=1, + si=2 } sync_mode_t; void init_UE_threads(int); +void init_UE_threads_stub(int); +void init_UE_single_thread_stub(int); void *UE_thread(void *arg); -void init_UE(int nb_inst,int,int); +void init_UE(int nb_inst,int,int,int); +void init_UE_stub(int nb_inst,int,int,char*); +void init_UE_stub_single_thread(int nb_inst,int,int,char*); +int init_timer_thread(void); +extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); +extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), + unsigned char _multicast_group, char *multicast_ifname); +extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); +extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); +extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); +extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); +extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); +extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP); + +//extern int tx_req_UE_MAC1(); + +void ue_stub_rx_handler(unsigned int, char *); int32_t **rxdata; int32_t **txdata; +int timer_subframe; +int timer_frame; +SF_ticking *phy_stub_ticking; + #define KHz (1000UL) #define MHz (1000*KHz) typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; } eutra_band_t; typedef struct band_info_s { - int nbands; - eutra_band_t band_info[100]; + int nbands; + eutra_band_t band_info[100]; } band_info_t; band_info_t bands_to_scan; static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, }; @@ -147,16 +176,21 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE)); memset(ue,0,sizeof(PHY_VARS_UE)); memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS)); - } + } else ue = PHY_vars_UE_g[UE_id][0]; ue->Mod_id = UE_id; ue->mac_enabled = 1; - // initialize all signal buffers - init_lte_ue_signal(ue,1,abstraction_flag); - // intialize transport - init_lte_ue_transport(ue,abstraction_flag); + + // Panos: In phy_stub_UE (MAC-to-MAC) mode these init functions don't need to get called. Is this correct? + if (nfapi_mode!=3) + { + // initialize all signal buffers + init_lte_ue_signal(ue,1,abstraction_flag); + // intialize transport + init_lte_ue_transport(ue,abstraction_flag); + } return(ue); } @@ -169,55 +203,57 @@ char uecap_xer[1024]; void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { #ifdef DEADLINE_SCHEDULER - if (sched_runtime!=0) { - struct sched_attr attr= {0}; - attr.size = sizeof(attr); - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = sched_runtime; - attr.sched_deadline = sched_deadline; - attr.sched_period = 0; - AssertFatal(sched_setattr(0, &attr, 0) == 0, - "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); - LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", - name, (unsigned long)gettid(), sched_getcpu()); - } + if (sched_runtime!=0) { + struct sched_attr attr= {0}; + attr.size = sizeof(attr); + attr.sched_policy = SCHED_DEADLINE; + attr.sched_runtime = sched_runtime; + attr.sched_deadline = sched_deadline; + attr.sched_period = 0; + AssertFatal(sched_setattr(0, &attr, 0) == 0, + "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); + LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", + name, (unsigned long)gettid(), sched_getcpu()); + } #else - if (CPU_COUNT(cpuset) > 0) - AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); - struct sched_param sp; - sp.sched_priority = sched_fifo; - AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, - "Can't set thread priority, Are you root?\n"); - /* Check the actual affinity mask assigned to the thread */ - cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); - if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { - char txt[512]={0}; - for (int j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, cset)) - sprintf(txt+strlen(txt), " %d ", j); - printf("CPU Affinity of thread %s is %s\n", name, txt); - } - CPU_FREE(cset); + if (CPU_COUNT(cpuset) > 0) + AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); + struct sched_param sp; + sp.sched_priority = sched_fifo; + AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, + "Can't set thread priority, Are you root?\n"); + /* Check the actual affinity mask assigned to the thread */ + cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); + if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { + char txt[512]={0}; + for (int j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET(j, cset)) + sprintf(txt+strlen(txt), " %d ", j); + printf("CPU Affinity of thread %s is %s\n", name, txt); + } + CPU_FREE(cset); #endif } -void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in) { +void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction) { PHY_VARS_UE *UE; int inst; int ret; LOG_I(PHY,"UE : Calling Layer 2 for initialization\n"); - + l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, 0,// cba_group_active 0); // HO flag - + for (inst=0;inst<nb_inst;inst++) { LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0); + // turn off timing control loop in UE + PHY_vars_UE_g[inst][0]->no_timing_correction = timing_correction; LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); init_UE_threads(inst); @@ -249,6 +285,76 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in) { #endif } +// Panos: Initiating all UEs within a single set of threads for PHY_STUB. Future extensions -> multiple +// set of threads for multiple UEs. +void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) { + + int inst; + + LOG_I(PHY,"UE : Calling Layer 2 for initialization, nb_inst: %d \n", nb_inst); + + l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, + 0,// cba_group_active + 0); // HO flag + + for (inst=0;inst<nb_inst;inst++) { + + LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); + PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0); + } + init_timer_thread(); + init_UE_single_thread_stub(nb_inst); + + + printf("UE threads created \n"); + + LOG_I(PHY,"Starting multicast link on %s\n",emul_iface); + if(nfapi_mode!=3) + multicast_link_start(ue_stub_rx_handler,0,emul_iface); + + +} + + + + + +void init_UE_stub(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) { + + int inst; + + LOG_I(PHY,"UE : Calling Layer 2 for initialization\n"); + + l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, + 0,// cba_group_active + 0); // HO flag + + for (inst=0;inst<nb_inst;inst++) { + + LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); + PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0); + } + init_timer_thread(); + + for (inst=0;inst<nb_inst;inst++) { + + LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); + init_UE_threads_stub(inst); + } + + printf("UE threads created \n"); + + LOG_I(PHY,"Starting multicast link on %s\n",emul_iface); + if(nfapi_mode !=3) + multicast_link_start(ue_stub_rx_handler,0,emul_iface); + + + +} + + + + /*! * \brief This is the UE synchronize thread. * It performs band scanning and synchonization. @@ -273,14 +379,14 @@ static void *UE_thread_synch(void *arg) UE->is_synchronized = 0; printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); - cpu_set_t cpuset; + cpu_set_t cpuset; CPU_ZERO(&cpuset); if ( threads.iq != -1 ) CPU_SET(threads.iq, &cpuset); // this thread priority must be lower that the main acquisition thread sprintf(threadname, "sync UE %d\n", UE->Mod_id); init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname); - + printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); ind = 0; found = 0; @@ -301,7 +407,7 @@ static void *UE_thread_synch(void *arg) ind++; } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - + if (found == 0) { LOG_E(PHY,"Can't find EUTRA band for frequency %d",UE->frame_parms.dl_CarrierFreq); exit_fun("Can't find EUTRA band for frequency"); @@ -315,7 +421,7 @@ static void *UE_thread_synch(void *arg) openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq; openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - if (uplink_frequency_offset[CC_id][i] != 0) // + if (uplink_frequency_offset[CC_id][i] != 0) // openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; else //FDD openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; @@ -337,15 +443,15 @@ static void *UE_thread_synch(void *arg) } } - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - pthread_mutex_unlock(&sync_mutex); + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + pthread_mutex_unlock(&sync_mutex); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); + printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; } while (oai_exit==0) { @@ -354,202 +460,202 @@ static void *UE_thread_synch(void *arg) // the thread waits here most of the time pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - + switch (sync_mode) { case pss: LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); current_offset += 20000000; // increase by 20 MHz - + if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { current_band++; - current_offset=0; - } - - if (current_band==bands_to_scan.nbands) { - current_band=0; - oai_exit=1; - } - - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; - - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - if (UE->UE_scan_carrier) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - } + current_offset=0; + } + + if (current_band==bands_to_scan.nbands) { + current_band=0; + oai_exit=1; + } + + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + if (UE->UE_scan_carrier) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + } + + break; - break; - case pbch: #if DISABLE_LOG_X - printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); #else - LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); #endif - if (initial_sync( UE, UE->mode ) == 0) { - - hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; - LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", - hw_slot_offset, - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, - UE->UE_scan_carrier ); - - - // rerun with new cell parameters and frequency-offset - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); - else - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; - downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; - freq_offset=0; - } + if (initial_sync( UE, UE->mode ) == 0) { + + hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; + LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", + hw_slot_offset, + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, + UE->UE_scan_carrier ); + + + // rerun with new cell parameters and frequency-offset + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); + else + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; + freq_offset=0; } + } + + // reconfigure for potentially different bandwidth + switch(UE->frame_parms.N_RB_DL) { + case 6: + openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; + openair0_cfg[UE->rf_map.card].rx_bw =.96e6; + openair0_cfg[UE->rf_map.card].tx_bw =.96e6; + // openair0_cfg[0].rx_gain[0] -= 12; + break; + case 25: + openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; + openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; + openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; + // openair0_cfg[0].rx_gain[0] -= 6; + break; + case 50: + openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; + openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; + openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; + // openair0_cfg[0].rx_gain[0] -= 3; + break; + case 100: + openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; + openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; + openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; + // openair0_cfg[0].rx_gain[0] -= 0; + break; + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + //UE->rfdevice.trx_stop_func(&UE->rfdevice); + sleep(1); + init_frame_parms(&UE->frame_parms,1); + /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + }*/ + + if (UE->UE_scan_carrier == 1) { + + UE->UE_scan_carrier = 0; + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 1; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + if( UE->mode == rx_dump_frame ) { + FILE *fd; + if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } else { + LOG_E(PHY,"Cannot open file for writing\n"); + exit(0); + } + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 0; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - // reconfigure for potentially different bandwidth - switch(UE->frame_parms.N_RB_DL) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; - // openair0_cfg[0].rx_gain[0] -= 0; - break; - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); - //UE->rfdevice.trx_stop_func(&UE->rfdevice); - sleep(1); - init_frame_parms(&UE->frame_parms,1); - /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - }*/ - - if (UE->UE_scan_carrier == 1) { - - UE->UE_scan_carrier = 0; - } else { - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - UE->is_synchronized = 1; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - - if( UE->mode == rx_dump_frame ) { - FILE *fd; - if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present - if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } else { - LOG_E(PHY,"Cannot open file for writing\n"); - exit(0); - } - } else { - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - UE->is_synchronized = 0; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - - } - } - } - } else { - // initial sync failed - // calculate new offset and try again - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) - freq_offset += 100; - freq_offset *= -1; - - if (abs(freq_offset) > 7500) { - LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); - FILE *fd; - if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - AssertFatal(1==0,"No cell synchronization found, abandoning"); - return &UE_thread_synch_retval; // not reached - } - } + } + } + } + } else { + // initial sync failed + // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + freq_offset += 100; + freq_offset *= -1; + + if (abs(freq_offset) > 7500) { + LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); + FILE *fd; + if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } + AssertFatal(1==0,"No cell synchronization found, abandoning"); + return &UE_thread_synch_retval; // not reached + } + } #if DISABLE_LOG_X - printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); #else - LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); #endif - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (UE->UE_scan_carrier==1) - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 - break; - case si: - default: - break; - } - - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - // indicate readiness - UE->proc.instance_cnt_synch--; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); - } // while !oai_exit - - return &UE_thread_synch_retval; + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + if (UE->UE_scan_carrier==1) + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + }// initial_sync=0 + break; + case si: + default: + break; + } + + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + // indicate readiness + UE->proc.instance_cnt_synch--; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); + } // while !oai_exit + + return &UE_thread_synch_retval; } /*! @@ -561,146 +667,733 @@ static void *UE_thread_synch(void *arg) */ static void *UE_thread_rxn_txnp4(void *arg) { - static __thread int UE_thread_rxtx_retval; - struct rx_tx_thread_data *rtd = arg; - UE_rxtx_proc_t *proc = rtd->proc; - PHY_VARS_UE *UE = rtd->UE; - int ret; - - proc->instance_cnt_rxtx=-1; - proc->subframe_rx=proc->sub_frame_start; - - char threadname[256]; - sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - - if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 ) - CPU_SET(threads.one, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 ) - CPU_SET(threads.two, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 ) - CPU_SET(threads.three, &cpuset); - //CPU_SET(threads.three, &cpuset); - init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, - threadname); - - while (!oai_exit) { - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("nothing to add"); - } - while (proc->instance_cnt_rxtx < 0) { - // most of the time, the thread is waiting here - pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - } - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - } - - initRefTimes(t2); - initRefTimes(t3); - pickTime(current); - updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); - - // Process Rx data for one sub-frame - lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { - - if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", - threadname, - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } else { - LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", - threadname, - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } + static __thread int UE_thread_rxtx_retval; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + PHY_VARS_UE *UE = rtd->UE; + int ret; + + proc->instance_cnt_rxtx=-1; + proc->subframe_rx=proc->sub_frame_start; + + char threadname[256]; + sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 ) + CPU_SET(threads.one, &cpuset); + if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 ) + CPU_SET(threads.two, &cpuset); + if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 ) + CPU_SET(threads.three, &cpuset); + //CPU_SET(threads.three, &cpuset); + init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, + threadname); + + while (!oai_exit) { + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); + } + while (proc->instance_cnt_rxtx < 0) { + // most of the time, the thread is waiting here + pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + } + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } + + initRefTimes(t2); + initRefTimes(t3); + pickTime(current); + updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); + + // Process Rx data for one sub-frame + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadname, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadname, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } #ifdef UE_SLOT_PARALLELISATION - phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); + phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); #else - phy_procedures_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); + phy_procedures_UE_RX(UE, proc, 0, 0, 1, UE->mode); #endif - } + } #if UE_TIMING_TRACE - start_meas(&UE->generic_stat); + start_meas(&UE->generic_stat); #endif - if (UE->mac_enabled==1) { - - ret = ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); - if ( ret != CONNECTION_OK) { - char *txt; - switch (ret) { - case CONNECTION_LOST: - txt="RRC Connection lost, returning to PRACH"; - break; - case PHY_RESYNCH: - txt="RRC Connection lost, trying to resynch"; - break; - case RESYNCH: - txt="return to PRACH and perform a contention-free access"; - break; - default: - txt="UNKNOWN RETURN CODE"; - }; - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); - } - } + if (UE->mac_enabled==1) { + + ret = ue_scheduler(UE->Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + if ( ret != CONNECTION_OK) { + char *txt; + switch (ret) { + case CONNECTION_LOST: + txt="RRC Connection lost, returning to PRACH"; + break; + case PHY_RESYNCH: + txt="RRC Connection lost, trying to resynch"; + break; + case RESYNCH: + txt="return to PRACH and perform a contention-free access"; + break; + default: + txt="UNKNOWN RETURN CODE"; + }; + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); + } + } #if UE_TIMING_TRACE - stop_meas(&UE->generic_stat); + stop_meas(&UE->generic_stat); +#endif + + + // Prepare the future Tx data + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) + phy_procedures_UE_TX(UE,proc,0,0,UE->mode); + + + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && + (UE->frame_parms.frame_type == TDD)) + if (UE->mode != loop_through_memory) + phy_procedures_UE_S_TX(UE,0,0); + updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); + + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } + proc->instance_cnt_rxtx--; +#if BASIC_SIMULATOR + if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); #endif + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } + } + + // thread finished + free(arg); + return &UE_thread_rxtx_retval; +} + + + +unsigned int emulator_absSF; + +void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) { + + PHY_VARS_UE *UE; + UE = PHY_vars_UE_g[0][0]; + + UE_tport_t *pdu = (UE_tport_t*)rx_buffer; + SLSCH_t *slsch = (SLSCH_t*)&pdu->slsch; + SLDCH_t *sldch = (SLDCH_t*)&pdu->sldch; + + switch (((UE_tport_header_t*)rx_buffer)->packet_type) { + case TTI_SYNC: + emulator_absSF = ((UE_tport_header_t*)rx_buffer)->absSF; + wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); + break; + case SLSCH: + + + LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLSCH packet\n",emulator_absSF/10,emulator_absSF%10); + LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLSCH payload (%d bytes) to MAC\n",num_bytes, + pdu->header.absSF/10,pdu->header.absSF%10, + slsch->payload_length); + printf("SLSCH:"); + for (int i=0;i<sizeof(SLSCH_t);i++) printf("%x ",((uint8_t*)slsch)[i]); + printf("\n"); + + ue_send_sl_sdu(0, + 0, + pdu->header.absSF/10, + pdu->header.absSF%10, + pdu->payload, + slsch->payload_length, + 0, + SL_DISCOVERY_FLAG_NO); + break; + + case SLDCH: + + + LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLDCH packet\n",emulator_absSF/10,emulator_absSF%10); + LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC\n",num_bytes, + pdu->header.absSF/10,pdu->header.absSF%10, + sldch->payload_length); + printf("SLDCH:"); + for (int i=0;i<sizeof(SLDCH_t);i++) printf("%x ",((uint8_t*)sldch)[i]); + printf("\n"); + + ue_send_sl_sdu(0, + 0, + pdu->header.absSF/10, + pdu->header.absSF%10, + sldch->payload, + sldch->payload_length, + 0, + SL_DISCOVERY_FLAG_YES); + break; + + } +} + + +/*! + * \brief This is the UE thread for RX subframe n and TX subframe n+4. + * This thread performs the phy_procedures_UE_RX() on every received slot. + * then, if TX is enabled it performs TX for n+4. + * \param arg is a pointer to a \ref PHY_VARS_UE structure. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ + +static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { + + thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); + + module_id_t Mod_id = 0; + //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames + static __thread int UE_thread_rxtx_retval; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + + // Initializations for nfapi-L2-emulator mode + dl_config_req = NULL; + ul_config_req = NULL; + hi_dci0_req = NULL; + tx_request_pdu_list = NULL; + + PHY_VARS_UE *UE; //= rtd->UE; + int ret; + // double t_diff; + + char threadname[256]; + //sprintf(threadname,"UE_%d_proc", UE->Mod_id); + //proc->instance_cnt_rxtx=-1; - // Prepare the future Tx data + phy_stub_ticking->ticking_var = -1; + proc->subframe_rx=proc->sub_frame_start; + + + //PANOS: CAREFUL HERE! + wait_sync("UE_phy_stub_single_thread_rxn_txnp4"); + + while (!oai_exit) { + + if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); + } + while (phy_stub_ticking->ticking_var < 0) { + // most of the time, the thread is waiting here + //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) + LOG_D(MAC,"Waiting for ticking_var\n"); + pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); + } + phy_stub_ticking->ticking_var--; + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } + LOG_D(MAC," Panos-D [UE_phy_stub_thread_rxn_txnp4 1] Frame: %d, Subframe: %d \n" "\n" "\n", timer_frame, timer_subframe); + + + proc->subframe_rx=timer_subframe; + proc->frame_rx = timer_frame; + proc->subframe_tx=(timer_subframe+4)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + + + oai_subframe_ind(timer_frame, timer_subframe); + + // Panos: Guessing that the next 4 lines are not needed for the phy_stub mode. + /*initRefTimes(t2); + initRefTimes(t3); + pickTime(current); + updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/ + + + //Panos: Not sure whether we should put the memory allocation here and not sure how much memory + //we should allocate for each subframe cycle. + UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); + + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t)); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + + + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t)); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t)); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; + + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + + + + + for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) { + //LOG_D(MAC, "UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id); + UE = PHY_vars_UE_g[Mod_id][0]; + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadname, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadname, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } + + + phy_procedures_UE_SL_RX(UE,proc); + + if (dl_config_req!=NULL && tx_request_pdu_list!=NULL){ + //if(dl_config_req!= NULL) { + dl_config_req_UE_MAC(dl_config_req, Mod_id); + + } - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) - if (UE->mode != loop_through_memory) - phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); + if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ + hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id); + } + if(nfapi_mode!=3) + phy_procedures_UE_SL_TX(UE,proc); + } - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && - (UE->frame_parms.frame_type == TDD)) - if (UE->mode != loop_through_memory) - phy_procedures_UE_S_TX(UE,0,0,no_relay); - updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); +#if UE_TIMING_TRACE + start_meas(&UE->generic_stat); +#endif - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - } - proc->instance_cnt_rxtx--; - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - } + if (UE->mac_enabled==1) { + + ret = ue_scheduler(UE->Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + if ( ret != CONNECTION_OK) { + char *txt; + switch (ret) { + case CONNECTION_LOST: + txt="RRC Connection lost, returning to PRACH"; + break; + case PHY_RESYNCH: + txt="RRC Connection lost, trying to resynch"; + break; + case RESYNCH: + txt="return to PRACH and perform a contention-free access"; + break; + default: + txt="UNKNOWN RETURN CODE"; + }; + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); + } } +#if UE_TIMING_TRACE + stop_meas(&UE->generic_stat); +#endif + + + // Prepare the future Tx data + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory){ + + // We make the start of RA between consecutive UEs differ by 20 frames + //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) { + if (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == next_Mod_id && proc->frame_rx >= next_ra_frame) { + + // check if we have PRACH opportunity + + if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[Mod_id].SI_Decoded == 1) { + + // The one working strangely... + //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) { + + PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); + if(prach_resources!=NULL ) { + UE_mac_inst[Mod_id].ra_frame = proc->frame_rx; + LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d \n", Mod_id ); + fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0); + UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; + next_Mod_id = Mod_id + 1; + next_ra_frame = (proc->frame_rx + 20)%1000; + } -// thread finished - free(arg); - return &UE_thread_rxtx_retval; + //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); + } + } // mode is PRACH + // Panos: Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger + // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). + // Generate UL_indications which correspond to UL traffic. + if(ul_config_req!=NULL){ //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ + ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id); + } + } + + phy_procedures_UE_SL_RX(UE,proc); + + + } //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) + + + if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0) + { + //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + oai_nfapi_crc_indication(&UL_INFO->crc_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n"); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + } + if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0) + { + //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus); + oai_nfapi_rx_ind(&UL_INFO->rx_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n"); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + } + if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) + { + //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs); + oai_nfapi_harq_indication(&UL_INFO->harq_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n"); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs =0; + + } + if(UL_INFO->sr_ind.sr_indication_body.number_of_srs>0) + { + //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs); + oai_nfapi_sr_indication(&UL_INFO->sr_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n"); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + } + + // Free UL_INFO messages + //if(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list != NULL){ + free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; + //} + //if(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list != NULL){ + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; + //} + //if(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list !=NULL){ + free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; + //} + //if(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list!=NULL){ + free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; + //} + + free(UL_INFO); + UL_INFO = NULL; + + // De-allocate memory of nfapi requests copies before next subframe round + if(dl_config_req!=NULL){ + if(dl_config_req->vendor_extension) + free(dl_config_req->vendor_extension); + if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL){ + free(dl_config_req->dl_config_request_body.dl_config_pdu_list); + dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL; + } + free(dl_config_req); + dl_config_req = NULL; + } + if(tx_request_pdu_list!=NULL){ + free(tx_request_pdu_list); + tx_request_pdu_list = NULL; + } + if(ul_config_req!=NULL){ + if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ + free(ul_config_req->ul_config_request_body.ul_config_pdu_list); + ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; + } + free(ul_config_req); + ul_config_req = NULL; + } + + if(hi_dci0_req!=NULL){ + if(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ + free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; + } + free(hi_dci0_req); + hi_dci0_req = NULL; + } + + + + } + // thread finished + free(arg); + return &UE_thread_rxtx_retval; } + + + +/*! + * \brief This is the UE thread for RX subframe n and TX subframe n+4. + * This thread performs the phy_procedures_UE_RX() on every received slot. + * then, if TX is enabled it performs TX for n+4. + * \param arg is a pointer to a \ref PHY_VARS_UE structure. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ + +static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { + + thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); + + module_id_t Mod_id = 0; + static __thread int UE_thread_rxtx_retval; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + PHY_VARS_UE *UE = rtd->UE; + int ret; + // double t_diff; + + char threadname[256]; + sprintf(threadname,"UE_%d_proc", UE->Mod_id); + + + //proc->instance_cnt_rxtx=-1; + + phy_stub_ticking->ticking_var = -1; + proc->subframe_rx=proc->sub_frame_start; + + //PANOS: CAREFUL HERE! + wait_sync("UE_phy_stub_thread_rxn_txnp4"); + + while (!oai_exit) { + + if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); + } + while (phy_stub_ticking->ticking_var < 0) { + // most of the time, the thread is waiting here + //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) + LOG_D(MAC,"Waiting for ticking_var\n"); + pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); + } + phy_stub_ticking->ticking_var--; + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } + LOG_D(MAC," Panos-D [UE_phy_stub_thread_rxn_txnp4 1] Frame: %d, Subframe: %d \n" "\n" "\n", timer_frame, timer_subframe); + + + proc->subframe_rx=timer_subframe; + proc->frame_rx = timer_frame; + proc->subframe_tx=(timer_subframe+4)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + + + // Process Rx data for one sub-frame + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadname, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadname, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } + + + phy_procedures_UE_SL_RX(UE,proc); + + oai_subframe_ind(timer_frame, timer_subframe); + + if(dl_config_req!= NULL) { + + dl_config_req_UE_MAC(dl_config_req, Mod_id); + + } + //if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){ + if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ + LOG_I( MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 after oai_subframe_ind 4 \n"); + hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id); + //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ + free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; + //} + free(hi_dci0_req); + hi_dci0_req = NULL; + } + + else if(hi_dci0_req!=NULL){ + free(hi_dci0_req); + hi_dci0_req = NULL; + } + + if (nfapi_mode != 3) + phy_procedures_UE_SL_TX(UE,proc); + + } + +#if UE_TIMING_TRACE + start_meas(&UE->generic_stat); +#endif + if (UE->mac_enabled==1) { + + ret = ue_scheduler(UE->Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0); + if ( ret != CONNECTION_OK) { + char *txt; + switch (ret) { + case CONNECTION_LOST: + txt="RRC Connection lost, returning to PRACH"; + break; + case PHY_RESYNCH: + txt="RRC Connection lost, trying to resynch"; + break; + case RESYNCH: + txt="return to PRACH and perform a contention-free access"; + break; + default: + txt="UNKNOWN RETURN CODE"; + }; + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); + } + } +#if UE_TIMING_TRACE + stop_meas(&UE->generic_stat); +#endif + + + // Prepare the future Tx data + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory){ + + if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) { + //LOG_D(MAC, "Panos-D: UE_phy_stub_thread_rxn_txnp4 before RACH \n"); + + // check if we have PRACH opportunity + + if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) { + PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); + if(prach_resources!=NULL) { + fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0); + UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; + } + + //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); + } + } // mode is PRACH + // Panos: Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger + // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). + // Generate UL_indications which correspond to UL traffic. + if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ + //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n"); + ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id); + if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ + free(ul_config_req->ul_config_request_body.ul_config_pdu_list); + ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; + } + free(ul_config_req); + ul_config_req = NULL; + } + else if(ul_config_req!=NULL){ + free(ul_config_req); + ul_config_req = NULL; + } + } + + phy_procedures_UE_SL_RX(UE,proc); + + } + // thread finished + free(arg); + return &UE_thread_rxtx_retval; +} + + + /*! * \brief This is the main UE thread. * This thread controls the other three UE threads: @@ -714,81 +1407,87 @@ static void *UE_thread_rxn_txnp4(void *arg) { void *UE_thread(void *arg) { - PHY_VARS_UE *UE = (PHY_VARS_UE *) arg; - // int tx_enabled = 0; - int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); - openair0_timestamp timestamp,timestamp1; - void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; - int start_rx_stream = 0; - int i; - int th_id; + PHY_VARS_UE *UE = (PHY_VARS_UE *) arg; + // int tx_enabled = 0; + int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); + openair0_timestamp timestamp,timestamp1; + void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + int start_rx_stream = 0; + int i; + int th_id; - static uint8_t thread_idx = 0; + static uint8_t thread_idx = 0; - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - if ( threads.iq != -1 ) - CPU_SET(threads.iq, &cpuset); - init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, - "UHD Threads"); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + if ( threads.iq != -1 ) + CPU_SET(threads.iq, &cpuset); + init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, + "UHD Threads"); #ifdef NAS_UE - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif - int sub_frame=-1; - //int cumulated_shift=0; + int sub_frame=-1; + //int cumulated_shift=0; - - while (!oai_exit) { - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - int instance_cnt_synch = UE->proc.instance_cnt_synch; - int is_synchronized = UE->is_synchronized; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - if (is_synchronized == 0) { - if (instance_cnt_synch < 0) { // we can invoke the synch - // grab 10 ms of signal and wakeup synch thread - for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&UE->common_vars.rxdata[i][0]; + while (!oai_exit) { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + int instance_cnt_synch = UE->proc.instance_cnt_synch; + int is_synchronized = UE->is_synchronized; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - if (UE->mode != loop_through_memory) - AssertFatal( UE->frame_parms.samples_per_tti*10 == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx), ""); - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - instance_cnt_synch = ++UE->proc.instance_cnt_synch; - if (instance_cnt_synch == 0) { - AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - } - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - } else { + if (is_synchronized == 0) { +#if BASIC_SIMULATOR + while (!((instance_cnt_synch = UE->proc.instance_cnt_synch) < 0)) { + printf("ue sync not ready\n"); + usleep(500*1000); + } +#endif + if (instance_cnt_synch < 0) { // we can invoke the synch + // grab 10 ms of signal and wakeup synch thread + for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&UE->common_vars.rxdata[i][0]; + + if (UE->mode != loop_through_memory) + AssertFatal( UE->frame_parms.samples_per_tti*10 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx), ""); + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + instance_cnt_synch = ++UE->proc.instance_cnt_synch; + if (instance_cnt_synch == 0) { + AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); + } else { + LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); + exit_fun("nothing to add"); + } + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + } else { #if OAISIM - (void)dummy_rx; /* avoid gcc warnings */ - usleep(500); + (void)dummy_rx; /* avoid gcc warnings */ + usleep(500); #else - // grab 10 ms of signal into dummy buffer - if (UE->mode != loop_through_memory) { - for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0; sf<10; sf++) - // printf("Reading dummy sf %d\n",sf); - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - } + // grab 10 ms of signal into dummy buffer + if (UE->mode != loop_through_memory) { + for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&dummy_rx[i][0]; + for (int sf=0; sf<10; sf++) + // printf("Reading dummy sf %d\n",sf); + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx); + } #endif - } + } } // UE->is_synchronized==0 else { @@ -831,6 +1530,17 @@ void *UE_thread(void *arg) { // update thread index for received subframe UE->current_thread_id[sub_frame] = thread_idx; +#if BASIC_SIMULATOR + { + int t; + for (t = 0; t < 2; t++) { + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; + pthread_mutex_lock(&proc->mutex_rxtx); + while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + pthread_mutex_unlock(&proc->mutex_rxtx); + } + } +#endif LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]); thread_idx++; @@ -852,14 +1562,19 @@ void *UE_thread(void *arg) { writeBlockSize=UE->frame_parms.samples_per_tti; } else { // set TO compensation to zero + UE->rx_offset_diff = 0; + // compute TO compensation that should be applied for this frame - if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && - UE->rx_offset > 0 ) + + if (UE->no_timing_correction == 0) { + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && + UE->rx_offset > 0 ) UE->rx_offset_diff = -1 ; - if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && - UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && + UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) UE->rx_offset_diff = 1; + } LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); readBlockSize=UE->frame_parms.samples_per_tti - @@ -952,6 +1667,7 @@ void *UE_thread(void *arg) { return NULL; } + /*! * \brief Initialize the UE theads. * Creates the UE threads: @@ -965,117 +1681,688 @@ void *UE_thread(void *arg) { * and the locking between them. */ void init_UE_threads(int inst) { - struct rx_tx_thread_data *rtd; - PHY_VARS_UE *UE; + struct rx_tx_thread_data *rtd; + PHY_VARS_UE *UE; - AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); - AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); - AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); - UE = PHY_vars_UE_g[inst][0]; + AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); + AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); + AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); + UE = PHY_vars_UE_g[inst][0]; - pthread_attr_init (&UE->proc.attr_ue); - pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); + pthread_attr_init (&UE->proc.attr_ue); + pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - pthread_mutex_init(&UE->proc.mutex_synch,NULL); - pthread_cond_init(&UE->proc.cond_synch,NULL); + pthread_mutex_init(&UE->proc.mutex_synch,NULL); + pthread_cond_init(&UE->proc.cond_synch,NULL); - // the threads are not yet active, therefore access is allowed without locking - int nb_threads=RX_NB_TH; - for (int i=0; i<nb_threads; i++) { - rtd = calloc(1, sizeof(struct rx_tx_thread_data)); - if (rtd == NULL) abort(); - rtd->UE = UE; - rtd->proc = &UE->proc.proc_rxtx[i]; + // the threads are not yet active, therefore access is allowed without locking + int nb_threads=RX_NB_TH; + for (int i=0; i<nb_threads; i++) { + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = UE; + rtd->proc = &UE->proc.proc_rxtx[i]; - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); - UE->proc.proc_rxtx[i].sub_frame_start=i; - UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; - printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); - pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); + pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].sub_frame_start=i; + UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; + printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); #ifdef UE_SLOT_PARALLELISATION - //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL); - //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL); - //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd); + //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL); + //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL); + //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd); - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL); - pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd); + pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL); + pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd); #endif - } - pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); + } + pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); } + +/*! + * \brief Initialize the UE theads. + * Creates the UE threads: + * - UE_thread_rxtx0 + * - UE_thread_synch + * - UE_thread_fep_slot0 + * - UE_thread_fep_slot1 + * - UE_thread_dlsch_proc_slot0 + * - UE_thread_dlsch_proc_slot1 + * and the locking between them. + */ +void init_UE_single_thread_stub(int nb_inst) { + struct rx_tx_thread_data *rtd; + PHY_VARS_UE *UE; + + for (int i=0; i<nb_inst; i++){ + AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); + AssertFatal(PHY_vars_UE_g[i]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); + AssertFatal(PHY_vars_UE_g[i][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); + } + UE = PHY_vars_UE_g[0][0]; + + pthread_attr_init (&UE->proc.attr_ue); + pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); + + // Panos: Don't need synch for phy_stub mode + //pthread_mutex_init(&UE->proc.mutex_synch,NULL); + //pthread_cond_init(&UE->proc.cond_synch,NULL); + + // the threads are not yet active, therefore access is allowed without locking + // Panos: In phy_stub_UE mode due to less heavy processing operations we don't need two threads + //int nb_threads=RX_NB_TH; + int nb_threads=1; + for (int i=0; i<nb_threads; i++) { + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = UE; + rtd->proc = &UE->proc.proc_rxtx[i]; + + pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].sub_frame_start=i; + UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; + printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd); + + } + // Panos: Remove thread for UE_sync in phy_stub_UE mode. + //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); +} + + + + +/*! + * \brief Initialize the UE theads. + * Creates the UE threads: + * - UE_thread_rxtx0 + * - UE_thread_synch + * - UE_thread_fep_slot0 + * - UE_thread_fep_slot1 + * - UE_thread_dlsch_proc_slot0 + * - UE_thread_dlsch_proc_slot1 + * and the locking between them. + */ +void init_UE_threads_stub(int inst) { + struct rx_tx_thread_data *rtd; + PHY_VARS_UE *UE; + + AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); + AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); + AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); + UE = PHY_vars_UE_g[inst][0]; + + pthread_attr_init (&UE->proc.attr_ue); + pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); + + // Panos: Don't need synch for phy_stub mode + //pthread_mutex_init(&UE->proc.mutex_synch,NULL); + //pthread_cond_init(&UE->proc.cond_synch,NULL); + + // the threads are not yet active, therefore access is allowed without locking + // Panos: In phy_stub_UE mode due to less heavy processing operations we don't need two threads + //int nb_threads=RX_NB_TH; + int nb_threads=1; + for (int i=0; i<nb_threads; i++) { + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = UE; + rtd->proc = &UE->proc.proc_rxtx[i]; + + pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].sub_frame_start=i; + UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; + printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_thread_rxn_txnp4, rtd); + + + } + // Panos: Remove thread for UE_sync in phy_stub_UE mode. + //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); +} + + + + #ifdef OPENAIR2 void fill_ue_band_info(void) { - UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; - int i,j; - - bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; - - for (i=0; i<bands_to_scan.nbands; i++) { - - for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++) - if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { - memcpy(&bands_to_scan.band_info[i], - &eutra_bands[j], - sizeof(eutra_band_t)); - - printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", - bands_to_scan.band_info[i].band, - UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, - bands_to_scan.band_info[i].dl_min, - bands_to_scan.band_info[i].dl_max, - bands_to_scan.band_info[i].ul_min, - bands_to_scan.band_info[i].ul_max, - (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); - break; - } - } + UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; + int i,j; + + bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; + + for (i=0; i<bands_to_scan.nbands; i++) { + + for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++) + if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { + memcpy(&bands_to_scan.band_info[i], + &eutra_bands[j], + sizeof(eutra_band_t)); + + printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", + bands_to_scan.band_info[i].band, + UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, + bands_to_scan.band_info[i].dl_min, + bands_to_scan.band_info[i].dl_max, + bands_to_scan.band_info[i].ul_min, + bands_to_scan.band_info[i].ul_max, + (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); + break; + } + } } #endif int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) { - int i, CC_id; - LTE_DL_FRAME_PARMS *frame_parms; - openair0_rf_map *rf_map; - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - rf_map = &phy_vars_ue[CC_id]->rf_map; - - AssertFatal( phy_vars_ue[CC_id] !=0, ""); - frame_parms = &(phy_vars_ue[CC_id]->frame_parms); - - // replace RX signal buffers with mmaped HW versions - rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); - txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); - - for (i=0; i<frame_parms->nb_antennas_rx; i++) { - LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", - CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); - rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD + int i, CC_id; + LTE_DL_FRAME_PARMS *frame_parms; + openair0_rf_map *rf_map; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + rf_map = &phy_vars_ue[CC_id]->rf_map; + + AssertFatal( phy_vars_ue[CC_id] !=0, ""); + frame_parms = &(phy_vars_ue[CC_id]->frame_parms); + + // replace RX signal buffers with mmaped HW versions + rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); + txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); + + for (i=0; i<frame_parms->nb_antennas_rx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); + rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD + } + + for (i=0; i<frame_parms->nb_antennas_tx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); + txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; + } + + // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] + // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] + // be careful when releasing memory! + // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) + } + return 0; +} + + + + +/*static void* timer_thread( void* param ) { + thread_top_init("timer_thread",1,870000L,1000000L,1000000L); + timer_subframe =9; + timer_frame =1023; + //phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking)); + phy_stub_ticking->ticking_var = -1; + PHY_VARS_UE *UE; + UE = PHY_vars_UE_g[0][0]; + double t_diff; + int external_timer = 0; + + + //struct timespec pselect_start; + + + //struct timespec sf_duration; + //sf_duration.tv_sec = 0; + //sf_duration.tv_nsec = 1e6; + + + wait_sync("timer_thread"); + + //pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL); + //pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL); + + // struct timespec start = {0}; + // struct timespec end = {0}; + //sleepValue.tv_nsec = 1000000; + opp_enabled = 1; + + // first check if we are receiving timing indications + if(nfapi_mode==4) { + usleep(10000); + if (UE->instance_cnt_timer > 0) { + external_timer = 1; + int absSFm1 = ((emulator_absSF+10239)%10240); + timer_frame = absSFm1/10; + timer_subframe = absSFm1%10; + pthread_mutex_lock(&UE->timer_mutex); + UE->instance_cnt_timer = -1; + pthread_mutex_unlock(&UE->timer_mutex); + LOG_I(PHY,"Running with external timer\n"); + } + else LOG_I(PHY,"Running with internal timer\n"); + } + + struct timespec t_start; + struct timespec t_now; + struct timespec t_sleep; + uint64_t T_0; + uint64_t T_now; + uint64_t T_next_SF; + uint64_t T_sleep; + uint64_t sf_cnt = 0; //Total Subframe counter + + clock_gettime(CLOCK_MONOTONIC, &t_start); + T_0 = (uint64_t) t_start.tv_sec*1000000000 + t_start.tv_nsec; + LOG_I(MAC, "Panos-D: timer_thread(), T_0 value: %" PRId64 "\n", T_0); + //printf("%" PRId64 "\n", t); + + while (!oai_exit) { + + // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. + // They are set on the first rx/tx in the underly FH routines. + if (timer_subframe==9) { + timer_subframe=0; + timer_frame++; + timer_frame&=1023; + } else { + timer_subframe++; + } + //printf("[timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe); + //LOG_I(MAC," Panos-D [timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe); + //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), ""); + AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,""); + phy_stub_ticking->ticking_var++; + // This should probably be a call to pthread_cond_broadcast when we introduce support for multiple UEs (threads) + if(phy_stub_ticking->ticking_var == 0){ + //AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d", + //phy_stub_ticking->ticking_var); + if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) { + //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); + LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n"); + exit_fun("nothing to add"); } - - for (i=0; i<frame_parms->nb_antennas_tx; i++) { - LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", - CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); - txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; + } + else + LOG_I(MAC, "Panos-D: timer_thread() Timing problem! \n"); + + AssertFatal(pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) ==0,""); + start_meas(&UE->timer_stats); + + + //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // get initial time-stamp + if (external_timer == 0) { + sf_cnt++; + T_next_SF = T_0 + sf_cnt*1000000; + do{ + clock_gettime(CLOCK_MONOTONIC, &t_now); + T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec; + }while(T_now < T_next_SF); + //usleep(1000); + UE_tport_t pdu; + pdu.header.packet_type = TTI_SYNC; + pdu.header.absSF = (timer_frame*10)+timer_subframe; + if (nfapi_mode!=3){ + multicast_link_write_sock(0, + &pdu, + sizeof(UE_tport_header_t)); + } + + } + else { + wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); + release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread"); + } + //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); // get final time-stamp + + //double t_ns = (double)(end.tv_sec - start.tv_sec) * 1.0e9 + + // (double)(end.tv_nsec - start.tv_nsec); + //printf("Panos-D: [timer_thread] REAL TIME difference: %f", t_ns); + + + stop_meas(&UE->timer_stats); + t_diff = get_time_meas_us(&UE->timer_stats); + + //printf("Panos-D: Absolute time: %lld, diff: %lld, diff_now: %lld \n",UE->timer_stats.p_time, UE->timer_stats.diff, UE->timer_stats.diff_now); + //LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); + //if (t_diff > 1100) + + + // LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff); + //LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff); + + //printf("Panos-D: Absolute time: %f", t_diff); + + + stop_meas(&UE->timer_stats); + t_diff = get_time_meas_us(&UE->timer_stats); + //printf("Panos-D: Absolute time: %lld, diff: %lld, diff_now: %lld \n",UE->timer_stats.p_time, UE->timer_stats.diff, UE->timer_stats.diff_now); + //LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); + //if (t_diff > 1100) LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff); + //printf("Panos-D: Absolute time: %f", t_diff); + + //UE->proc.ticking_var++; + // pthread_cond_signal() //Send signal to ue_thread()? + // We also need to somehow pass the information of SFN/SF + } + free(phy_stub_ticking); + pthread_cond_destroy(&phy_stub_ticking->cond_ticking); + pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking); + return 0; + +}*/ + + + + + + + + + +// Panos: This timer thread is used only in the phy_stub mode as an independent timer +// which will be ticking and provide the SFN/SF values that will be used from the UE threads +// playing the role of nfapi-pnf. + +//02/02/2018 +static void* timer_thread( void* param ) { + thread_top_init("timer_thread",1,870000L,1000000L,1000000L); + timer_subframe =9; + timer_frame =1023; + //phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking)); + phy_stub_ticking->ticking_var = -1; + PHY_VARS_UE *UE; + UE = PHY_vars_UE_g[0][0]; + //double t_diff; + int external_timer = 0; + + + wait_sync("timer_thread"); + + opp_enabled = 1; + + // first check if we are receiving timing indications + if(nfapi_mode==4) { + usleep(10000); + if (UE->instance_cnt_timer > 0) { + external_timer = 1; + int absSFm1 = ((emulator_absSF+10239)%10240); + timer_frame = absSFm1/10; + timer_subframe = absSFm1%10; + pthread_mutex_lock(&UE->timer_mutex); + UE->instance_cnt_timer = -1; + pthread_mutex_unlock(&UE->timer_mutex); + LOG_I(PHY,"Running with external timer\n"); + } + else LOG_I(PHY,"Running with internal timer\n"); + } + + struct timespec t_start; + struct timespec t_now; + struct timespec t_sleep; + uint64_t T_0; + uint64_t T_now; + uint64_t T_next_SF; + uint64_t T_sleep; + uint64_t sf_cnt = 0; //Total Subframe counter + + clock_gettime(CLOCK_MONOTONIC, &t_start); + T_0 = (uint64_t) t_start.tv_sec*1000000000 + t_start.tv_nsec; + LOG_D(MAC, "timer_thread(), T_0 value: %" PRId64 "\n", T_0); + + while (!oai_exit) { + + // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. + // They are set on the first rx/tx in the underly FH routines. + if (timer_subframe==9) { + timer_subframe=0; + timer_frame++; + timer_frame&=1023; + } else { + timer_subframe++; + } + + //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), ""); + AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,""); + phy_stub_ticking->ticking_var++; + // This should probably be a call to pthread_cond_broadcast when we introduce support for multiple UEs (threads) + if(phy_stub_ticking->ticking_var == 0){ + //AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d", + //phy_stub_ticking->ticking_var); + if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) { + //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); + LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n"); + exit_fun("nothing to add"); } - - // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] - // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] - // be careful when releasing memory! - // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) } - return 0; + else + LOG_D(MAC, "timer_thread() Timing problem! ticking_var value:%d \n \n \n", phy_stub_ticking->ticking_var); + + AssertFatal(pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) ==0,""); + start_meas(&UE->timer_stats); + + + //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // get initial time-stamp + if (external_timer == 0) { + clock_gettime(CLOCK_MONOTONIC, &t_now); + sf_cnt++; + T_next_SF = T_0 + sf_cnt*1000000; + T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec; + if(T_now > T_next_SF){ + t_sleep.tv_sec =0; + t_sleep.tv_nsec =0; + } + else{ + T_sleep = T_next_SF - T_now; + t_sleep.tv_sec =0; + t_sleep.tv_nsec = (__syscall_slong_t) T_sleep; + } + nanosleep(&t_sleep, (struct timespec *)NULL); + UE_tport_t pdu; + pdu.header.packet_type = TTI_SYNC; + pdu.header.absSF = (timer_frame*10)+timer_subframe; + if (nfapi_mode!=3){ + multicast_link_write_sock(0, + (char *)&pdu, + sizeof(UE_tport_header_t)); + } + + } + else { + wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); + release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread"); + } + + + /*stop_meas(&UE->timer_stats); + t_diff = get_time_meas_us(&UE->timer_stats); + + stop_meas(&UE->timer_stats); + t_diff = get_time_meas_us(&UE->timer_stats);*/ + } + free(phy_stub_ticking); + pthread_cond_destroy(&phy_stub_ticking->cond_ticking); + pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking); + return 0; + +} + + + + + + + + + + + + + + + + + + + +/*static void* timer_thread( void* param ) { + thread_top_init("timer_thread",1,870000L,1000000L,1000000L); + timer_subframe =9; + timer_frame =1023; + //phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking)); + phy_stub_ticking->ticking_var = -1; + PHY_VARS_UE *UE; + UE = PHY_vars_UE_g[0][0]; + double t_diff; + int external_timer = 0; + + wait_sync("timer_thread"); + + //pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL); + //pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL); + + // struct timespec start = {0}; + // struct timespec end = {0}; + //sleepValue.tv_nsec = 1000000; + opp_enabled = 1; + + // first check if we are receiving timing indications + if(nfapi_mode==4) { + usleep(10000); + if (UE->instance_cnt_timer > 0) { + external_timer = 1; + int absSFm1 = ((emulator_absSF+10239)%10240); + timer_frame = absSFm1/10; + timer_subframe = absSFm1%10; + pthread_mutex_lock(&UE->timer_mutex); + UE->instance_cnt_timer = -1; + pthread_mutex_unlock(&UE->timer_mutex); + LOG_I(PHY,"Running with external timer\n"); + } + else LOG_I(PHY,"Running with internal timer\n"); + } + + while (!oai_exit) { + + // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. + // They are set on the first rx/tx in the underly FH routines. + if (timer_subframe==9) { + timer_subframe=0; + timer_frame++; + timer_frame&=1023; + } else { + timer_subframe++; + } + //printf("[timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe); + //LOG_I(MAC," Panos-D [timer_thread] Frame: %d, Subframe: %d \n", timer_frame, timer_subframe); + //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), ""); + AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,""); + phy_stub_ticking->ticking_var++; + // This should probably be a call to pthread_cond_broadcast when we introduce support for multiple UEs (threads) + if(phy_stub_ticking->ticking_var == 0){ + //AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d", + // phy_stub_ticking->ticking_var); + if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) { + //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); + LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n"); + exit_fun("nothing to add"); + } + } + + AssertFatal(pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) ==0,""); + start_meas(&UE->timer_stats); + + + //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // get initial time-stamp + if (external_timer == 0) { + usleep(1000); + UE_tport_t pdu; + pdu.header.packet_type = TTI_SYNC; + pdu.header.absSF = (timer_frame*10)+timer_subframe; + multicast_link_write_sock(0, + &pdu, + sizeof(UE_tport_header_t)); + + } + else { + wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); + release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread"); + } + //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); // get final time-stamp + + //double t_ns = (double)(end.tv_sec - start.tv_sec) * 1.0e9 + + // (double)(end.tv_nsec - start.tv_nsec); + //printf("Panos-D: [timer_thread] REAL TIME difference: %f", t_ns); + + + stop_meas(&UE->timer_stats); + t_diff = get_time_meas_us(&UE->timer_stats); + + //printf("Panos-D: Absolute time: %lld, diff: %lld, diff_now: %lld \n",UE->timer_stats.p_time, UE->timer_stats.diff, UE->timer_stats.diff_now); + //LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); + //if (t_diff > 1100) + + + // LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff); + //LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff); + + //printf("Panos-D: Absolute time: %f", t_diff); + + + stop_meas(&UE->timer_stats); + t_diff = get_time_meas_us(&UE->timer_stats); + //printf("Panos-D: Absolute time: %lld, diff: %lld, diff_now: %lld \n",UE->timer_stats.p_time, UE->timer_stats.diff, UE->timer_stats.diff_now); + //LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); + //if (t_diff > 1100) LOG_E(MAC," Panos-D Absolute time: %f\n", t_diff); + //printf("Panos-D: Absolute time: %f", t_diff); + + //UE->proc.ticking_var++; + // pthread_cond_signal() //Send signal to ue_thread()? + // We also need to somehow pass the information of SFN/SF + } + free(phy_stub_ticking); + pthread_cond_destroy(&phy_stub_ticking->cond_ticking); + pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking); + return 0; + +}*/ + + + + + + + + +int init_timer_thread(void) { + //PHY_VARS_UE *UE=PHY_vars_UE_g[0]; + PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; + phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking)); + pthread_mutex_init(&UE->timer_mutex,NULL); + pthread_cond_init(&UE->timer_cond,NULL); + UE->instance_cnt_timer = -1; + pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL); + pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL); + pthread_create(&phy_stub_ticking->pthread_timer, NULL, &timer_thread, NULL); + return 0; +} + + +/* HACK: this function is needed to compile the UE + * fix it somehow + */ +int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) +{ + printf("you cannot read this\n"); + abort(); } diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c new file mode 100644 index 0000000000000000000000000000000000000000..06106e9ff80fa6b784ed792fb152e24b6f990e5d --- /dev/null +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -0,0 +1,1300 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * 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 lte-enb.c + * \brief Top-level threads for eNodeB + * \author R. Knopp, F. Kaltenberger, Navid Nikaein + * \date 2012 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr + * \note + * \warning + */ + + +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <sched.h> + + +#include "T.h" + +#include "rt_wrapper.h" + + +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "assertions.h" +#include "msc.h" + +#include "PHY/types.h" + +#include "PHY/defs_UE.h" +#include "common/ran_context.h" +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "../../ARCH/COMMON/common_lib.h" +#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" + +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "PHY/phy_vars_ue.h" +#include "PHY/LTE_TRANSPORT/transport_vars.h" +#include "SCHED/sched_common_vars.h" +#include "PHY/MODULATION/modulation_vars.h" +#include "../../SIMU/USER/init_lte.h" + +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_vars.h" +#include "LAYER2/MAC/mac_proto.h" +#include "RRC/LTE/rrc_vars.h" +#include "PHY_INTERFACE/phy_interface_vars.h" + +#include "UTIL/LOG/log_extern.h" +#include "UTIL/OTG/otg_tx.h" +#include "UTIL/OTG/otg_externs.h" +#include "UTIL/MATH/oml.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "enb_config.h" +//#include "PHY/TOOLS/time_meas.h" + +#ifndef OPENAIR2 +#include "UTIL/OTG/otg_vars.h" +#endif + +#if defined(ENABLE_ITTI) +#include "intertask_interface_init.h" +#include "create_tasks.h" +#endif + +#include "system.h" + +#ifdef XFORMS +#include "PHY/TOOLS/lte_phy_scope.h" +#include "stats.h" +#endif +#include "lte-softmodem.h" + +RAN_CONTEXT_t RC; + +/* temporary compilation wokaround (UE/eNB split */ +uint16_t sf_ahead; +#ifdef XFORMS +// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) +// at eNB 0, an UL scope for every UE +FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; +FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; +char title[255]; +unsigned char scope_enb_num_ue = 2; +static pthread_t forms_thread; //xforms +#endif //XFORMS + +pthread_cond_t nfapi_sync_cond; +pthread_mutex_t nfapi_sync_mutex; +int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex + +uint8_t nfapi_mode = 0; + +uint16_t sf_ahead=2; + +char *emul_iface; + + +pthread_cond_t sync_cond; +pthread_mutex_t sync_mutex; +int sync_var=-1; //!< protected by mutex \ref sync_mutex. +int config_sync_var=-1; + +uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] +uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] + +#if defined(ENABLE_ITTI) +volatile int start_eNB = 0; +volatile int start_UE = 0; +#endif +volatile int oai_exit = 0; + +static clock_source_t clock_source = internal; +static int wait_for_sync = 0; + +unsigned int mmapped_dma=0; +int single_thread_flag=1; + +static int8_t threequarter_fs=0; + +uint32_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + + + +#if defined(ENABLE_ITTI) +static char *itti_dump_file = NULL; +#endif + +int UE_scan = 1; +int UE_scan_carrier = 0; +runmode_t mode = normal_txrx; + +FILE *input_fd=NULL; + + +#if MAX_NUM_CCs == 1 +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}}; +#else +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; +#endif + +double rx_gain_off = 0.0; + +double sample_rate=30.72e6; +double bw = 10.0e6; + +static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; + +char rf_config_file[1024]; + +int chain_offset=0; +int phy_test = 0; +uint8_t usim_test = 0; + +uint8_t dci_Format = 0; +uint8_t agregation_Level =0xFF; + +uint8_t nb_antenna_tx = 1; +uint8_t nb_antenna_rx = 1; + +char ref[128] = "internal"; +char channels[128] = "0"; + +int rx_input_level_dBm; + +#ifdef XFORMS +extern int otg_enabled; +static char do_forms=0; +#else +int otg_enabled; +#endif +//int number_of_cards = 1; + + +static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; +uint32_t target_dl_mcs = 28; //maximum allowed mcs +uint32_t target_ul_mcs = 20; +uint32_t timing_advance = 0; +uint8_t exit_missed_slots=1; +uint64_t num_missed_slots=0; // counter for the number of missed slots + + +extern void reset_opp_meas(void); +extern void print_opp_meas(void); +extern void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface); + +extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag); + + +int transmission_mode=1; + +int emulate_rf = 0; +int numerology = 0; +int codingw = 0; +int fepw = 0; + +/* struct for ethernet specific parameters given in eNB conf file */ +eth_params_t *eth_params; + +openair0_config_t openair0_cfg[MAX_CARDS]; + +double cpuf; + +extern char uecap_xer[1024]; +char uecap_xer_in=0; + +int oaisim_flag=0; +threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; + +/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed + * this is very hackish - find a proper solution + */ +uint8_t abstraction_flag=0; + +/* forward declarations */ +void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); + +/*---------------------BMC: timespec helpers -----------------------------*/ + +struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; +struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; + +struct timespec clock_difftime(struct timespec start, struct timespec end) { + struct timespec temp; + 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; + } + return temp; +} + +void print_difftimes(void) { +#ifdef DEBUG + printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); +#else + LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); +#endif +} + +void update_difftimes(struct timespec start, struct timespec end) { + struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 }; + int changed = 0; + diff_time = clock_difftime(start, end); + if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { + min_diff_time.tv_nsec = diff_time.tv_nsec; + changed = 1; + } + if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { + max_diff_time.tv_nsec = diff_time.tv_nsec; + changed = 1; + } +#if 1 + if (changed) print_difftimes(); +#endif +} + +/*------------------------------------------------------------------------*/ + +unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) { + return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); +} +unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { + return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); +} + +#if !defined(ENABLE_ITTI) +void signal_handler(int sig) { + void *array[10]; + size_t size; + + if (sig==SIGSEGV) { + // get void*'s for all entries on the stack + size = backtrace(array, 10); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(-1); + } else { + printf("trying to exit gracefully...\n"); + oai_exit = 1; + } +} +#endif +#define KNRM "\x1B[0m" +#define KRED "\x1B[31m" +#define KGRN "\x1B[32m" +#define KBLU "\x1B[34m" +#define RESET "\033[0m" + + + +void exit_fun(const char* s) +{ + int CC_id; + + if (s != NULL) { + printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + } + + oai_exit = 1; + + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + } + +#if defined(ENABLE_ITTI) + sleep(1); //allow lte-softmodem threads to exit first + itti_terminate_tasks (TASK_UNKNOWN); +#endif +} + +#ifdef XFORMS + + +void reset_stats(FL_OBJECT *button, long arg) +{ + int i,j,k; + PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0]; + + for (i=0; i<NUMBER_OF_UE_MAX; i++) { + for (k=0; k<8; k++) { //harq_processes + for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) { + phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; + } + + phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; + + + phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; + phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; + phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; + } + } +} + +static void *scope_thread(void *arg) { + char stats_buffer[16384]; +# ifdef ENABLE_XFORMS_WRITE_STATS + FILE *UE_stats, *eNB_stats; +# endif + struct sched_param sched_param; + + + sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; + sched_setscheduler(0, SCHED_FIFO,&sched_param); + + printf("Scope thread has priority %d\n",sched_param.sched_priority); + +# ifdef ENABLE_XFORMS_WRITE_STATS + + UE_stats = fopen("UE_stats.txt", "w"); + +#endif + + while (!oai_exit) { + // dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); + //fl_set_object_label(form_stats->stats_text, stats_buffer); + fl_clear_browser(form_stats->stats_text); + fl_add_browser_line(form_stats->stats_text, stats_buffer); + + phy_scope_UE(form_ue[0], + PHY_vars_UE_g[0][0], + 0, + 0,7); + + // printf("%s",stats_buffer); + } +# ifdef ENABLE_XFORMS_WRITE_STATS + + if (UE_stats) { + rewind (UE_stats); + fwrite (stats_buffer, 1, len, UE_stats); + fclose (UE_stats); + } + +# endif + + pthread_exit((void*)arg); +} +#endif + + + +#if defined(ENABLE_ITTI) +void *l2l1_task(void *arg) { + MessageDef *message_p = NULL; + int result; + + itti_set_task_real_time(TASK_L2L1); + itti_mark_task_ready(TASK_L2L1); + + + do { + // Wait for a message + itti_receive_msg (TASK_L2L1, &message_p); + + switch (ITTI_MSG_ID(message_p)) { + case TERMINATE_MESSAGE: + oai_exit=1; + itti_exit_task (); + break; + + case ACTIVATE_MESSAGE: + start_UE = 1; + break; + + case DEACTIVATE_MESSAGE: + start_UE = 0; + break; + + case MESSAGE_TEST: + LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); + break; + + default: + LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while(!oai_exit); + + return NULL; +} +#endif + +extern int16_t dlsch_demod_shift; + +static void get_options(void) { + char logmem_filename[1024] = {0}; + int CC_id; + int tddflag, nonbiotflag; + char *loopfile=NULL; + int dumpframe; + uint32_t online_log_messages; + uint32_t glog_level, glog_verbosity; + uint32_t start_telnetsrv; + + paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; + paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; + + set_default_frame_parms(frame_parms); + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + + if (strlen(in_path) > 0) { + opt_type = OPT_PCAP; + opt_enabled=1; + printf("Enabling OPT for PCAP with the following file %s \n",in_path); + } + if (strlen(in_ip) > 0) { + opt_enabled=1; + opt_type = OPT_WIRESHARK; + printf("Enabling OPT for wireshark for local interface"); + } + + config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); + if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { + set_glog_onlinelog(online_log_messages); + } + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { + set_glog(glog_level, -1); + } + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGVERBO_IDX)) { + set_glog(-1, glog_verbosity); + } + if (start_telnetsrv) { + load_module_shlib("telnetsrv",NULL,0); + } + + paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; + paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; + + + config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); + config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); + if (loopfile != NULL) { + printf("Input file for hardware emulation: %s",loopfile); + mode=loop_through_memory; + input_fd = fopen(loopfile,"r"); + AssertFatal(input_fd != NULL,"Please provide a valid input file\n"); + } + + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; + if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach; + if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect; + if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; + if (dumpframe > 0) mode = rx_dump_frame; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; + } + UE_scan=0; + + + if (tddflag > 0) { + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) + frame_parms[CC_id]->frame_type = TDD; + } + + if (frame_parms[0]->N_RB_DL !=0) { + if ( frame_parms[0]->N_RB_DL < 6 ) { + frame_parms[0]->N_RB_DL = 6; + printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 100 ) { + frame_parms[0]->N_RB_DL = 100; + printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { + frame_parms[0]->N_RB_DL = 50; + printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { + frame_parms[0]->N_RB_DL = 25; + printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); + } + UE_scan = 0; + frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; + for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL; + frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; + } + } + + + for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++) { + tx_max_power[CC_id]=tx_max_power[0]; + rx_gain[0][CC_id] = rx_gain[0][0]; + tx_gain[0][CC_id] = tx_gain[0][0]; + } + +#if T_TRACER + paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; + config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); +#endif + + if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) { + // Here the configuration file is the XER encoded UE capabilities + // Read it in and store in asn1c data structures + sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME")); + printf("%s\n",uecap_xer); + if(nfapi_mode!=3) + uecap_xer_in=1; + } /* UE with config file */ +} + + +#if T_TRACER +int T_nowait = 0; /* by default we wait for the tracer */ +int T_port = 2021; /* default port to listen to to wait for the tracer */ +int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ +#endif + + + +void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { + + int CC_id; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); + /* Set some default values that may be overwritten while reading options */ + frame_parms[CC_id]->frame_type = FDD; + frame_parms[CC_id]->tdd_config = 3; + frame_parms[CC_id]->tdd_config_S = 0; + frame_parms[CC_id]->N_RB_DL = 100; + frame_parms[CC_id]->N_RB_UL = 100; + frame_parms[CC_id]->Ncp = NORMAL; + frame_parms[CC_id]->Ncp_UL = NORMAL; + frame_parms[CC_id]->Nid_cell = 0; + frame_parms[CC_id]->num_MBSFN_config = 0; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; + frame_parms[CC_id]->nb_antennas_tx = 1; + frame_parms[CC_id]->nb_antennas_rx = 1; + + frame_parms[CC_id]->nushift = 0; + + frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; + frame_parms[CC_id]->phich_config_common.phich_duration = normal; + // UL RS Config + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0 + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; + + frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; + + downlink_frequency[CC_id][0] = DEFAULT_DLF; // Use float to avoid issue with frequency over 2^31. + downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; + + frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0]; + + } + +} + +void init_openair0(void) { + + int card; + int i; + + for (card=0; card<MAX_CARDS; card++) { + + openair0_cfg[card].mmapped_dma=mmapped_dma; + openair0_cfg[card].configFilename = NULL; + + if(frame_parms[0]->N_RB_DL == 100) { + if (frame_parms[0]->threequarter_fs) { + openair0_cfg[card].sample_rate=23.04e6; + openair0_cfg[card].samples_per_frame = 230400; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } else { + openair0_cfg[card].sample_rate=30.72e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } + } else if(frame_parms[0]->N_RB_DL == 50) { + openair0_cfg[card].sample_rate=15.36e6; + openair0_cfg[card].samples_per_frame = 153600; + openair0_cfg[card].tx_bw = 5e6; + openair0_cfg[card].rx_bw = 5e6; + } else if (frame_parms[0]->N_RB_DL == 25) { + openair0_cfg[card].sample_rate=7.68e6; + openair0_cfg[card].samples_per_frame = 76800; + openair0_cfg[card].tx_bw = 2.5e6; + openair0_cfg[card].rx_bw = 2.5e6; + } else if (frame_parms[0]->N_RB_DL == 6) { + openair0_cfg[card].sample_rate=1.92e6; + openair0_cfg[card].samples_per_frame = 19200; + openair0_cfg[card].tx_bw = 1.5e6; + openair0_cfg[card].rx_bw = 1.5e6; + } + + + + + if (frame_parms[0]->frame_type==TDD) + openair0_cfg[card].duplex_mode = duplex_mode_TDD; + else //FDD + openair0_cfg[card].duplex_mode = duplex_mode_FDD; + + printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + openair0_cfg[card].Mod_id = 0; + + openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + + openair0_cfg[card].clock_source = clock_source; + + + openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx); + openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + + for (i=0; i<4; i++) { + + if (i<openair0_cfg[card].tx_num_channels) + openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i]+uplink_frequency_offset[0][i]; + else + openair0_cfg[card].tx_freq[i]=0.0; + + if (i<openair0_cfg[card].rx_num_channels) + openair0_cfg[card].rx_freq[i] = downlink_frequency[0][i]; + else + openair0_cfg[card].rx_freq[i]=0.0; + + openair0_cfg[card].autocal[i] = 1; + openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; + openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; + + + openair0_cfg[card].configFilename = rf_config_file; + printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", + card,i, openair0_cfg[card].tx_gain[i], + openair0_cfg[card].rx_gain[i], + openair0_cfg[card].tx_freq[i], + openair0_cfg[card].rx_freq[i]); + } + } +} + + + + +#if defined(ENABLE_ITTI) +/* + * helper function to terminate a certain ITTI task + */ +void terminate_task(task_id_t task_id, module_id_t mod_id) +{ + LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + MessageDef *msg; + msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); + itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); +} + + + +#endif + + + +static inline void wait_nfapi_init(char *thread_name) { + + printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); + pthread_mutex_lock( &nfapi_sync_mutex ); + + while (nfapi_sync_var<0) + pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); + + pthread_mutex_unlock(&nfapi_sync_mutex); + + printf( "NFAPI: got sync (%s)\n", thread_name); +} + +int stop_L1L2(module_id_t enb_id) +{ + return 0; +} + + +int restart_L1L2(module_id_t enb_id) +{ + return 0; +} + +int main( int argc, char **argv ) +{ + int i; +#if defined (XFORMS) + void *status; +#endif + + int CC_id; + uint8_t abstraction_flag=0; + uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + + // Default value for the number of UEs. It will hold, + // if not changed from the command line option --num-ues + NB_UE_INST=1; + +#if defined (XFORMS) + int ret; +#endif + + start_background_system(); + if ( load_configmodule(argc,argv) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + +#ifdef DEBUG_CONSOLE + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); +#endif + + PHY_VARS_UE *UE[MAX_NUM_CCs]; + + mode = normal_txrx; + memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); + + memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); + + set_latency_target(); + + logInit(); + + printf("Reading in command-line options\n"); + + get_options (); + + printf("NFAPI_MODE value: %d \n", nfapi_mode); + + // Panos: Not sure if the following is needed here + /*if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { + if (UE_flag == 0) { + fprintf(stderr,"Getting configuration failed\n"); + exit(-1); + } + else { + printf("Setting nfapi mode to UE_STUB_OFFNET\n"); + nfapi_mode = 4; + } + }*/ + + +#if T_TRACER + T_init(T_port, 1-T_nowait, T_dont_fork); +#endif + + + + //randominit (0); + set_taus_seed (0); + + + set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); + set_comp_log(PHY, LOG_INFO, LOG_HIGH, 1); + set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RLC, LOG_INFO, LOG_HIGH | FLAG_THREAD, 1); + set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); + set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); +#if defined(ENABLE_ITTI) + set_comp_log(EMU, LOG_INFO, LOG_MED, 1); +# if defined(ENABLE_USE_MME) + set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); +# endif +#endif + + + if (ouput_vcd) { + VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); + } + + cpuf=get_cpu_freq_GHz(); + +#if defined(ENABLE_ITTI) + + log_set_instance_type (LOG_INSTANCE_UE); + + + printf("ITTI init\n"); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); + + // initialize mscgen log after ITTI + MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); +#endif + + if (opt_type != OPT_NONE) { + radio_type_t radio_type; + + if (frame_parms[0]->frame_type == FDD) + radio_type = RADIO_TYPE_FDD; + else + radio_type = RADIO_TYPE_TDD; + + if (init_opt(in_path, in_ip, NULL, radio_type) == -1) + LOG_E(OPT,"failed to run OPT \n"); + } + +#ifdef PDCP_USE_NETLINK + printf("PDCP netlink\n"); + netlink_init(); +#if defined(PDCP_USE_NETLINK_QUEUES) + pdcp_netlink_init(); +#endif +#endif + +//TTN for D2D +#ifdef Rel14 + printf ("RRC control socket\n"); + rrc_control_socket_init(); + printf ("PDCP PC5S socket\n"); + pdcp_pc5_socket_init(); +#endif + +#if !defined(ENABLE_ITTI) + // to make a graceful exit when ctrl-c is pressed + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); +#endif + + + check_clock(); + +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#endif + + LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + + // init the parameters + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; + frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later + } + + + + printf("Before CC \n"); + + + + // Panos: From old version + /*if (UE_flag==1) { + PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)*NB_UE_INST); + for (int i=0; i<NB_UE_INST; i++) { + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + + PHY_vars_UE_g[i] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); + PHY_vars_UE_g[i][CC_id] = init_ue_vars(frame_parms[CC_id], i,abstraction_flag); + + UE[CC_id] = PHY_vars_UE_g[i][CC_id]; + printf("PHY_vars_UE_g[inst][%d] = %p\n",CC_id,UE[CC_id]); + + if (phy_test==1) + UE[CC_id]->mac_enabled = 0; + else + UE[CC_id]->mac_enabled = 1; + } + } + }*/ + + + + //NB_UE_INST=1; + NB_INST=1; + if(nfapi_mode == 3){ + PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)*NB_UE_INST); + for (int i=0; i<NB_UE_INST; i++) { + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_UE_g[i] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); + PHY_vars_UE_g[i][CC_id] = init_ue_vars(frame_parms[CC_id], i,abstraction_flag); + + UE[CC_id] = PHY_vars_UE_g[i][CC_id]; + printf("PHY_vars_UE_g[inst][%d] = %p\n",CC_id,UE[CC_id]); + + if (phy_test==1) + UE[CC_id]->mac_enabled = 0; + else + UE[CC_id]->mac_enabled = 1; + } + } + } + else{ + + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + //NB_UE_INST=1; + NB_INST=1; + PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)); + PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); + PHY_vars_UE_g[0][CC_id] = init_ue_vars(frame_parms[CC_id], 0,abstraction_flag); + UE[CC_id] = PHY_vars_UE_g[0][CC_id]; + printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]); + + if (phy_test==1) + UE[CC_id]->mac_enabled = 0; + else + UE[CC_id]->mac_enabled = 1; + + if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode + for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { + UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; + UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); + UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; + } + } + + UE[CC_id]->UE_scan = UE_scan; + UE[CC_id]->UE_scan_carrier = UE_scan_carrier; + UE[CC_id]->mode = mode; + printf("UE[%d]->mode = %d\n",CC_id,mode); + + if (UE[CC_id]->mac_enabled == 1) { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234; + }else { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235; + } + UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; + + if (frame_parms[CC_id]->frame_type==FDD) { + UE[CC_id]->N_TA_offset = 0; + } + else { + if (frame_parms[CC_id]->N_RB_DL == 100) + UE[CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + UE[CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + UE[CC_id]->N_TA_offset = 624/4; + + } + init_openair0(); + } + + + printf("Runtime table\n"); + fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); + cpuf=get_cpu_freq_GHz(); + } + + + +#ifndef DEADLINE_SCHEDULER + + printf("NO deadline scheduler\n"); + /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ + + cpu_set_t cpuset; + int s; + char cpu_affinity[1024]; + CPU_ZERO(&cpuset); +#ifdef CPU_AFFINITY + if (get_nprocs() > 2) { + CPU_SET(0, &cpuset); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } + LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); + } +#endif + + /* Check the actual affinity mask assigned to the thread */ + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_getaffinity_np"); + exit_fun("Error getting processor affinity "); + } + memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + for (int j = 0; j < CPU_SETSIZE; j++) { + if (CPU_ISSET(j, &cpuset)) { + char temp[1024]; + sprintf(temp, " CPU_%d ", j); + strcat(cpu_affinity, temp); + } + } + LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); +#endif + + + + +#if defined(ENABLE_ITTI) + if (create_tasks_ue(1) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } + if(nfapi_mode==3){ //Panos: Here we should add another nfapi_mode for the case of Supervised LTE-D2D + UE_config_stub_pnf(); + } + printf("ITTI tasks created\n"); +#endif + + // init UE_PF_PO and mutex lock + pthread_mutex_init(&ue_pf_po_mutex, NULL); + memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); + + mlockall(MCL_CURRENT | MCL_FUTURE); + + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + +#ifdef XFORMS + int UE_id; + + printf("XFORMS\n"); + + if (do_forms==1) { + fl_initialize (&argc, argv, NULL, 0, 0); + + form_stats = create_form_stats_form(); + fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); + UE_id = 0; + form_ue[UE_id] = create_lte_phy_scope_ue(); + sprintf (title, "LTE DL SCOPE UE"); + fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + /* + if (openair_daq_vars.use_ia_receiver) { + fl_set_button(form_ue[UE_id]->button_0,1); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); + } else { + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + }*/ + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); + + if (ret == 0) + pthread_setname_np( forms_thread, "xforms" ); + + printf("Scope thread created, ret=%d\n",ret); + } + +#endif + + rt_sleep_ns(10*100000000ULL); + + const char *nfapi_mode_str = "<UNKNOWN>"; + + switch(nfapi_mode) + { + case 0: + nfapi_mode_str = "MONOLITHIC"; + break; + case 1: + nfapi_mode_str = "PNF"; + break; + case 2: + nfapi_mode_str = "VNF"; + break; + case 3: + nfapi_mode_str = "UE_STUB_PNF"; + break; + case 4: + nfapi_mode_str = "UE_STUB_OFFNET"; + break; + default: + nfapi_mode_str = "<UNKNOWN NFAPI MODE>"; + break; + } + printf("NFAPI MODE:%s\n", nfapi_mode_str); + + + // start the main threads + int eMBMS_active = 0; + + if (nfapi_mode==3) // UE-STUB-PNF + { + config_sync_var=0; + wait_nfapi_init("main?"); + //Panos: Temporarily we will be using single set of threads for multiple UEs. + //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface); + init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); + } + else { + init_UE(1,eMBMS_active,uecap_xer_in,0); + } + + if (phy_test==0) { + printf("Filling UE band info\n"); + fill_ue_band_info(); + dl_phy_sync_success (0, 0, 0, 1); + } + + if (nfapi_mode!=3){ + number_of_cards = 1; + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_UE_g[0][CC_id]->rf_map.card=0; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + } + } + + + + // connect the TX/RX buffers + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + + +#ifdef OAI_USRP + UE[CC_id]->hw_timing_advance = timing_advance; +#else + UE[CC_id]->hw_timing_advance = 160; +#endif + } + if(nfapi_mode!=3) { + if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { + printf("Error setting up eNB buffer\n"); + exit(-1); + } + } + + + + + if (input_fd) { + printf("Reading in from file to antenna buffer %d\n",0); + if (fread(UE[0]->common_vars.rxdata[0], + sizeof(int32_t), + frame_parms[0]->samples_per_tti*10, + input_fd) != frame_parms[0]->samples_per_tti*10) + printf("error reading from file\n"); + } + //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; + + printf("Sending sync to all threads\n"); + + pthread_mutex_lock(&sync_mutex); + sync_var=0; + pthread_cond_broadcast(&sync_cond); + pthread_mutex_unlock(&sync_mutex); + printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); + end_configmodule(); + printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); + + // wait for end of program + printf("TYPE <CTRL-C> TO TERMINATE\n"); + //getchar(); + +#if defined(ENABLE_ITTI) + printf("Entering ITTI signals handler\n"); + itti_wait_tasks_end(); + printf("Returned from ITTI signal handler\n"); + oai_exit=1; + printf("oai_exit=%d\n",oai_exit); +#else + + while (oai_exit==0) + rt_sleep_ns(100000000ULL); + printf("Terminating application - oai_exit=%d\n",oai_exit); + +#endif + + // stop threads +#ifdef XFORMS + printf("waiting for XFORMS thread\n"); + + if (do_forms==1) { + pthread_join(forms_thread,&status); + fl_hide_form(form_stats->stats_form); + fl_free_form(form_stats->stats_form); + fl_hide_form(form_ue[0]->lte_phy_scope_ue); + fl_free_form(form_ue[0]->lte_phy_scope_ue); + } + +#endif + + printf("stopping MODEM threads\n"); + + pthread_cond_destroy(&sync_cond); + pthread_mutex_destroy(&sync_mutex); + + pthread_mutex_destroy(&ue_pf_po_mutex); + + // *** Handle per CC_id openair0 + if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); + + if (ouput_vcd) + VCD_SIGNAL_DUMPER_CLOSE(); + + if (opt_enabled == 1) + terminate_opt(); + + logClean(); + + printf("Bye.\n"); + + return 0; +} diff --git a/targets/RT/USER/rt_wrapper.c b/targets/RT/USER/rt_wrapper.c index c1e5996d44375f4d40f3eeb433ebced1279810f9..443d183068e634ab97e751d7ed5f448edd820732 100644 --- a/targets/RT/USER/rt_wrapper.c +++ b/targets/RT/USER/rt_wrapper.c @@ -43,8 +43,9 @@ #include <getopt.h> #include <sys/sysinfo.h> #include "rt_wrapper.h" +#include <errno.h> -#include "openair1/PHY/defs.h" +#include "openair1/PHY/defs_common.h" static int latency_target_fd = -1; static int32_t latency_target_value = 0; @@ -283,6 +284,7 @@ void thread_top_init(char *thread_name, if (sched_setattr(0, &attr, flags) < 0 ) { perror("[SCHED] eNB tx thread: sched_setattr failed\n"); + fprintf(stderr,"sched_setattr Error = %s",strerror(errno)); exit(1); } diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index b31c47ba95d58f7d3f71fdce9510e3177f069aea..3018dbe1fb10e7565303323d9e599daf072b38c5 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -26,32 +26,24 @@ #include <stdio.h> #include <time.h> -#include "SIMULATION/TOOLS/defs.h" -#include "SIMULATION/RF/defs.h" +#include "SIMULATION/TOOLS/sim.h" +#include "SIMULATION/RF/rf.h" #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" +#include "PHY/phy_extern_ue.h" -#ifdef OPENAIR2 -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log_if.h" #include "UTIL/LOG/log_extern.h" -#include "RRC/LITE/extern.h" -#include "PHY_INTERFACE/extern.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface_extern.h" #include "UTIL/OCG/OCG.h" #include "UTIL/OPT/opt.h" // to test OPT -#endif #include "UTIL/FIFO/types.h" -#ifdef IFFT_FPGA -#include "PHY/LTE_REFSIG/mod_table.h" -#endif - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - #ifdef XFORMS #include "forms.h" #include "phy_procedures_sim_form.h" @@ -61,6 +53,10 @@ #define RF #define DEBUG_SIM +/* +#undef LOG_D +#define LOG_D(A,B,C...) printf(B,C) +*/ int number_rb_ul; int first_rbUL ; @@ -83,8 +79,8 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM node_desc_t *enb_data[NUMBER_OF_RU_MAX], node_desc_t *ue_data[NUMBER_OF_UE_MAX], uint16_t subframe, - uint16_t offset, - uint16_t length, + uint32_t offset, + uint32_t length, uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *ue_frame_parms, uint8_t UE_id, int CC_id) @@ -140,6 +136,7 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM if (!hold_channel) { // calculate the random channel from each RU for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { + frame_parms = &RC.ru[ru_id]->frame_parms; random_channel(RU2UE[ru_id][UE_id][CC_id],abstraction_flag); /* @@ -231,7 +228,6 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM pthread_mutex_lock(&RU_output_mutex[UE_id]); if (RU_output_mask[UE_id] == 0) { // This is the first eNodeB for this UE, clear the buffer - for (aa=0; aa<nb_antennas_rx; aa++) { memset((void*)r_re_DL[UE_id][aa],0,(RC.ru[0]->frame_parms.samples_per_tti)*sizeof(double)); memset((void*)r_im_DL[UE_id][aa],0,(RC.ru[0]->frame_parms.samples_per_tti)*sizeof(double)); @@ -244,22 +240,54 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM frame_parms = &RC.ru[ru_id]->frame_parms; sf_offset = (subframe*frame_parms->samples_per_tti) + offset; - LOG_D(EMU,"TXPATH: RU %d : DL_sig reading TX for subframe %d (sf_offset %d, length %d) from %p\n",ru_id,subframe,sf_offset,length,txdata[0]+sf_offset); + LOG_D(EMU,">>>>>>>>>>>>>>>>>TXPATH: RU %d : DL_sig reading TX for subframe %d (sf_offset %d, length %d) from %p\n",ru_id,subframe,sf_offset,length,txdata[0]+sf_offset); int length_meas = frame_parms->ofdm_symbol_size; - tx_pwr = dac_fixed_gain(s_re, - s_im, - txdata, - sf_offset, - nb_antennas_tx, - length, - sf_offset, - length_meas, - 14, - frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE - 0, - &ru_amp[ru_id], - frame_parms->N_RB_DL*12); + if (sf_offset+length <= frame_parms->samples_per_tti*10) { + + tx_pwr = dac_fixed_gain(s_re, + s_im, + txdata, + sf_offset, + nb_antennas_tx, + length, + sf_offset, + length_meas, + 14, + frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE + 0, + &ru_amp[ru_id], + frame_parms->N_RB_DL*12); + + } + else { + tx_pwr = dac_fixed_gain(s_re, + s_im, + txdata, + sf_offset, + nb_antennas_tx, + (frame_parms->samples_per_tti*10)-sf_offset, + sf_offset, + length_meas, + 14, + frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE + 0, + &ru_amp[ru_id], + frame_parms->N_RB_DL*12); + tx_pwr = dac_fixed_gain(s_re, + s_im, + txdata, + sf_offset, + nb_antennas_tx, + length+sf_offset-(frame_parms->samples_per_tti*10), + sf_offset, + length_meas, + 14, + frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE + 0, + &ru_amp[ru_id], + frame_parms->N_RB_DL*12); + } #ifdef DEBUG_SIM LOG_D(PHY,"[SIM][DL] subframe %d: txp (time) %d dB\n", subframe,dB_fixed(signal_energy(&txdata[0][sf_offset],length_meas))); @@ -342,7 +370,8 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM UE_id,ru_id, 10*log10(rx_pwr),subframe); #endif - + + pthread_mutex_lock(&RU_output_mutex[UE_id]); for (i=0; i<frame_parms->samples_per_tti; i++) { for (aa=0; aa<nb_antennas_rx; aa++) { @@ -356,14 +385,14 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM - double *r_re_p[2] = {r_re_DL[ru_id][0],r_re_DL[ru_id][1]}; - double *r_im_p[2] = {r_im_DL[ru_id][0],r_im_DL[ru_id][1]}; + double *r_re_p[2] = {r_re_DL[UE_id][0],r_re_DL[UE_id][1]}; + double *r_im_p[2] = {r_im_DL[UE_id][0],r_im_DL[UE_id][1]}; #ifdef DEBUG_SIM rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,length<length_meas?length:length_meas,0)/(12.0*frame_parms->N_RB_DL); LOG_D(OCM,"[SIM][DL] UE %d : ADC in %f dBm/RE for subframe %d\n",UE_id,10*log10(rx_pwr),subframe); #endif - + rxdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.rxdata; sf_offset = (subframe*frame_parms->samples_per_tti)+offset; @@ -460,7 +489,7 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] + UE2RU[UE_id][ru_id][CC_id]->path_loss_dB) <= -125.0) { // don't simulate a UE that is too weak - LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d)\n", + LOG_D(OCM,"[SIM][UL] ULPOWERS UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d)\n", UE_id, PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe], PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe], @@ -479,7 +508,7 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM 1, NULL, PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]); // This make the previous argument the total power - LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n", + LOG_D(OCM,"[SIM][UL] ULPOWERS UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n", UE_id, 10*log10(tx_pwr*PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]), PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe], @@ -539,11 +568,11 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM 1e3/UE2RU[0][ru_id][CC_id]->sampling_rate, // sampling time (ns) (double)RC.ru[ru_id]->max_rxgain-(double)RC.ru[ru_id]->att_rx - 66.227); // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later) -#ifdef DEBUG_SIM + //#ifdef DEBUG_SIM rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,frame_parms->samples_per_tti,0);//*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL; LOG_D(OCM,"[SIM][UL] rx_pwr (ADC in) %f dB for subframe %d (rx_gain %f)\n",10*log10(rx_pwr),subframe, (double)RC.ru[ru_id]->max_rxgain-(double)RC.ru[ru_id]->att_rx); -#endif + //#endif rxdata = RC.ru[ru_id]->common.rxdata; sf_offset = subframe*frame_parms->samples_per_tti; diff --git a/targets/SIMU/USER/event_handler.c b/targets/SIMU/USER/event_handler.c index 7c9f6b73fc8186c29b1d0be642df36857a240289..e840bde57b05bac5af860933c89291013cec4e4b 100644 --- a/targets/SIMU/USER/event_handler.c +++ b/targets/SIMU/USER/event_handler.c @@ -524,9 +524,9 @@ void update_mac(Event_t event) for(j=0; j<MAX_NUM_LCID; j++) { oai_emulation->mac_config[i].max_allowed_rbs[j]= mac_config[i].max_allowed_rbs[j]; - UE_list->UE_sched_ctrl[i].max_allowed_rbs[j] = oai_emulation->mac_config[i].max_allowed_rbs[j]; + UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0] = oai_emulation->mac_config[i].max_allowed_rbs[j]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",i,j); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_allowed_rbs[j]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0]); } } @@ -646,9 +646,9 @@ void update_mac(Event_t event) if(mac_config->max_allowed_rbs !=NULL) { oai_emulation->mac_config[i].max_allowed_rbs[j]= mac_config[i].max_allowed_rbs[j]; - UE_list->UE_sched_ctrl[i].max_allowed_rbs[j] = oai_emulation->mac_config[i].max_allowed_rbs[j]; + UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0] = oai_emulation->mac_config[i].max_allowed_rbs[j]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",i,j); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_allowed_rbs[j]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0]); } @@ -685,8 +685,8 @@ void update_mac(Event_t event) LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_sched_ctrl[event.ue].priority[event.lcid]); } } else if(!strcmp((char *) event.key, "DCI_aggregation_min") && event.value!=NULL && validate_mac(event)) { - Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); - mac_config = (Mac_config *) event.value; + //Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); + //mac_config = (Mac_config *) event.value; LOG_I(EMU,"DCI_aggregation_min update \n"); @@ -706,8 +706,8 @@ void update_mac(Event_t event) LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_template[0][event.ue].DCI_aggregation_min);*/ } } else if(!strcmp((char *) event.key, "DLSCH_dci_size_bits") && event.value!=NULL && validate_mac(event)) { - Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); - mac_config = (Mac_config *) event.value; + //Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); + //mac_config = (Mac_config *) event.value; LOG_I(EMU,"DLSCH_dci_size_bits update \n"); @@ -951,18 +951,18 @@ void update_mac(Event_t event) if(&mac_config[i].max_allowed_rbs[j]!=NULL) { oai_emulation->mac_config[i].max_allowed_rbs[j]= mac_config[i].max_allowed_rbs[j]; - UE_list->UE_sched_ctrl[i].max_allowed_rbs[j] = oai_emulation->mac_config[i].max_allowed_rbs[j]; + UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0] = oai_emulation->mac_config[i].max_allowed_rbs[j]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",i,j); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_allowed_rbs[j]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0]); } } } } } else { oai_emulation->mac_config[event.ue].max_allowed_rbs[event.lcid]= mac_config[event.ue].max_allowed_rbs[event.lcid]; - UE_list->UE_sched_ctrl[event.ue].max_allowed_rbs[event.lcid] = oai_emulation->mac_config[event.ue].max_allowed_rbs[event.lcid]; + UE_list->UE_sched_ctrl[event.ue].max_rbs_allowed_slice[event.lcid][0] = oai_emulation->mac_config[event.ue].max_allowed_rbs[event.lcid]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",event.ue,event.lcid); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[event.ue].max_allowed_rbs[event.lcid]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[event.ue].max_rbs_allowed_slice[event.lcid][0]); } } else if(!strcmp((char *) event.key, "max_mcs") && event.value!=NULL && validate_mac(event)) { diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c index 0818629727c7e4e2fc6b2c74e7dd0971c4bb4de9..13b9026640786664904fc326bf4bef6968bd3ece 100644 --- a/targets/SIMU/USER/init_lte.c +++ b/targets/SIMU/USER/init_lte.c @@ -29,12 +29,12 @@ #include "init_lte.h" -#include "PHY/extern.h" +#include "PHY/phy_extern.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log_if.h" -#include "PHY_INTERFACE/extern.h" +#include "PHY_INTERFACE/phy_interface.h" /* diff --git a/targets/SIMU/USER/init_lte.h b/targets/SIMU/USER/init_lte.h index 6f0aa0a6eb5ea8840a6b587bd7f18d6563d251b3..fee6c974b84d0e7c2c5761eaae24e7c7a51e1d2d 100644 --- a/targets/SIMU/USER/init_lte.h +++ b/targets/SIMU/USER/init_lte.h @@ -20,7 +20,7 @@ */ #include "PHY/types.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, uint8_t eNB_id, @@ -32,10 +32,6 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); -PHY_VARS_RN* init_lte_RN(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t RN_id, - uint8_t eMBMS_active_state); - void init_lte_vars(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs], uint8_t frame_type, uint8_t tdd_config, diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 94e05dd754b1b11afdfbc3015925aad04f1dac14..1847db1d7185627b15ca36e9d80385fb5e5961c4 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -41,24 +41,23 @@ #include <execinfo.h> #include "event_handler.h" -#include "SIMULATION/RF/defs.h" +#include "SIMULATION/RF/rf.h" #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/LTE_TRANSPORT/proto.h" -#include "PHY/vars.h" - -#include "SIMULATION/ETH_TRANSPORT/proto.h" - -//#ifdef OPENAIR2 -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/vars.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/phy_vars.h" +#include "PHY/phy_vars_ue.h" +#include "SCHED/sched_common_vars.h" + +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_proto.h" +#include "LAYER2/MAC/mac_vars.h" #include "pdcp.h" -#include "RRC/LITE/vars.h" +#include "RRC/LTE/rrc_vars.h" #include "RRC/NAS/nas_config.h" -#include "SCHED/defs.h" -#include "SCHED/vars.h" #include "system.h" @@ -76,9 +75,7 @@ uint8_t config_smbv = 0; char smbv_ip[16]; #endif -#if defined(FLEXRAN_AGENT_SB_IF) -# include "flexran_agent.h" -#endif +#include "flexran_agent.h" #include "oaisim_functions.h" @@ -103,6 +100,7 @@ char smbv_ip[16]; #if defined(ENABLE_ITTI) # include "intertask_interface.h" # include "create_tasks.h" +# include "intertask_interface_init.h" #endif #include "T.h" @@ -160,6 +158,8 @@ volatile int oai_exit = 0; //int32_t **rxdata; //int32_t **txdata; +uint16_t sf_ahead=4; +uint8_t nfapi_mode = 0; // Added for PHY abstraction extern node_list* ue_node_list; @@ -195,6 +195,11 @@ time_stats_t oaisim_stats_f; time_stats_t dl_chan_stats; time_stats_t ul_chan_stats; +int emulate_rf = 0; +int numerology = 0; +int codingw = 0; +int fepw = 0; + // this should reflect the channel models in openair1/SIMULATION/TOOLS/defs.h mapping small_scale_names[] = { { "custom", custom }, { "SCM_A", SCM_A }, @@ -216,7 +221,8 @@ oai_shutdown (void); void reset_opp_meas_oaisim (void); -void wait_eNBs() { +void wait_eNBs(void) +{ return; } @@ -364,7 +370,7 @@ static void set_cli_start(module_id_t module_idP, uint8_t start) #ifdef OPENAIR2 int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_Flow_Unit omv_data) { - module_id_t i, j; + module_id_t i; omv_data.end = 0; //omv_data.total_num_nodes = NB_UE_INST + NB_eNB_INST; @@ -377,7 +383,7 @@ int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_F omv_data.geo[i].node_type = 0; //eNB enb_node_list = enb_node_list->next; omv_data.geo[i].Neighbors = 0; - +/* for (j = NB_RU; j < NB_UE_INST + NB_RU; j++) { if (is_UE_active (i, j - NB_RU) == 1) { omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j; @@ -387,6 +393,7 @@ int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_F "[RU %d][UE %d] is_UE_active(i,j) %d geo (x%d, y%d) num neighbors %d\n", i, j-NB_RU, is_UE_active(i,j-NB_RU), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors); } } +*/ } } @@ -413,7 +420,7 @@ int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_F ue_node_list = ue_node_list->next; omv_data.geo[i].Neighbors = 0; - +/* for (j = 0; j < NB_RU; j++) { if (is_UE_active (j, i - NB_RU) == 1) { omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j; @@ -423,6 +430,7 @@ int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_F "[UE %d][RU %d] is_UE_active %d geo (x%d, y%d) num neighbors %d\n", i-NB_RU, j, is_UE_active(j,i-NB_RU), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors); } } +*/ } } @@ -493,7 +501,7 @@ l2l1_task (void *args_p) #undef PRINT_STATS /* this undef is to avoid gcc warnings */ #define PRINT_STATS #ifdef PRINT_STATS - int len; + //int len; FILE *UE_stats[NUMBER_OF_UE_MAX]; FILE *UE_stats_th[NUMBER_OF_UE_MAX]; FILE *eNB_stats[NUMBER_OF_eNB_MAX]; @@ -524,11 +532,6 @@ l2l1_task (void *args_p) } } - // UL scope at eNB 0 - form_enb[UE_inst] = create_lte_phy_scope_enb(); - sprintf (title, "LTE UL SCOPE UE %d to eNB %d", UE_inst, eNB_inst); - fl_show_form (form_enb[UE_inst]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - } } @@ -624,13 +627,8 @@ l2l1_task (void *args_p) } #endif - module_id_t enb_id; - module_id_t UE_id; + - if (abstraction_flag == 1) { - for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) - dl_phy_sync_success (UE_id, 0, 0,1); //UE_id%NB_eNB_INST); - } start_meas (&oaisim_stats); @@ -699,8 +697,8 @@ l2l1_task (void *args_p) //oai_emulation.info.time_ms += 1; oai_emulation.info.time_s += 0.01; // emu time in s, each frame lasts for 10 ms // JNote: TODO check the coherency of the time and frame (I corrected it to 10 (instead of 0.01) - update_omg (frame); // frequency is defined in the omg_global params configurable by the user - update_omg_ocm (); + //update_omg (frame); // frequency is defined in the omg_global params configurable by the user + //update_omg_ocm (); #ifdef OPENAIR2 @@ -740,19 +738,16 @@ l2l1_task (void *args_p) CC_id=0; int all_done=0; - while (all_done==0) { pthread_mutex_lock(&subframe_mutex); - int subframe_ru_mask_local = subframe_ru_mask; - int subframe_UE_mask_local = subframe_UE_mask; + int subframe_ru_mask_local = (subframe_select(&RC.ru[0]->frame_parms,(sf+4)%10)!=SF_UL) ? subframe_ru_mask : ((1<<NB_RU)-1); + int subframe_UE_mask_local = (RC.ru[0]->frame_parms.frame_type == FDD || subframe_select(&RC.ru[0]->frame_parms,(sf+4)%10)!=SF_DL) ? subframe_UE_mask : ((1<<NB_UE_INST)-1); pthread_mutex_unlock(&subframe_mutex); - LOG_D(EMU,"Frame %d, Subframe %d: Checking masks %x,%x\n",frame,sf,subframe_ru_mask_local,subframe_UE_mask_local); + LOG_D(EMU,"Frame %d, Subframe %d, NB_RU %d, NB_UE %d: Checking masks %x,%x\n",frame,sf,NB_RU,NB_UE_INST,subframe_ru_mask_local,subframe_UE_mask_local); if ((subframe_ru_mask_local == ((1<<NB_RU)-1)) && - (subframe_UE_mask_local == ((1<<NB_UE_INST)-1))) - all_done=1; - else - usleep(1500); + (subframe_UE_mask_local == ((1<<NB_UE_INST)-1))) all_done=1; + else usleep(1500); } @@ -772,11 +767,11 @@ l2l1_task (void *args_p) */ for (ru_id=0;ru_id<NB_RU;ru_id++) { current_ru_rx_timestamp[ru_id][CC_id] += RC.ru[ru_id]->frame_parms.samples_per_tti; - LOG_D(EMU,"RU %d/%d: TS %llu\n",ru_id,CC_id,current_ru_rx_timestamp[ru_id][CC_id]); + LOG_D(EMU,"RU %d/%d: TS %"PRIi64"\n",ru_id,CC_id,current_ru_rx_timestamp[ru_id][CC_id]); } for (UE_inst = 0; UE_inst<NB_UE_INST;UE_inst++) { current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti; - LOG_D(EMU,"UE %d/%d: TS %llu\n",UE_id,CC_id,current_UE_rx_timestamp[UE_inst][CC_id]); + LOG_D(EMU,"UE %d/%d: TS %"PRIi64"\n",UE_inst,CC_id,current_UE_rx_timestamp[UE_inst][CC_id]); } for (eNB_inst = oai_emulation.info.first_enb_local; @@ -797,15 +792,6 @@ l2l1_task (void *args_p) PHY_vars_eNB_g[eNB_inst][0]->frame_parms.Nid_cell); */ -#ifdef OPENAIR2 - //Application: traffic gen - update_otg_eNB (eNB_inst, oai_emulation.info.time_ms); - - //IP/OTG to PDCP and PDCP to IP operation - // pdcp_run (frame, 1, 0, eNB_inst); //PHY_vars_eNB_g[eNB_id]->Mod_id -#endif - - #ifdef PRINT_STATS if((sf==9) && frame%10==0) @@ -819,9 +805,7 @@ l2l1_task (void *args_p) fwrite (stats_buffer, 1, len, eNB_stats[eNB_inst]); fflush(eNB_stats[eNB_inst]); } - */ #ifdef OPENAIR2 - if (eNB_l2_stats) { len = dump_eNB_l2_stats (stats_buffer, 0); rewind (eNB_l2_stats); @@ -830,6 +814,7 @@ l2l1_task (void *args_p) } #endif +*/ #endif } }// eNB_inst loop @@ -840,200 +825,6 @@ l2l1_task (void *args_p) #endif - /* - clear_UE_transport_info (oai_emulation.info.nb_ue_local); - clear_UE_transport_info (oai_emulation.info.nb_ue_local); - - for (UE_inst = oai_emulation.info.first_ue_local; - (UE_inst < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local)); - UE_inst++) { - if (oai_emulation.info.cli_start_ue[UE_inst] != 0) { -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - -#else - - if (frame >= (UE_inst * 20)) // activate UE only after 20*UE_id frames so that different UEs turn on separately -#endif - { - LOG_D(EMU, - "PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n", - UE_inst, frame % MAX_FRAME_NUMBER, slot, next_slot >> 1, - last_slot >> 1); - - if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0] - != NOT_SYNCHED) { - if (frame > 0) { - PHY_vars_UE_g[UE_inst][0]->frame_rx = frame % MAX_FRAME_NUMBER; - PHY_vars_UE_g[UE_inst][0]->slot_rx = last_slot; - PHY_vars_UE_g[UE_inst][0]->slot_tx = next_slot; - - if (next_slot > 1) - PHY_vars_UE_g[UE_inst][0]->frame_tx = frame % MAX_FRAME_NUMBER; - else - PHY_vars_UE_g[UE_inst][0]->frame_tx = (frame + 1) % MAX_FRAME_NUMBER; -#ifdef OPENAIR2 - //Application - update_otg_UE (UE_inst, oai_emulation.info.time_ms); - - //Access layer - // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, ENB_FLAG_NO, NOT_A_RNTI, frame, next_slot>>1, 0); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, 0, ENB_FLAG_NO, NOT_A_RNTI, frame % MAX_FRAME_NUMBER, next_slot); - pdcp_run (&ctxt); -#endif - - for (CC_id = 0; CC_id < MAX_NUM_CCs; - CC_id++) { - phy_procedures_UE_lte ( - PHY_vars_UE_g[UE_inst][CC_id], - 0, abstraction_flag, - normal_txrx, no_relay, - NULL); - } - - ue_data[UE_inst]->tx_power_dBm = - PHY_vars_UE_g[UE_inst][0]->tx_power_dBm; - } - } else { - if (abstraction_flag == 1) { - LOG_E(EMU, - "sync not supported in abstraction mode (UE%d,mode%d)\n", - UE_inst, - PHY_vars_UE_g[UE_inst][0]->UE_mode[0]); - exit (-1); - } - - if ((frame > 0) - && (last_slot - == (LTE_SLOTS_PER_FRAME - - 2))) { - initial_sync (PHY_vars_UE_g[UE_inst][0], - normal_txrx); - - } - } - -#ifdef PRINT_STATS - - if(last_slot==2 && frame%10==0) { - if (UE_stats_th[UE_inst]) { - fprintf(UE_stats_th[UE_inst],"%d %d\n",frame%MAX_FRAME_NUMBER, PHY_vars_UE_g[UE_inst][0]->bitrate[0]/1000); - } - } - - if (UE_stats[UE_inst]) { - len = dump_ue_stats (PHY_vars_UE_g[UE_inst][0], stats_buffer, 0, normal_txrx, 0); - rewind (UE_stats[UE_inst]); - fwrite (stats_buffer, 1, len, UE_stats[UE_inst]); - fflush(UE_stats[UE_inst]); - } - -#endif - } - } - } - -#if defined(Rel10) || defined(Rel14) - - for (RN_id=oai_emulation.info.first_rn_local; - RN_id<oai_emulation.info.first_rn_local+oai_emulation.info.nb_rn_local; - RN_id++) { - // UE id and eNB id of the RN - UE_inst= oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local + RN_id;// NB_UE_INST + RN_id - eNB_inst= oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local + RN_id;// NB_eNB_INST + RN_id - - // currently only works in FDD - if (oai_emulation.info.eMBMS_active_state == 4) { - r_type = multicast_relay; - //LOG_I(EMU,"Activating the multicast relaying\n"); - } else { - LOG_E(EMU,"Not supported eMBMS option when relaying is enabled %d\n", r_type); - exit(-1); - } - - PHY_vars_RN_g[RN_id]->frame = frame % MAX_FRAME_NUMBER; - - if ( oai_emulation.info.frame_type == 0) { - // RN == UE - if (frame>0) { - if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0] != NOT_SYNCHED) { - LOG_D(EMU,"[RN %d] PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n", - RN_id, UE_inst, frame, slot, next_slot >> 1,last_slot>>1); - PHY_vars_UE_g[UE_inst][0]->frame_rx = frame % MAX_FRAME_NUMBER; - PHY_vars_UE_g[UE_inst][0]->slot_rx = last_slot; - PHY_vars_UE_g[UE_inst][0]->slot_tx = next_slot; - - if (next_slot>1) PHY_vars_UE_g[UE_inst][0]->frame_tx = frame % MAX_FRAME_NUMBER; - else PHY_vars_UE_g[UE_inst][0]->frame_tx = (frame+1) % MAX_FRAME_NUMBER; - - phy_procedures_UE_lte (PHY_vars_UE_g[UE_inst][0], 0, abstraction_flag,normal_txrx, - r_type, PHY_vars_RN_g[RN_id]); - } else if (last_slot == (LTE_SLOTS_PER_FRAME-2)) { - initial_sync(PHY_vars_UE_g[UE_inst][0],normal_txrx); - } - } - - emu_transport (frame % MAX_FRAME_NUMBER, sf<<1, ((sf+4)%10)<<1, subframe_select(&PHY_vars_eNB_g[0][0]->frame_parms,sf), - oai_emulation.info.frame_type[0], ethernet_flag); - - start_meas (&dl_chan_stats); - - for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - //#warning figure out what to do with UE frame_parms during initial_sync - do_DL_sig (r_re0, - r_im0, - r_re, - r_im, - s_re, - s_im, - eNB2UE, - enb_data, - ue_data, - PHY_vars_eNB_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1, - abstraction_flag, - &PHY_vars_eNB_g[0][CC_id]->frame_parms, - UE_inst, CC_id); - do_DL_sig (r_re0, - r_im0, - r_re, - r_im,n - - s_re, - s_im, - eNB2UE, - enb_data, - ue_data, - (PHY_vars_eNB_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1)+1, - abstraction_flag, - &PHY_vars_eNB_g[0][CC_id]->frame_parms, - UE_inst, CC_id); - } - - stop_meas (&dl_chan_stats); - - - start_meas (&ul_chan_stats); - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - //#warning figure out what to do with UE frame_parms during initial_sync - do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, - enb_data, ue_data, - PHY_vars_UE_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1, - abstraction_flag, - &PHY_vars_eNB_g[0][CC_id]->frame_parms, - frame % MAX_FRAME_NUMBER, CC_id); - do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, - enb_data, ue_data, - (PHY_vars_UE_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1)+1, - abstraction_flag, - &PHY_vars_eNB_g[0][CC_id]->frame_parms, - frame % MAX_FRAME_NUMBER, CC_id); - } - - stop_meas (&ul_chan_stats); - - */ - if ((sf == 0) && ((frame % MAX_FRAME_NUMBER) == 0) && (abstraction_flag == 0) && (oai_emulation.info.n_frames == 1)) { @@ -1070,7 +861,7 @@ l2l1_task (void *args_p) } - update_ocm (); + //update_ocm (); /* if ((frame >= 10) && (frame <= 11) && (abstraction_flag == 0) #ifdef PROC @@ -1185,6 +976,23 @@ l2l1_task (void *args_p) return NULL; } +/* + * The following two functions are meant to restart *the lte-softmodem* and are + * here to make oaisim compile. A restart command from the controller will be + * ignored in oaisim. + */ +int stop_L1L2(int enb_id) +{ + LOG_W(FLEXRAN_AGENT, "stop_L1L2() not supported in oaisim\n"); + return 0; +} + +int restart_L1L2(int enb_id) +{ + LOG_W(FLEXRAN_AGENT, "restart_L1L2() not supported in oaisim\n"); + return 0; +} + #if T_TRACER int T_wait = 1; /* by default we wait for the tracer */ int T_port = 2021; /* default port to listen to to wait for the tracer */ @@ -1192,8 +1000,8 @@ int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ #endif -void wait_RUs() { - +void wait_RUs(void) +{ int i; // wait for all RUs to be configured over fronthaul @@ -1237,9 +1045,23 @@ void wait_RUs() { printf("RUs are ready, let's go\n"); } -void init_UE(int,int,int); +void init_UE(int,int,int,int); void init_RU(const char*); +void set_UE_defaults(int nb_ue) { + + for (int UE_id = 0;UE_id<nb_ue;UE_id++) { + for (int CC_id = 0;CC_id<MAX_NUM_CCs;CC_id++) { + for (uint8_t i=0; i<RX_NB_TH_MAX; i++) { + PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[i][0]->dciFormat = 0; + PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[i][0]->agregationLevel = 0xFF; + } + PHY_vars_UE_g[UE_id][CC_id]->current_dlsch_cqi[0] = 10; + PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm = 23; + } + } +} + static void print_current_directory(void) { @@ -1250,9 +1072,9 @@ static void print_current_directory(void) printf("working directory: %s\n", dir); } -/*------------------------------------------------------------------------------*/ -int -main (int argc, char **argv) +void init_devices(void); + +int main (int argc, char **argv) { clock_t t; @@ -1270,12 +1092,12 @@ main (int argc, char **argv) int node_id; int port,Process_Flag=0,wgt,Channel_Flag=0,temp; #endif - int i; //default parameters oai_emulation.info.n_frames = MAX_FRAME_NUMBER; //1024; //10; oai_emulation.info.n_frames_flag = 0; //fixme snr_dB = 30; + NB_UE_INST = 1; //Default values if not changed by the user in get_simulation_options(); pdcp_period = 1; @@ -1292,7 +1114,7 @@ main (int argc, char **argv) // start thread for log gen log_thread_init (); - init_oai_emulation (); // to initialize everything !!! + //init_oai_emulation (); // to initialize everything !!! // get command-line options get_simulation_options (argc, argv); //Command-line options @@ -1329,7 +1151,37 @@ main (int argc, char **argv) #endif // configure oaisim with OCG - oaisim_config (); // config OMG and OCG, OPT, OTG, OLG + //oaisim_config (); // config OMG and OCG, OPT, OTG, OLG + logInit(); + +#if defined(ENABLE_ITTI) + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, oai_emulation.info.itti_dump_file); + MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); +#endif + + set_glog(LOG_INFO, 0x15); + + + //set_log(OCG, LOG_DEBUG, 1); + //set_log(EMU, LOG_INFO, 20); + set_log(MAC, LOG_DEBUG, 1); + set_log(RLC, LOG_TRACE, 1); + //set_log(PHY, LOG_DEBUG, 1); + set_log(PDCP, LOG_TRACE, 1); + set_log(RRC, LOG_DEBUG, 1); + //set_log(OCM, LOG_INFO, 20); + //set_log(OTG, LOG_INFO, 1); + set_comp_log(OCG, LOG_ERR, 0x15,1); + set_comp_log(EMU, LOG_DEBUG, 0x15,20); + set_comp_log(MAC, LOG_TRACE, 0x15,1); + set_comp_log(RLC, LOG_TRACE, 0x15,1); + set_comp_log(PHY, LOG_TRACE, 0x15, 1); + set_comp_log(PDCP, LOG_DEBUG, 0x15,1); + set_comp_log(RRC, LOG_DEBUG, 0x15,1); + set_comp_log(OCM, LOG_DEBUG, 0x15,20); + set_comp_log(OTG, LOG_DEBUG, 0x15,1); + set_comp_log(OMG, LOG_NOTICE, 0x15,1); + set_comp_log(OPT, LOG_ERR, 0x15,1); if (ue_connection_test == 1) { snr_direction = -snr_step; @@ -1341,15 +1193,11 @@ main (int argc, char **argv) pthread_mutex_init(&sync_mutex, NULL); pthread_mutex_init(&subframe_mutex, NULL); -#ifdef OPENAIR2 - init_omv (); -#endif //Before this call, NB_UE_INST and NB_eNB_INST are not set correctly check_and_adjust_params (); set_seed = oai_emulation.emulation_config.seed.value; - init_otg_pdcp_buffer (); init_seed (set_seed); @@ -1364,17 +1212,20 @@ main (int argc, char **argv) - if (create_tasks(0, - oai_emulation.info.nb_ue_local) < 0) + if (create_tasks_ue(NB_UE_INST) < 0) exit(-1); // need a softer mode printf("Waiting for RUs to get set up\n"); wait_RUs(); - init_UE(NB_UE_INST,0,0); + init_UE(NB_UE_INST,0,0,1); + + set_UE_defaults(NB_UE_INST); + init_ocm (); + printf("Sending sync to all threads\n"); @@ -1383,12 +1234,6 @@ main (int argc, char **argv) pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); -#ifdef SMBV - // Rohde&Schwarz SMBV100A vector signal generator - smbv_init_config(smbv_fname, smbv_nframes); - smbv_write_config_from_frame_parms(smbv_fname, &PHY_vars_eNB_g[0][0]->frame_parms); -#endif - /* #if defined (FLEXRAN_AGENT_SB_IF) flexran_agent_start(); #endif */ @@ -1493,6 +1338,8 @@ reset_opp_meas_oaisim (void) reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_turbo_encoding_stats); reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_interleaving_stats); reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_multiplexing_stats); + + /* * L2 functions */ @@ -1513,6 +1360,7 @@ reset_opp_meas_oaisim (void) reset_meas (&UE_pdcp_stats[UE_id].pdcp_ip); reset_meas (&UE_pdcp_stats[UE_id].ip_pdcp); + } for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) { @@ -1633,8 +1481,10 @@ print_opp_meas_oaisim (void) &oaisim_stats, &oaisim_stats_f); - print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx, - "[UE][total_phy_proc_rx]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0], + "[UE][total_phy_proc_rx[0]]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[1], + "[UE][total_phy_proc_rx[1]]", &oaisim_stats, &oaisim_stats_f); // print_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_demod_stats, // "[UE][ofdm_demod]", &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->rx_dft_stats, "[UE][rx_dft]", @@ -1892,11 +1742,6 @@ oai_shutdown (void) #endif - //Perform KPI measurements - if (oai_emulation.info.otg_enabled == 1){ - LOG_N(EMU,"calling OTG kpi gen .... \n"); - kpi_gen (); - } if (oai_emulation.info.opp_enabled == 1) print_opp_meas_oaisim (); @@ -1951,18 +1796,6 @@ oai_shutdown (void) } } //End of PHY abstraction changes -#ifdef OPENAIR2 - mac_top_cleanup (); -#endif - - // stop OMG - stop_mobility_generator (omg_param_list); //omg_param_list.mobility_type -#ifdef OPENAIR2 - - if (oai_emulation.info.omv_enabled == 1) - omv_end (pfd[1], omv_data); - -#endif if ((oai_emulation.info.ocm_enabled == 1) && (ethernet_flag == 0) && (ShaF != NULL)) { @@ -1973,9 +1806,6 @@ oai_shutdown (void) if (opt_enabled == 1) terminate_opt (); - if (oai_emulation.info.cli_enabled) - cli_server_cleanup (); - for (int i = 0; i < NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX; i++) if (oai_emulation.info.oai_ifup[i] == 1) { char interfaceName[8]; @@ -2006,3 +1836,10 @@ get_OAI_emulation () } +// dummy function declarations + +void *rrc_enb_task(void *args_p) +{ + return NULL; +} + diff --git a/targets/SIMU/USER/oaisim.h b/targets/SIMU/USER/oaisim.h index ce21470ed4918e57310472946a20f930e6b305f2..1ddc09398322cbb2cd91463e818a5d12ae4efc0f 100644 --- a/targets/SIMU/USER/oaisim.h +++ b/targets/SIMU/USER/oaisim.h @@ -26,15 +26,16 @@ #include <stdio.h> #include <time.h> -#include "SIMULATION/TOOLS/defs.h" -#include "SIMULATION/RF/defs.h" +#include "SIMULATION/TOOLS/sim.h" +#include "SIMULATION/RF/rf.h" #include "PHY/types.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" #include "oaisim_config.h" #include "init_lte.h" #ifdef OPENAIR2 -#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/mac.h" #include "UTIL/OMV/structures.h" #endif @@ -48,10 +49,11 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM uint32_t frame,int eNB_id,uint8_t CC_id); void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs], - node_desc_t *enb_data[NUMBER_OF_RU_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX], + node_desc_t *enb_data[NUMBER_OF_RU_MAX], + node_desc_t *ue_data[NUMBER_OF_UE_MAX], uint16_t subframe, - uint16_t offset, - uint16_t length, + uint32_t offset, + uint32_t length, uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,uint8_t UE_id,int CC_id); void init_ue(node_desc_t *ue_data, UE_Antenna ue_ant);//Abstraction changes diff --git a/targets/SIMU/USER/oaisim_config.h b/targets/SIMU/USER/oaisim_config.h index fe1309b7a48531033474e6bf7413bd54a9b0642c..a403252d06430f214ba3c30e521f1e4652e8f000 100644 --- a/targets/SIMU/USER/oaisim_config.h +++ b/targets/SIMU/USER/oaisim_config.h @@ -49,10 +49,8 @@ The current sturcture of oaisim is shown by the figure. #include "UTIL/OPT/opt.h" // to test OPT #include "UTIL/OMG/omg.h" #include "UTIL/CLI/cli_if.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SIMULATION/ETH_TRANSPORT/defs.h" -#include "PHY/defs.h" +#include "PHY/defs_eNB.h" +#include "PHY/phy_extern.h" /** @defgroup _init_oai Initial oaisim * @ingroup _fn diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index ae139b797f74e374de0efdcae64bd5103b84612a..a302c12ff327e3bef62371db9da1f88b1632e6db 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -43,29 +43,22 @@ #include "assertions.h" #include "oaisim_functions.h" -#include "PHY/extern.h" -#include "LAYER2/MAC/extern.h" -#ifdef OPENAIR2 -#include "LAYER2/MAC/proto.h" -#endif +#include "PHY/phy_extern.h" +#include "PHY/phy_extern_ue.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "LAYER2/PDCP_v10.1.0/pdcp_primitives.h" -#include "RRC/LITE/extern.h" +#include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#include "PHY_INTERFACE/extern.h" +#include "PHY_INTERFACE/phy_interface_extern.h" //#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" -#include "SCHED/extern.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" #include "UTIL/OCG/OCG_extern.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "UTIL/OTG/otg_config.h" #include "UTIL/OTG/otg_tx.h" -#if ENABLE_RAL -#include "lteRALenb.h" -#include "lteRALue.h" -#endif - #include "cor_SF_sim.h" #include "enb_config.h" @@ -80,10 +73,8 @@ #include "../../ARCH/COMMON/common_lib.h" #include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" -#ifdef SMBV -extern uint8_t config_smbv; -extern char smbv_ip[16]; -#endif +#include "ENB_APP/enb_paramdef.h" +#include "common/config/config_userapi.h" //constant for OAISIM soft realtime calibration #define SF_DEVIATION_OFFSET_NS 100000 //= 0.1ms : should be as a number of UE @@ -134,34 +125,14 @@ int sleep_time_us = 0; int phy_test = 0; -#ifdef OPENAIR2 -// omv related info -//pid_t omv_pid; -char full_name[200]; -extern int pfd[2]; // fd for omv : fixme: this could be a local var -char fdstr[10]; -char frames[10]; -char num_enb[10]; -char num_ue[10]; -//area_x, area_y and area_z for omv -char x_area[20]; -char y_area[20]; -char z_area[20]; -char nb_antenna[20]; -char frame_type[10]; -char tdd_config[10]; -#endif - -Packet_OTG_List_t *otg_pdcp_buffer = NULL; - extern node_desc_t *enb_data[NUMBER_OF_RU_MAX]; -extern node_desc_t *ue_data[NUMBER_OF_UE_MAX]; -extern channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs]; -extern channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs]; +extern node_desc_t *ue_data[MAX_MOBILES_PER_ENB]; +extern channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; +extern channel_desc_t *UE2RU[MAX_MOBILES_PER_ENB][NUMBER_OF_RU_MAX][MAX_NUM_CCs]; extern mapping small_scale_names[]; -#if defined(Rel10) || defined(Rel14) -extern pdcp_mbms_t pdcp_mbms_array_ue[NUMBER_OF_UE_MAX][maxServiceCount][maxSessionPerPMCH]; +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +extern pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH]; extern pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH]; #endif @@ -177,6 +148,18 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int oaisim_flag=1; +void RCConfig_sim(void) { + + paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; + + + // Get num RU instances + config_getlist( &RUParamList,NULL,0, NULL); + RC.nb_RU = RUParamList.numelt; + + +} + void get_simulation_options(int argc, char *argv[]) { int option; @@ -686,7 +669,7 @@ void get_simulation_options(int argc, char *argv[]) break; case 'u': - oai_emulation.info.nb_ue_local = atoi (optarg); + NB_UE_INST = atoi (optarg); break; case 'U': @@ -782,13 +765,13 @@ void get_simulation_options(int argc, char *argv[]) } } - if ( load_configmodule(argc,argv) == NULL) { + if ( load_configmodule(argc,argv) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } if (RC.config_file_name != NULL) { /* Read eNB configuration file */ - RCConfig(); + RCConfig_sim(); printf("returned with %d eNBs, %d rus\n",RC.nb_inst,RC.nb_RU); oai_emulation.info.nb_enb_local = RC.nb_inst; oai_emulation.info.nb_ru_local = RC.nb_RU; @@ -853,15 +836,15 @@ void check_and_adjust_params(void) { int32_t ret; - int i,j; + //int i,j; - if (oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local > NUMBER_OF_UE_MAX) { - LOG_E(EMU,"Enter fewer than %d UEs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_UE_MAX); + if (oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local > MAX_MOBILES_PER_ENB) { + LOG_E(EMU,"Enter fewer than %d UEs/RNs for the moment or change the MAX_MOBILES_PER_ENB\n", MAX_MOBILES_PER_ENB); exit(EXIT_FAILURE); } if (oai_emulation.info.nb_enb_local + oai_emulation.info.nb_rn_local > NUMBER_OF_eNB_MAX) { - LOG_E(EMU,"Enter fewer than %d eNBs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_eNB_MAX); + LOG_E(EMU,"Enter fewer than %d eNBs/RNs for the moment or change the MAX_MOBILES_PER_ENB\n", NUMBER_OF_eNB_MAX); exit(EXIT_FAILURE); } @@ -916,80 +899,15 @@ void check_and_adjust_params(void) } // ethernet flag */ // - NB_UE_INST = oai_emulation.info.nb_ue_local + oai_emulation.info.nb_ue_remote; - NB_eNB_INST = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_enb_remote; - NB_RN_INST = oai_emulation.info.nb_rn_local + oai_emulation.info.nb_rn_remote; - NB_RU = oai_emulation.info.nb_ru_local + oai_emulation.info.nb_ru_remote; + + NB_RU = RC.nb_RU; #if defined(PDCP_USE_NETLINK_QUEUES) && defined(OPENAIR2) pdcp_netlink_init(); #endif - if (NB_RN_INST > 0 ) { - LOG_N(EMU,"Total number of RN %d (local %d, remote %d) mobility (the same as eNB) %s \n", NB_RN_INST,oai_emulation.info.nb_rn_local,oai_emulation.info.nb_rn_remote, - oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option); - - LOG_N(EMU,"Adjust the number of eNB inst (%d->%d) and UE inst (%d->%d)\n ", - NB_eNB_INST, NB_eNB_INST+NB_RN_INST, - NB_UE_INST, NB_UE_INST+NB_RN_INST); - NB_eNB_INST+=NB_RN_INST; - NB_UE_INST+=NB_RN_INST; - } - - LOG_I(EMU,"Total number of UE %d (first local %d , num local %d, remote %d, relay %d) mobility %s \n", - NB_UE_INST,oai_emulation.info.first_ue_local, oai_emulation.info.nb_ue_local,oai_emulation.info.nb_ue_remote, - NB_RN_INST, - oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option); - - LOG_I(EMU,"Total number of eNB %d (local %d, remote %d, relay %d) mobility %s \n", - NB_eNB_INST,oai_emulation.info.nb_enb_local,oai_emulation.info.nb_enb_remote, - NB_RN_INST, - oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option); - } -#ifdef OPENAIR2 -void init_omv(void) -{ - if (oai_emulation.info.omv_enabled == 1) { - - if(pipe(pfd) == -1) - perror("pipe error \n"); - - snprintf( full_name, sizeof(full_name), "%s/UTIL/OMV/OMV",getenv("OPENAIR2_DIR") ); - LOG_I(EMU,"Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, pfd[0],pfd[1]); - - switch(fork()) { - case -1 : - perror("fork failed \n"); - break; - - case 0 : // child is going to be the omv, it is the reader - if(close(pfd[1]) == -1 ) // we close the write desc. - perror("close on write\n" ); - - sprintf(fdstr, "%d", pfd[0] ); - sprintf(num_enb, "%d", NB_eNB_INST); - sprintf(num_ue, "%d", NB_UE_INST); - sprintf(x_area, "%f", oai_emulation.topology_config.area.x_m ); - sprintf(y_area, "%f", oai_emulation.topology_config.area.y_m ); - sprintf(z_area, "%f", 200.0 ); - sprintf(frames, "%d", oai_emulation.info.n_frames); - sprintf(nb_antenna, "%d", 4); - sprintf(frame_type, "%s", (oai_emulation.info.frame_type[0] == 0) ? "FDD" : "TDD"); - sprintf(tdd_config, "%d", oai_emulation.info.tdd_config[0]); - // execl is used to launch the visualisor - execl(full_name,"OMV", fdstr, frames, num_enb, num_ue, x_area, y_area, z_area, nb_antenna, frame_type, tdd_config,NULL ); - perror( "error in execl the OMV" ); - } - - //parent - if(close( pfd[0] ) == -1 ) // we close the write desc. - perror("close on read\n" ); - } -} -#endif - void init_seed(uint8_t set_seed) { @@ -1005,9 +923,9 @@ void init_seed(uint8_t set_seed) } openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; -openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs]; +openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; openair0_timestamp last_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; -openair0_timestamp last_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs]; +openair0_timestamp last_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; int ru_trx_start(openair0_device *device) { return(0); @@ -1066,26 +984,27 @@ int ru_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** while (sample_count<nsamps) { while (current_ru_rx_timestamp[ru_id][CC_id]< (nsamps+last_ru_rx_timestamp[ru_id][CC_id])) { - LOG_D(EMU,"RU: current TS %llu, last TS %llu, sleeping\n",current_ru_rx_timestamp[ru_id][CC_id],last_ru_rx_timestamp[ru_id][CC_id]); + LOG_D(EMU,"RU: current TS %"PRIi64", last TS %"PRIi64", sleeping\n",current_ru_rx_timestamp[ru_id][CC_id],last_ru_rx_timestamp[ru_id][CC_id]); usleep(500); } subframe = (last_ru_rx_timestamp[ru_id][CC_id]/RC.ru[ru_id]->frame_parms.samples_per_tti)%10; - LOG_D(EMU,"RU_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n", - subframe,(unsigned long long)*ptimestamp, - (unsigned long long)current_ru_rx_timestamp[ru_id][CC_id]); - - do_UL_sig(UE2RU, - enb_data, - ue_data, - subframe, - 0, // abstraction_flag - &RC.ru[ru_id]->frame_parms, - 0, // frame is only used for abstraction - ru_id, - CC_id); - + if (subframe_select(&RC.ru[ru_id]->frame_parms,subframe) != SF_DL || RC.ru[ru_id]->frame_parms.frame_type == FDD) { + LOG_D(EMU,"RU_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n", + subframe,(unsigned long long)*ptimestamp, + (unsigned long long)current_ru_rx_timestamp[ru_id][CC_id]); + + do_UL_sig(UE2RU, + enb_data, + ue_data, + subframe, + 0, // abstraction_flag + &RC.ru[ru_id]->frame_parms, + 0, // frame is only used for abstraction + ru_id, + CC_id); + } last_ru_rx_timestamp[ru_id][CC_id] += RC.ru[ru_id]->frame_parms.samples_per_tti; sample_count += RC.ru[ru_id]->frame_parms.samples_per_tti; } @@ -1099,62 +1018,70 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** int UE_id = device->Mod_id; int CC_id = device->CC_id; - int subframe,new_subframe; + int subframe; int sample_count=0; int read_size; + int sptti = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti; *ptimestamp = last_UE_rx_timestamp[UE_id][CC_id]; - LOG_D(EMU,"[TXPATH]UE_trx_read nsamps %d TS %llu (%llu) antenna %d\n",nsamps, + LOG_D(EMU,"UE %d DL simulation 0: UE_trx_read nsamps %d TS %llu (%llu, offset %d) antenna %d\n", + UE_id, + nsamps, (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id], (unsigned long long)last_UE_rx_timestamp[UE_id][CC_id], + (int)(last_UE_rx_timestamp[UE_id][CC_id]%sptti), cc); - if (nsamps < PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti) + if (nsamps < sptti) read_size = nsamps; else - read_size = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti; + read_size = sptti; while (sample_count<nsamps) { + LOG_D(EMU,"UE %d: DL simulation 1: UE_trx_read : current TS now %"PRIi64", last TS %"PRIi64"\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); while (current_UE_rx_timestamp[UE_id][CC_id] < (last_UE_rx_timestamp[UE_id][CC_id]+read_size)) { - LOG_D(EMU,"[TXPATH]UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); + LOG_D(EMU,"UE %d: DL simulation 2: UE_trx_read : current TS %"PRIi64", last TS %"PRIi64", sleeping\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); usleep(500); } - - // LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); + LOG_D(EMU,"UE %d: DL simulation 3: UE_trx_read : current TS now %"PRIi64", last TS %"PRIi64"\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); // if we cross a subframe-boundary - subframe = (last_UE_rx_timestamp[UE_id][CC_id]/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10; - new_subframe = ((last_UE_rx_timestamp[UE_id][CC_id]+read_size)/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10; - if (new_subframe!=subframe) { - // tell top-level we are busy - pthread_mutex_lock(&subframe_mutex); - subframe_UE_mask|=(1<<UE_id); - LOG_D(EMU,"Setting UE_id %d mask to busy (%d)\n",UE_id,subframe_UE_mask); - pthread_mutex_unlock(&subframe_mutex); + subframe = (last_UE_rx_timestamp[UE_id][CC_id]/sptti)%10; - } + // tell top-level we are busy + pthread_mutex_lock(&subframe_mutex); + subframe_UE_mask|=(1<<UE_id); + LOG_D(EMU,"Setting UE_id %d mask to busy (%d)\n",UE_id,subframe_UE_mask); + pthread_mutex_unlock(&subframe_mutex); + + + + LOG_D(PHY,"UE %d: DL simulation 4: UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu,nsamps %d)\n", + UE_id,subframe,(unsigned long long)*ptimestamp, + (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id], + nsamps); + + LOG_D(EMU,"UE %d: DL simulation 5: Doing DL simulation for %d samples starting in subframe %d at offset %d\n", + UE_id,nsamps,subframe, + (int)(last_UE_rx_timestamp[UE_id][CC_id]%sptti)); - LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n", - subframe,(unsigned long long)*ptimestamp, - (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]); do_DL_sig(RU2UE, enb_data, ue_data, subframe, - last_UE_rx_timestamp[UE_id][CC_id]%PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti, - nsamps, + last_UE_rx_timestamp[UE_id][CC_id]%sptti, + sptti, 0, //abstraction_flag, &PHY_vars_UE_g[UE_id][CC_id]->frame_parms, UE_id, CC_id); - - LOG_D(EMU,"[TXPATH]UE_trx_read @ TS %llu (%llu)=> frame %d, subframe %d\n", - (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id], - (unsigned long long)last_UE_rx_timestamp[UE_id][CC_id], - ((unsigned long long)last_UE_rx_timestamp[UE_id][CC_id]/(PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti*10))&1023, + LOG_D(EMU,"UE %d: DL simulation 6: UE_trx_read @ TS %"PRIi64" (%"PRIi64")=> frame %d, subframe %d\n", + UE_id, current_UE_rx_timestamp[UE_id][CC_id], + last_UE_rx_timestamp[UE_id][CC_id], + (int)((last_UE_rx_timestamp[UE_id][CC_id]/(sptti*10))&1023), subframe); last_UE_rx_timestamp[UE_id][CC_id] += read_size; @@ -1329,7 +1256,6 @@ void init_devices(void){ PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_freq_func = UE_trx_set_freq; PHY_vars_UE_g[UE_id][CC_id]->rfdevice.trx_set_gains_func = UE_trx_set_gains; last_UE_rx_timestamp[UE_id][CC_id] = 0; - } } } @@ -1342,64 +1268,20 @@ void init_ocm(void) /* Added for PHY abstraction */ - char* frame_type = "unknown"; + /* TODO: frame_type is unused, is it intended? */ + //char* frame_type = "unknown"; LTE_DL_FRAME_PARMS *fp = &RC.ru[0]->frame_parms; - switch (fp->frame_type) { - case FDD: - frame_type = "FDD"; - break; - - case TDD: - frame_type = "TDD"; - break; - } - - if (abstraction_flag) { - - get_beta_map(); - get_MIESM_param(); - - //load_pbch_desc(); - } - - - for (ru_id = 0; ru_id < RC.nb_RU; ru_id++) { - enb_data[ru_id] = (node_desc_t *)malloc(sizeof(node_desc_t)); - init_enb(enb_data[ru_id],oai_emulation.environment_system_config.antenna.eNB_antenna); - } - - for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) { - ue_data[UE_id] = (node_desc_t *)malloc(sizeof(node_desc_t)); - init_ue(ue_data[UE_id],oai_emulation.environment_system_config.antenna.UE_antenna); - } - - if ((oai_emulation.info.ocm_enabled == 1)&& (ethernet_flag == 0 ) && - (oai_emulation.environment_system_config.fading.shadowing.decorrelation_distance_m>0) && - (oai_emulation.environment_system_config.fading.shadowing.variance_dB>0)) { - - // init SF map here!!! - map1 =(int)oai_emulation.topology_config.area.x_m; - map2 =(int)oai_emulation.topology_config.area.y_m; - ShaF = init_SF(map1,map2,oai_emulation.environment_system_config.fading.shadowing.decorrelation_distance_m,oai_emulation.environment_system_config.fading.shadowing.variance_dB); - - // size of area to generate shadow fading map - LOG_D(EMU,"Simulation area x=%f, y=%f\n", - oai_emulation.topology_config.area.x_m, - oai_emulation.topology_config.area.y_m); - } - - if (abstraction_flag == 0) - init_channel_vars (fp, &s_re, &s_im, &r_re, &r_im, &r_re0, &r_im0); + init_channel_vars (fp, &s_re, &s_im, &r_re, &r_im, &r_re0, &r_im0); // initialize channel descriptors + LOG_I(PHY,"Initializing channel descriptors (nb_RU %d, nb_UE %d)\n",RC.nb_RU,NB_UE_INST); for (ru_id = 0; ru_id < RC.nb_RU; ru_id++) { for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - LOG_D(OCM,"Initializing channel (%s, %d) from eNB %d to UE %d\n", oai_emulation.environment_system_config.fading.small_scale.selected_option, - map_str_to_int(small_scale_names,oai_emulation.environment_system_config.fading.small_scale.selected_option), ru_id, UE_id); - + LOG_I(PHY,"Initializing channel descriptors (RU %d, UE %d) for N_RB_DL %d\n",ru_id,UE_id, + RC.ru[ru_id]->frame_parms.N_RB_DL); RU2UE[ru_id][UE_id][CC_id] = new_channel_desc_scm(RC.ru[ru_id]->nb_tx, PHY_vars_UE_g[UE_id][CC_id]->frame_parms.nb_antennas_rx, @@ -1428,22 +1310,29 @@ void init_ocm(void) // to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed. //UE2RU[UE_id][ru_id] = RU2UE[ru_id][UE_id]; - } - } - } -} -void init_otg_pdcp_buffer(void) -{ - module_id_t i; - otg_pdcp_buffer = malloc((NB_UE_INST + NB_eNB_INST) * sizeof(Packet_OTG_List_t)); + AssertFatal(RU2UE[ru_id][UE_id][CC_id]!=NULL,"RU2UE[%d][%d][%d] is null\n",ru_id,UE_id,CC_id); + AssertFatal(UE2RU[UE_id][ru_id][CC_id]!=NULL,"UE2RU[%d][%d][%d] is null\n",UE_id,ru_id,CC_id); + //pathloss: -132.24 dBm/15kHz RE + target SNR - eNB TX power per RE + if (ru_id == (UE_id % RC.nb_RU)) { + RU2UE[ru_id][UE_id][CC_id]->path_loss_dB = -132.24 + snr_dB - RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower; + UE2RU[UE_id][ru_id][CC_id]->path_loss_dB = -132.24 + snr_dB - RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower; + } else { + RU2UE[ru_id][UE_id][CC_id]->path_loss_dB = -132.24 + sinr_dB - RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower; + UE2RU[UE_id][ru_id][CC_id]->path_loss_dB = -132.24 + sinr_dB - RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower; + } + + LOG_D(OCM,"Path loss from eNB %d to UE %d (CCid %d)=> %f dB (eNB TX %d, SNR %f)\n",ru_id,UE_id,CC_id, + RU2UE[ru_id][UE_id][CC_id]->path_loss_dB, + RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower,snr_dB); + - for (i = 0; i < NB_UE_INST + NB_eNB_INST; i++) { - pkt_list_init(&(otg_pdcp_buffer[i])); - //LOG_I(EMU,"HEAD of otg_pdcp_buffer[%d] is %p\n", i, pkt_list_get_head(&(otg_pdcp_buffer[i]))); + } + } } } +/* void update_omg (frame_t frameP) { module_id_t UE_id, eNB_id; @@ -1489,7 +1378,7 @@ void update_ocm() - /* check if the openair channel model is activated used for PHY abstraction : path loss*/ + // check if the openair channel model is activated used for PHY abstraction : path loss if ((oai_emulation.info.ocm_enabled == 1)&& (ethernet_flag == 0 )) { for (ru_id = 0; ru_id < RC.nb_RU; ru_id++) @@ -1501,15 +1390,12 @@ void update_ocm() //LOG_D(OMG," extracting position of eNb...\n"); //display_node_list(enb_node_list); // display_node_list(ue_node_list); - extract_position(enb_node_list, enb_data, RC.nb_RU); + //extract_position(enb_node_list, enb_data, RC.nb_RU); //extract_position_fixed_enb(enb_data, NB_eNB_INST,frame); //LOG_D(OMG," extracting position of UE...\n"); // if (oai_emulation.info.omg_model_ue == TRACE) - extract_position(ue_node_list, ue_data, NB_UE_INST); + //extract_position(ue_node_list, ue_data, NB_UE_INST); - /* if (frame % 50 == 0) - LOG_N(OCM,"Path loss for TTI %d : \n", frame); - */ for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (ru_id = 0; ru_id < RC.nb_RU; ru_id++) { for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) { @@ -1524,10 +1410,10 @@ void update_ocm() //dx = enb_data[ru_id]->x - ue_data[UE_id]->x; //dy = enb_data[ru_id]->y - ue_data[UE_id]->y; //distance = sqrt(dx * dx + dy * dy); - /*LOG_D(LOCALIZE, " OCM distance between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f \n", - ru_id, enb_data[ru_id]->x,enb_data[ru_id]->y, - UE_id, ue_data[UE_id]->x,ue_data[UE_id]->y, - distance);*/ + ///LOG_D(LOCALIZE, " OCM distance between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f \n", + // ru_id, enb_data[ru_id]->x,enb_data[ru_id]->y, + // UE_id, ue_data[UE_id]->x,ue_data[UE_id]->y, + // distance); } } } @@ -1539,7 +1425,7 @@ void update_ocm() for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { AssertFatal(RU2UE[ru_id][UE_id][CC_id]!=NULL,"RU2UE[%d][%d][%d] is null\n",ru_id,UE_id,CC_id); - AssertFatal(UE2RU[ru_id][UE_id][CC_id]!=NULL,"RU2UE[%d][%d][%d] is null\n",ru_id,UE_id,CC_id); + AssertFatal(UE2RU[UE_id][ru_id][CC_id]!=NULL,"UE2RU[%d][%d][%d] is null\n",UE_id,ru_id,CC_id); //pathloss: -132.24 dBm/15kHz RE + target SNR - eNB TX power per RE if (ru_id == (UE_id % RC.nb_RU)) { RU2UE[ru_id][UE_id][CC_id]->path_loss_dB = -132.24 + snr_dB - RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower; @@ -1559,15 +1445,128 @@ void update_ocm() } } + #ifdef OPENAIR2 void update_otg_eNB(module_id_t enb_module_idP, unsigned int ctime) { +#if defined(USER_MODE) && defined(OAI_EMU) + + //int rrc_state=0; + if (oai_emulation.info.otg_enabled ==1 ) { + + int dst_id, app_id; + Packet_otg_elt_t *otg_pkt; + + for (dst_id = 0; dst_id < MAX_MOBILES_PER_ENB; dst_id++) { + for_times += 1; + + // generate traffic if the ue is rrc reconfigured state + //if ((rrc_state=mac_eNB_get_rrc_status(enb_module_idP, dst_id)) > 2 //RRC_CONNECTED + { + if (mac_eNB_get_rrc_status(enb_module_idP, oai_emulation.info.eNB_ue_module_id_to_rnti[enb_module_idP][dst_id]) > 2 ){ + if_times += 1; + + for (app_id=0; app_id<MAX_NUM_APPLICATION; app_id++) { + otg_pkt = malloc (sizeof(Packet_otg_elt_t)); + + (otg_pkt->otg_pkt).sdu_buffer = (uint8_t*) packet_gen(enb_module_idP, dst_id + NB_eNB_INST, app_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size)); + + if ((otg_pkt->otg_pkt).sdu_buffer != NULL) { + otg_times += 1; + (otg_pkt->otg_pkt).rb_id = DTCH-2; // app could be binded to a given DRB + (otg_pkt->otg_pkt).module_id = enb_module_idP; + (otg_pkt->otg_pkt).dst_id = dst_id; + (otg_pkt->otg_pkt).is_ue = 0; + (otg_pkt->otg_pkt).mode = PDCP_TRANSMISSION_MODE_DATA; + //Adding the packet to the OTG-PDCP buffer + pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[enb_module_idP])); + LOG_D(EMU,"[eNB %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d for app id %d \n", + (otg_pkt->otg_pkt).module_id, otg_pkt->otg_pkt.sdu_buffer_size, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id, app_id); + } else { + free(otg_pkt); + otg_pkt=NULL; + } + } + } + } + +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + mbms_service_id_t service_id; + mbms_session_id_t session_id; + rb_id_t rb_id; + + // MBSM multicast traffic + if (ctime >= 500 ) {// only generate when UE can receive MTCH (need to control this value) + for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount + for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH + if (pdcp_mbms_array_eNB[enb_module_idP][service_id][session_id].instanciated_instance == TRUE) { // this service/session is configured + + otg_pkt = malloc (sizeof(Packet_otg_elt_t)); + // LOG_T(OTG,"multicast packet gen for (service/mch %d, session/lcid %d, rb_id %d)\n", service_id, session_id, service_id*maxSessionPerPMCH + session_id); + rb_id = pdcp_mbms_array_eNB[enb_module_idP][service_id][session_id].rb_id; + (otg_pkt->otg_pkt).sdu_buffer = (uint8_t*) packet_gen_multicast(enb_module_idP, session_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size)); + + if ((otg_pkt->otg_pkt).sdu_buffer != NULL) { + (otg_pkt->otg_pkt).rb_id = rb_id; + (otg_pkt->otg_pkt).module_id = enb_module_idP; + (otg_pkt->otg_pkt).dst_id = session_id; + (otg_pkt->otg_pkt).is_ue = FALSE; + //Adding the packet to the OTG-PDCP buffer + (otg_pkt->otg_pkt).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; + pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[enb_module_idP])); + LOG_D(EMU, "[eNB %d] ADD packet (%p) multicast to OTG buffer for dst %d on rb_id %d\n", + (otg_pkt->otg_pkt).module_id, otg_pkt, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id); + } else { + //LOG_I(EMU, "OTG returns null \n"); + free(otg_pkt); + otg_pkt=NULL; + } + + + // old version + // MBSM multicast traffic + #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + if (frame >= 46) {// only generate when UE can receive MTCH (need to control this value) + for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount + for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH + // LOG_I(OTG,"DUY:frame %d, pdcp_mbms_array[module_id][rb_id].instanciated_instance is %d\n",frame,pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].instanciated_instance); + if ((pdcp_mbms_array[module_idP][service_id*maxSessionPerPMCH + session_id].instanciated_instance== module_idP + 1) && (eNB_flag == 1)){ // this service/session is configured + // LOG_T(OTG,"multicast packet gen for (service/mch %d, session/lcid %d)\n", service_id, session_id); + // Duy add + LOG_I(OTG, "frame %d, multicast packet gen for (service/mch %d, session/lcid %d, rb_id %d)\n",frame, service_id, session_id,service_id*maxSessionPerPMCH + session_id); + // end Duy add + rb_id = pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].rb_id; + otg_pkt=(uint8_t*) packet_gen_multicast(module_idP, session_id, ctime, &pkt_size); + if (otg_pkt != NULL) { + LOG_D(OTG,"[eNB %d] sending a multicast packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", eNB_index, module_idP, rb_id, module_idP, session_id, pkt_size); + pdcp_data_req(module_id, frame, eNB_flag, rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pkt_size, otg_pkt,PDCP_TM); + free(otg_pkt); + } + } + } + } + } // end multicast traffic + #endif + + + + } + } + } + + } // end multicast traffic + + +#endif + } + +#else #if 0 // defined(EXMIMO) || defined(OAI_USRP) if (otg_enabled==1) { ctime = frame * 100; - for (dst_id = 0; dst_id < NUMBER_OF_UE_MAX; dst_id++) { + for (dst_id = 0; dst_id < MAX_MOBILES_PER_ENB; dst_id++) { if (mac_get_rrc_status(eNB_index, eNB_flag, dst_id ) > 2) { otg_pkt = malloc (sizeof(Packet_otg_elt_t)); (otg_pkt->otg_pkt).sdu_buffer = packet_gen(module_instP, dst_id, ctime, &pkt_size); @@ -1596,6 +1595,7 @@ void update_otg_UE(module_id_t ue_mod_idP, unsigned int ctime) { } #endif +*/ int init_slot_isr(void) { @@ -1664,6 +1664,13 @@ void init_time() td_avg = TARGET_SF_TIME_NS; } +// dummy function +int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) { + + return(0); + +} + /* int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) { diff --git a/targets/SIMU/USER/sinr_sim.c b/targets/SIMU/USER/sinr_sim.c index 7c752ce432f2b268cc7d11b2efd1f770a2c2482b..2dc86b844301977c9983430ac51e7f89b2725072 100644 --- a/targets/SIMU/USER/sinr_sim.c +++ b/targets/SIMU/USER/sinr_sim.c @@ -27,27 +27,26 @@ #include <time.h> #include <cblas.h> -#include "SIMULATION/TOOLS/defs.h" -#include "SIMULATION/RF/defs.h" +#include "SIMULATION/TOOLS/sim.h" +#include "SIMULATION/RF/rf.h" #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_extern.h" #include "oaisim_config.h" #ifdef OPENAIR2 -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" #include "UTIL/LOG/log_if.h" #include "UTIL/LOG/log_extern.h" -#include "RRC/LITE/extern.h" -#include "PHY_INTERFACE/extern.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface_extern.h" #include "UTIL/OCG/OCG.h" #include "UTIL/OMG/omg.h" #include "UTIL/OPT/opt.h" // to test OPT #endif -#include "SCHED/defs.h" -#include "SCHED/extern.h" #include "oaisim.h"