diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 94ff4b239a..e4d3acf4b1 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -114,6 +114,7 @@ endmacro(add_list_string_option)
####################################################
# compilation flags
#############################################
+
#set(CMAKE_BUILD_TYPE "Debug")
if (CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
@@ -170,7 +171,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU
# these changes are related to hardcoded path to include .h files
add_definitions(-DCMAKER)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3")
-set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O2")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O2")
set(GIT_BRANCH "UNKNOWN")
@@ -195,7 +196,7 @@ if(GIT_FOUND)
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
-
+
# Get the latest commit date of the working branch
execute_process(
COMMAND git log -1 --format=%cd
@@ -223,9 +224,9 @@ add_boolean_option(DISABLE_XER_PRINT False "print XER Format")
add_boolean_option(XER_PRINT False "print XER Format")
add_boolean_option(RRC_MSG_PRINT False "print RRC messages")
add_boolean_option(PDCP_MSG_PRINT False "print PDCP messages to /tmp/pdcp.log")
-add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace
-add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace
-add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace
+add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace
+add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace
+add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace
add_boolean_option(TEST_OMG False "???")
add_boolean_option(DEBUG_OMG False "???")
add_boolean_option(XFORMS False "This adds the possibility to see the signal oscilloscope")
@@ -486,7 +487,7 @@ add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
include_directories("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/")
include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
#set (option_HWEXMIMOLIB_lib "-l ")
-set(HWLIB_EXMIMO_SOURCE
+set(HWLIB_EXMIMO_SOURCE
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
# ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
)
@@ -494,27 +495,27 @@ add_library(oai_exmimodevif MODULE ${HWLIB_EXMIMO_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/")
set (option_HWUSRPLIB_lib "-l uhd")
-set(HWLIB_USRP_SOURCE
+set(HWLIB_USRP_SOURCE
${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
)
add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/")
set (option_HWBLADERFLIB_lib "-l bladerf")
-set(HWLIB_BLADERF_SOURCE
+set(HWLIB_BLADERF_SOURCE
${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
)
add_library(oai_bladerfdevif MODULE ${HWLIB_BLADERF_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/")
-set(HWLIB_LMSSDR_SOURCE
+set(HWLIB_LMSSDR_SOURCE
${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp
)
add_library(oai_lmssdrdevif MODULE ${HWLIB_LMSSDR_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/")
-set(TPLIB_ETHERNET_SOURCE
+set(TPLIB_ETHERNET_SOURCE
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -569,12 +570,12 @@ elseif (${RF_BOARD} STREQUAL "CPRIGW")
)
include_directories("${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/")
set(option_HW_lib "-rdynamic dl")
-
+
endif (${RF_BOARD} STREQUAL "EXMIMO")
if (${TRANSP_PRO} STREQUAL "ETHERNET")
-
+
include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB")
set(TRANSPORT_SOURCE ${TRANSPORT_SOURCE}
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -583,7 +584,7 @@ if (${TRANSP_PRO} STREQUAL "ETHERNET")
)
set(option_TP_lib "-rdynamic -ldl")
-
+
endif (${TRANSP_PRO} STREQUAL "ETHERNET")
##########################################################
@@ -837,13 +838,13 @@ include_directories("${OPENAIR_DIR}")
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
@@ -874,10 +875,10 @@ if (FLEXRAN_AGENT_SB_IF)
${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} )
-
+
add_library(FLPT_MSG
${FLPT_OAI_generated}
${FLPT_source}
@@ -908,12 +909,12 @@ if (FLEXRAN_AGENT_SB_IF)
)
set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT)
#include_directories(${OPENAIR2_DIR}/ENB_APP)
-
+
set(PROTOBUF_LIB "protobuf-c")
-
+
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)
@@ -929,9 +930,9 @@ add_library(HASHTABLE
include_directories(${OPENAIR_DIR}/common/utils/hashtable)
if (MESSAGE_CHART_GENERATOR)
- add_library(MSC
+ add_library(MSC
${OPENAIR_DIR}/common/utils/msc/msc.c
- )
+ )
set(MSC_LIB MSC)
endif()
include_directories(${OPENAIR_DIR}/common/utils/msc)
@@ -1008,7 +1009,7 @@ add_library(SECU_CN ${SECU_CN_SRC})
# Scheduler
################################"
-set(SCHED_SRC
+set(SCHED_SRC
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_eNb.c
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_ue.c
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
@@ -1100,6 +1101,7 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/INIT/lte_parms.c
${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
+ ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
@@ -1301,7 +1303,7 @@ set(libnas_api_OBJS
${NAS_SRC}COMMON/API/NETWORK/nas_message.c
${NAS_SRC}COMMON/API/NETWORK/network_api.c
)
-
+
set(libnas_emm_msg_OBJS
${NAS_SRC}COMMON/EMM/MSG/AttachAccept.c
${NAS_SRC}COMMON/EMM/MSG/AttachComplete.c
@@ -1334,7 +1336,7 @@ set(libnas_emm_msg_OBJS
${NAS_SRC}COMMON/EMM/MSG/TrackingAreaUpdateRequest.c
${NAS_SRC}COMMON/EMM/MSG/UplinkNasTransport.c
)
-
+
set(libnas_esm_msg_OBJS
${NAS_SRC}COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.c
${NAS_SRC}COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.c
@@ -1454,7 +1456,7 @@ set (libnas_utils_OBJS
${NAS_SRC}COMMON/UTIL/OctetString.c
)
-if(NAS_UE)
+if(NAS_UE)
set(libnas_ue_api_OBJS
${NAS_SRC}UE/API/USER/at_command.c
${NAS_SRC}UE/API/USER/at_error.c
@@ -1757,9 +1759,10 @@ add_executable(lte-softmodem
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${GTPU_need_ITTI}
${HW_SOURCE}
- ${TRANSPORT_SOURCE}
+ ${TRANSPORT_SOURCE}
${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
@@ -1794,7 +1797,7 @@ add_executable(lte-softmodem-nos1
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${HW_SOURCE}
- ${TRANSPORT_SOURCE}
+ ${TRANSPORT_SOURCE}
${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
@@ -1818,15 +1821,15 @@ add_executable(rrh_gw
${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
- ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
+ ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${HW_SOURCE}
- ${TRANSPORT_SOURCE}
+ ${TRANSPORT_SOURCE}
${T_SOURCE}
)
target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti)
target_link_libraries(rrh_gw
-Wl,--start-group
- UTIL LFDS
+ UTIL LFDS
-Wl,--end-group )
target_link_libraries (rrh_gw rt pthread m )
target_link_libraries (rrh_gw ${option_HW_lib} ${option_TP_lib})
@@ -1883,13 +1886,15 @@ add_executable(oaisim
${OPENAIR_TARGETS}/SIMU/USER/oaisim_functions.c
${OPENAIR_TARGETS}/SIMU/USER/event_handler.c
${OPENAIR_TARGETS}/SIMU/USER/oaisim.c
+ ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
+ ${OPENAIR_DIR}/common/utils/utils.c
${GTPU_need_ITTI}
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${HW_SOURCE}
- ${TRANSPORT_SOURCE}
+ ${TRANSPORT_SOURCE}
${XFORMS_SOURCE}
${T_SOURCE}
)
@@ -1897,7 +1902,7 @@ add_executable(oaisim
target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER)
target_link_libraries (oaisim
- -Wl,--start-group
+ -Wl,-ldl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SIMU_ETH SECU_OSA ${ITTI_LIB} ${MIH_LIB}
-Wl,--end-group )
@@ -1928,11 +1933,12 @@ add_executable(oaisim_nos1
${OPENAIR_TARGETS}/SIMU/USER/oaisim_functions.c
${OPENAIR_TARGETS}/SIMU/USER/event_handler.c
${OPENAIR_TARGETS}/SIMU/USER/oaisim.c
+ ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${HW_SOURCE}
- ${TRANSPORT_SOURCE}
+ ${TRANSPORT_SOURCE}
${XFORMS_SOURCE}
${T_SOURCE}
)
@@ -1956,7 +1962,20 @@ target_link_libraries (oaisim_nos1 ${T_LIB})
# Unitary tests for each piece of L1: example, mbmssim is MBMS L1 simulator
#####################################
+#special case for dlim TM4, which uses its own version of phy_scope code
+add_executable(dlsim_tm4
+ ${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
+ 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
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
@@ -1981,7 +2000,7 @@ add_executable(test_epc_generate_scenario
${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}
+ -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}
)
add_executable(test_epc_play_scenario
@@ -2002,7 +2021,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 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}
)
@@ -2022,7 +2041,7 @@ foreach(myExe s1ap
${OPENAIR3_DIR}/TEST/test_${myExe}.c
)
target_link_libraries (test_${myExe}
- -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
+ -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
)
endforeach(myExe)
@@ -2038,6 +2057,7 @@ if (${T_TRACER})
add_dependencies(oaisim generate_T)
add_dependencies(oaisim_nos1 generate_T)
add_dependencies(dlsim generate_T)
+ add_dependencies(dlsim_tm4 generate_T)
add_dependencies(dlsim_tm7 generate_T)
add_dependencies(ulsim generate_T)
add_dependencies(pbchsim generate_T)
@@ -2185,16 +2205,16 @@ make_driver(ue_ip ${OPENAIR2_DIR}/NETWORK_DRIVER/UE_IP ${ue_ip_src})
# OCTAVE tools
###############
set(OCT_INCL -I${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS -I${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB -I${OPENAIR_TARGETS}/ARCH/COMMON)
-set(OCT_LIBS -L${CMAKE_CURRENT_BINARY_DIR} -lm -lOPENAIR0_LIB)
+set(OCT_LIBS -L${CMAKE_CURRENT_BINARY_DIR} -lm -lOPENAIR0_LIB)
set(OCT_FLAGS -DEXMIMO)
set(OCT_DIR ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/OCTAVE)
set(OCT_FILES
oarf_config_exmimo.oct
- oarf_config_exmimo.oct
- oarf_get_frame.oct
- oarf_stop.oct
- oarf_send_frame.oct
- oarf_get_num_detected_cards.oct
+ oarf_config_exmimo.oct
+ oarf_get_frame.oct
+ oarf_stop.oct
+ oarf_send_frame.oct
+ oarf_get_num_detected_cards.oct
oarf_stop_without_reset.oct
)
@@ -2204,7 +2224,7 @@ foreach(file IN ITEMS ${OCT_FILES})
OUTPUT ${file}
DEPENDS ${OCT_DIR}/${src} OPENAIR0_LIB
COMMAND mkoctfile
- ARGS ${OCT_FLAGS} ${OCT_INCL} ${OCT_LIBS}
+ ARGS ${OCT_FLAGS} ${OCT_INCL} ${OCT_LIBS}
ARGS -o ${file} ${OCT_DIR}/${src}
COMMENT "Generating ${file}"
VERBATIM
diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt
index ca9a305463..61d1565bac 100755
--- a/cmake_targets/at_commands/CMakeLists.txt
+++ b/cmake_targets/at_commands/CMakeLists.txt
@@ -88,31 +88,47 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototype
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DMALLOC_CHECK_=3")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -DMALLOC_CHECK_=3 -O2")
-#This is to detect nettle version changes between Ubuntu 14.04/16.04
-set ( nettle_cmd "nettle-hash" )
-set ( nettle_arg "-V" )
-execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev)
-
-string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov})
-
-message("NETTLE_VERSION = ${nv}")
-
-# we need to remove decimal as floating point arithematic does not work properly with C preprocessor
-STRING(REGEX REPLACE "[.]" "" nv ${nv})
-
-if ("${nv}" STREQUAL "")
- message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" )
-endif()
-
-set (NETTLE_VERSION "${nv}")
-add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}")
+##This is to detect nettle version changes between Ubuntu 14.04/16.04
+#set ( nettle_cmd "nettle-hash" )
+#set ( nettle_arg "-V" )
+#execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev)
+#
+#string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov})
+#
+#message("NETTLE_VERSION = ${nv}")
+#
+## we need to remove decimal as floating point arithematic does not work properly with C preprocessor
+#STRING(REGEX REPLACE "[.]" "" nv ${nv})
+#
+#if ("${nv}" STREQUAL "")
+# message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" )
+#endif()
+#
+#set (NETTLE_VERSION "${nv}")
+#add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}")
include(FindPkgConfig)
-INCLUDE(FindNettle)
-IF( NOT NETTLE_FOUND )
- MESSAGE( SEND_ERROR "Nettle is required" )
-ENDIF( NOT NETTLE_FOUND )
+pkg_search_module(NETTLE nettle)
+if(NOT ${NETTLE_FOUND})
+ message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!")
+else()
+ include_directories(${NETTLE_INCLUDE_DIRS})
+endif()
+
+message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}")
+
+string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION})
+string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION})
+message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}")
+message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}")
+
+if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "")
+ message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" )
+endif()
+
+add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}")
+add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}")
pkg_search_module(OPENSSL openssl REQUIRED)
@@ -215,8 +231,8 @@ set(api_user_HDR
add_library(api_user ${api_user_SRC} ${api_user_HDR})
target_include_directories(api_user PRIVATE ${OPENAIR_NAS_DIR}/UE/API/USER
- ${OPENAIR_NAS_DIR}/UE
${OPENAIR_NAS_DIR}/COMMON
+ ${OPENAIR_NAS_DIR}/UE
)
################################################################################
@@ -397,6 +413,7 @@ target_include_directories(emm PRIVATE
${OPENAIR_DIR}/common/utils/msc
${OPENAIR_DIR}/common/utils
${OPENAIR_DIR}/openair2/COMMON
+ ${OPENAIR_NAS_DIR}/UE
${OPENAIR_NAS_DIR}/UE/API/USIM
${OPENAIR_NAS_DIR}/UE/EMM
${OPENAIR_NAS_DIR}/COMMON/EMM/MSG
@@ -409,7 +426,6 @@ target_include_directories(emm PRIVATE
# esm LIB
################################################################################
set(esm_SRC
- ${OPENAIR_NAS_DIR}/UE/ESM/esm_main.c
${OPENAIR_NAS_DIR}/UE/ESM/DedicatedEpsBearerContextActivation.c
${OPENAIR_NAS_DIR}/UE/ESM/DefaultEpsBearerContextActivation.c
${OPENAIR_NAS_DIR}/UE/ESM/EpsBearerContextDeactivation.c
@@ -452,6 +468,7 @@ set(esm_SRC
)
set(esm_HDR
+ ${OPENAIR_TARGETS}/COMMON/openairinterface5g_limits.h
${OPENAIR_NAS_DIR}/UE/ESM/esm_main.h
${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.h
${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.h
@@ -481,13 +498,17 @@ set(esm_HDR
${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_recv.h
${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_sap.h
${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_send.h
+ ${OPENAIR_DIR}/common/utils/utils.h
)
add_library(esm ${esm_SRC} ${esm_HDR})
target_include_directories(esm PRIVATE
+ ${OPENAIR_DIR}/common/utils
+ ${OPENAIR_NAS_DIR}/UE
${OPENAIR_NAS_DIR}/UE/API/USER
${OPENAIR_NAS_DIR}/UE/ESM
+ ${OPENAIR_TARGETS}/COMMON
${OPENAIR_NAS_DIR}/COMMON/ESM/MSG
${OPENAIR_NAS_DIR}/UE/ESM/SAP
${OPENAIR_NAS_DIR}/COMMON/IES
@@ -670,6 +691,9 @@ target_include_directories(ies PRIVATE
# EXECUTABLE at_nas_ue
################################################################################
include_directories(
+ ${OPENAIR_TARGETS}/COMMON
+ ${OPENAIR_NAS_DIR}/UE
+ ${OPENAIR_DIR}/common/utils
${OPENAIR_DIR}/common/utils/msc
${OPENAIR3_DIR}/COMMON
${OPENAIR3_DIR}/SECU
@@ -691,6 +715,7 @@ ADD_EXECUTABLE(at_nas_ue ${OPENAIR_NAS_DIR}/UE/UEprocess.c
${OPENAIR_NAS_DIR}/UE/nas_parser.c
${OPENAIR_NAS_DIR}/UE/nas_proc.c
${OPENAIR_NAS_DIR}/UE/nas_user.c
+ ${OPENAIR_DIR}/common/utils/utils.c
)
target_link_libraries (at_nas_ue
diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt
index 5841ed6dc2..8156e31bee 100644
--- a/cmake_targets/autotests/README.txt
+++ b/cmake_targets/autotests/README.txt
@@ -101,6 +101,19 @@ Obj.# Case# Test# Description
01 51 04 pdcchsim (TBD)
01 51 05 pbchsim (TBD)
01 51 06 mbmssim (TBD)
+01 51 10 dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB),
+ (Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)),
+ (Test 6: 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)),
+ (Test 6b: 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (70%)),
+ (Test 7: 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (30%)),
+ (Test 7b: 5 MHz, R3-1.FDD (MCS 15), ETU70, 1.4 dB (30%)),
+ (Test 10: 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)),
+ (Test 10b: 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)),
+ (Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%))
+ (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
+ (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
+
+
01 55 lte-softmodem tests with USRP B210 RF as eNB and ALU EPC w/ Bandrich COTS UE for 1TX/1RX (TM1), 2TX/2RX (TM2)
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index e51b57e6ec..f37c265462 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -994,6 +994,43 @@
3
+
+ execution
+ dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB),
+ (Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)),
+ (Test 6, 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)),
+ (Test 6b, 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (70%)),
+ (Test 7, 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (30%)),
+ (Test 7b, 5 MHz, R3-1.FDD (MCS 15), ETU70, 1.4 dB (30%)),
+ (Test 10, 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)),
+ (Test 10b, 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)),
+ (Test 11, 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%))
+ (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
+ (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
+
+
+ $OPENAIR_DIR/cmake_targets/build_oai
+ --phy_simulators -c
+ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash
+
+ $OPENAIR_DIR/cmake_targets/lte-simulators/build/dlsim_tm4
+ -m5 -gF -s-1 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70
+ -m4 -gF -s0 -w1.0 -f.2 -n500 -B6 -c4 -z2 -O70
+ -m15 -gF -s6.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70
+ -m14 -gF -s6.7 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O70
+ -m15 -gG -s6.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O30
+ -m14 -gG -s1.4 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O30
+ -m25 -gF -s17.4 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O70
+ -m25 -gF -s17.5 -w1.0 -f.2 -n500 -B25 -c3 -z2 -r1022 -O70
+ -m26 -gF -s17.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70
+ -m14 -gF -s6.8 -w1.0 -f.2 -n500 -B50 -c2 -x2 -y2 -z2 -O70
+ -m13 -gF -s5.9 -w1.0 -f.2 -n500 -B25 -c3 -x2 -y2 -z2 -O70
+ dlsim_tm4.test1 dlsim_tm4.test5 dlsim_tm4.test6 dlsim_tm4.test6b dlsim_tm4.test7 dlsim_tm4.test7b dlsim_tm4.test10 dlsim_tm4.test10b dlsim_tm4.test11 dlsim_tm4.TM2_test1 dlsim_tm4.TM2_test1b
+ "passed"
+ segmentation fault|assertion|exiting|fatal
+ 3
+
+
lte-softmodem
diff --git a/cmake_targets/autotests/v2/actions/execution_compile.bash b/cmake_targets/autotests/v2/actions/execution_compile.bash
index 6791e93b0d..530447ebcd 100644
--- a/cmake_targets/autotests/v2/actions/execution_compile.bash
+++ b/cmake_targets/autotests/v2/actions/execution_compile.bash
@@ -3,6 +3,9 @@ source oaienv
cd cmake_targets
rm -rf log
mkdir -p log
+echo $PRE_BUILD
bash -c "$PRE_BUILD"
+echo $BUILD_PROG $BUILD_ARGUMENTS
$BUILD_PROG $BUILD_ARGUMENTS
+echo $PRE_EXEC
bash -c "$PRE_EXEC"
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index db0899d1fe..de1addcee3 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -57,17 +57,20 @@ CMAKE_BUILD_TYPE=""
UE_AUTOTEST_TRACE="False"
trap handle_ctrl_c INT
+gen_nvram_path=$OPENAIR_DIR/targets/bin
+conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
+
function print_help() {
- echo_info '
+ echo_info "
This program installs OpenAirInterface Software
You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14
Options
-h
This help
-c | --clean
- Erase all files to make a rebuild from start"
+ Erase all files to make a rebuild from start
-C | --clean-all
- Erase all files made by previous compilations, installations"
+ Erase all files made by previous compilations, installations
--clean-kernel
Erase previously installed features in kernel: iptables, drivers, ...
-I | --install-external-packages
@@ -82,7 +85,11 @@ Options
--eNB
Makes the LTE softmodem
--UE
- Makes the UE specific parts (ue_ip, usim, nvram)
+ Makes the UE specific parts (ue_ip, usim, nvram) from the given configuration file
+--UE-conf-nvram [configuration file]
+ Specify conf_nvram_path (default \"$conf_nvram_path\")
+--UE-gen-nvram [output path]
+ Specify gen_nvram_path (default \"$gen_nvram_path\")
--RRH
Makes the RRH
-a | --agent
@@ -97,7 +104,7 @@ Options
ETHERNET , None
Adds this trasport protocol support in compilation
--oaisim
- Makes the oaisim simulator. Hardware will be defaulted to "None".
+ Makes the oaisim simulator. Hardware will be defaulted to \"None\".
--phy_simulators
Makes the unitary tests Layer 1 simulators
--core_simulators
@@ -140,11 +147,12 @@ Usage (first build):
Usage (Regular):
oaisim : ./build_oai --oaisim -x
Eurecom EXMIMO + OAI ENB : ./build_oai --eNB -x
- NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP'
+ NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP"
}
function main() {
+
until [ -z "$1" ]
do
case "$1" in
@@ -183,6 +191,12 @@ function main() {
UE=1
echo_info "Will compile UE"
shift;;
+ --UE-conf-nvram)
+ conf_nvram_path=$(readlink -f "$1")
+ shift 2;;
+ --UE-gen-nvram)
+ gen_nvram_path=$(readlink -f $2)
+ shift 2;;
--RRH)
RRH=1
echo_info "Will compile RRH"
@@ -292,6 +306,10 @@ function main() {
UE_AUTOTEST_TRACE="True"
echo_info "Enabling autotest specific trace for UE"
shift 1;;
+ --uhd-images-dir)
+ UHD_IMAGES_DIR=$2
+ echo_info "Downloading UHD images in the indicated location"
+ shift 2;;
-h | --help)
print_help
exit 1;;
@@ -362,6 +380,10 @@ function main() {
echo_info "Flags for Deadline scheduler: $DEADLINE_SCHEDULER_FLAG_USER"
echo_info "Flags for CPU Affinity: $CPU_AFFINITY_FLAG_USER"
+ if [ -n "$UHD_IMAGES_DIR" ] && [ -z "$INSTALL_EXTERNAL" ]; then
+ echo_error "UHD images download settings will not be applied without -I present"
+ exit
+ fi
############################################
# setting and printing OAI envs, we should check here
############################################
@@ -399,7 +421,7 @@ function main() {
echo_info "installing packages for USRP support"
check_install_usrp_uhd_driver
if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then
- install_usrp_uhd_driver
+ install_usrp_uhd_driver $UHD_IMAGES_DIR
fi
fi
if [ "$HW" == "OAI_BLADERF" ] ; then
@@ -418,9 +440,9 @@ function main() {
if [ "$oaisim" = "1" ] ; then
#to be discussed
- # there is no RF device and no transport protocol
+ # there is no RF device transport protocol
HW="None"
- TP="None"
+ TP="ETHERNET"
if [ "$XFORMS" == "True" ] ; then
PRINT_STATS="True"
@@ -517,15 +539,17 @@ function main() {
compilations \
nas_sim_tools nvram \
nvram $dbin/nvram
+ compilations \
+ nas_sim_tools conf2uedata \
+ conf2uedata $dbin/conf2uedata
# generate USIM data
- if [ -f $dbin/nvram ]; then
- install_nas_tools $dbin $dconf
+ if [ -f $dbin/conf2uedata ]; then
+ install_nas_tools $conf_nvram_path $gen_nvram_path
echo_info "Copying UE specific part to $DIR/$lte_build_dir/build"
- cp -Rvf $dbin/.ue_emm.nvram $DIR/$lte_build_dir/build
- cp -Rvf $dbin/.ue.nvram $DIR/$lte_build_dir/build
- cp -Rvf $dbin/.usim.nvram $DIR/$lte_build_dir/build
-
+ cp -Rvf $dbin/.ue_emm.nvram0 $DIR/$lte_build_dir/build
+ cp -Rvf $dbin/.ue.nvram0 $DIR/$lte_build_dir/build
+ cp -Rvf $dbin/.usim.nvram0 $DIR/$lte_build_dir/build
else
echo_warning "not generated UE NAS files: binaries not found"
fi
@@ -543,7 +567,7 @@ function main() {
if [ "$SIMUS_PHY" = "1" ] ; then
# lte unitary simulators compilation
echo_info "Compiling unitary tests simulators"
- simlist="dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
+ simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
for f in $simlist ; do
compilations \
lte-simulators $f \
@@ -647,10 +671,13 @@ function main() {
compilations \
nas_sim_tools nvram \
nvram $dbin/nvram
+ compilations \
+ nas_sim_tools conf2uedata \
+ conf2uedata $dbin/conf2uedata
# generate USIM data
- if [ -f $dbin/nvram ]; then
- install_nas_tools $dbin $dconf
+ if [ -f $dbin/conf2uedata ]; then
+ install_nas_tools $conf_nvram_path $gen_nvram_path
else
echo_warning "not generated UE NAS files: binaries not found"
fi
@@ -671,6 +698,15 @@ function main() {
# CMakeFiles/oai_nw_drv/oai_nw_drv.ko $dbin/oai_nw_drv.ko
fi
+ if [ "$TP" == "ETHERNET" ] ; then
+ compilations \
+ $oaisim_build_dir oai_eth_transpro \
+ liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
+ ln -sf liboai_eth_transpro.so liboai_transpro.so
+ ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
+ echo_info "liboai_transpro.so is linked with ETHERNET library"
+ fi
+
cmake_file=$DIR/oaisim_mme_build_oai/CMakeLists.txt
cp $DIR/oaisim_mme_build_oai/CMakeLists.template $cmake_file
echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
@@ -754,8 +790,8 @@ function main() {
liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
fi
- ln -s liboai_usrpdevif.so liboai_device.so
- ln -s $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so
+ ln -sf liboai_usrpdevif.so liboai_device.so
+ ln -sf $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to USRP device library"
elif [ "$HW" == "OAI_BLADERF" ] ; then
if [ -f "/usr/include/libbladeRF.h" ] ; then
@@ -764,8 +800,8 @@ function main() {
liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL
fi
- ln -s liboai_bladerfdevif.so liboai_device.so
- ln -s $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
+ ln -sf liboai_bladerfdevif.so liboai_device.so
+ ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to BLADERF device library"
elif [ "$HW" == "OAI_LMSSDR" ] ; then
# if [ -f "/usr/include/libbladeRF.h" ] ; then
@@ -774,8 +810,8 @@ function main() {
liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL
# fi
- ln -s liboai_lmssdrdevif.so liboai_device.so
- ln -s $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
+ ln -sf liboai_lmssdrdevif.so liboai_device.so
+ ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to LMSSDR device library"
else
echo_info "liboai_device.so is not linked to any device library"
@@ -791,8 +827,8 @@ function main() {
compilations \
$build_dir oai_eth_transpro \
liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
- ln -s liboai_eth_transpro.so liboai_transpro.so
- ln -s $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
+ ln -sf liboai_eth_transpro.so liboai_transpro.so
+ ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
echo_info "liboai_transpro.so is linked with ETHERNET library"
fi
fi
diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt
index 0b706c8748..5ed4d93d80 100644
--- a/cmake_targets/lte-simulators/CMakeLists.txt
+++ b/cmake_targets/lte-simulators/CMakeLists.txt
@@ -8,7 +8,7 @@ set(DEBUG_PHY False)
set(MU_RECIEVER False)
set(RANDOM_BF False)
set(PBS_SIM False)
-set(PERFECT_CE False)
+set(PERFECT_CE True)
set(NAS_UE False)
set(MESSAGE_CHART_GENERATOR False)
diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt
index 732ede3f94..81e3fe4b3c 100644
--- a/cmake_targets/nas_sim_tools/CMakeLists.txt
+++ b/cmake_targets/nas_sim_tools/CMakeLists.txt
@@ -2,70 +2,89 @@ cmake_minimum_required(VERSION 2.8)
project(NAS_SIM_TOOLS)
+include(FindPkgConfig)
+pkg_search_module(CONFIG libconfig REQUIRED)
+include_directories(${CONFIG_INCLUDE_DIRS})
+add_definitions(-std=gnu99)
ENABLE_LANGUAGE(C)
-#Sends the -std=c99 flag to the gcc compiler
-add_definitions(-std=c99)
-add_definitions(-DNAS_UE)
+
+set(CMAKE_C_FLAGS
+ "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat -g")
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
-set(OPENAIR1_DIR $ENV{OPENAIR_DIR}/openair1)
-set(OPENAIR2_DIR $ENV{OPENAIR_DIR}/openair2)
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
-set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
-set(OPENAIR_TARGETS $ENV{OPENAIR_DIR}/targets)
-#set(EXECUTABLE_OUTPUT_PATH ${OPENAIR_DIR}/targets/bin)
-
-
-# Add .h files for dependancies
-set(usim_SRC
- ${OPENAIR_DIR}/openair3/NAS/TOOLS/usim_data.c
+set(CONF2UEDATA_LIB_SRC
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_network.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_plmn.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_parser.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.c
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.c
+ ${OPENAIR_DIR}/common/utils/utils.c
)
-set(usim_HDR
- ${OPENAIR_DIR}/openair3/NAS/TOOLS/network.h
+
+set(conf2uedata_HDR
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.h
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.h
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.h
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.h
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.h
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.h
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.h
+ ${OPENAIR_DIR}/common/utils/utils.h
)
+
include_directories(
+ ${OPENAIR_DIR}/common/utils
+ ${OPENAIR_DIR}/openair3/NAS/UE
${OPENAIR_DIR}/openair3/NAS/COMMON
+ ${OPENAIR_DIR}/openair3/NAS/UE/API/USER
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM
${OPENAIR_DIR}/openair3/NAS/UE/EMM/
${OPENAIR_DIR}/openair3/NAS/UE/ESM/
${OPENAIR_DIR}/openair3/NAS/COMMON/IES/
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL
)
-ADD_EXECUTABLE(usim ${usim_SRC} ${usim_HDR})
+
+# conf2uedata binary
+
+set(conf2uedata_SRC
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c
+ ${CONF2UEDATA_LIB_SRC}
+)
+
+add_executable(conf2uedata ${conf2uedata_SRC} ${conf2uedata_HDR} )
+target_link_libraries(conf2uedata ${CONFIG_LIBRARIES})
+
+# usim binary
+
+set(usim_SRC
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/usim.c
+ ${CONF2UEDATA_LIB_SRC}
+)
+add_executable(usim ${usim_SRC} ${conf2uedata_HDR} )
+target_link_libraries(usim ${CONFIG_LIBRARIES})
+# nvram binary
set(nvram_SRC
- ${OPENAIR_DIR}/openair3/NAS/TOOLS/ue_data.c
- ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c
- ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c
+ ${OPENAIR_DIR}/openair3/NAS/TOOLS/nvram.c
+ ${CONF2UEDATA_LIB_SRC}
)
-set(nvram_HDR
- ${OPENAIR_DIR}/openair3/NAS/UE/EMM/emmData.h
- ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h
- ${OPENAIR_DIR}/openair3/NAS/COMMON/userDef.h
-)
-ADD_EXECUTABLE(nvram ${nvram_SRC} ${nvram_HDR})
-
-#install (TARGETS usim DESTINATION ${EXECUTABLE_OUTPUT_PATH})
-#install (TARGETS nvram DESTINATION ${EXECUTABLE_OUTPUT_PATH})
-
-#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/nvram --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)")
-#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/usim --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)")
+add_executable(nvram ${nvram_SRC} ${conf2uedata_HDR} )
+target_link_libraries(nvram ${CONFIG_LIBRARIES})
diff --git a/cmake_targets/snap_environment.sh b/cmake_targets/snap_environment.sh
new file mode 100755
index 0000000000..1c0725d8b5
--- /dev/null
+++ b/cmake_targets/snap_environment.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+export UHD_IMAGES_DIR=$SNAP/uhd_images
+exec $@
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 448d54f334..ede8ef4196 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -136,6 +136,20 @@ clean_all_files() {
# Compilers
###################################
+#check_warnings:
+# print error message if the compilation had warnings
+#argument:
+# $1: log file
+check_warnings() {
+ #we look for 'warning:' in the compilation log file
+ #this is how gcc starts a warning
+ #this is not perfect, we may get false positive
+ warning_count=`grep "warning:" "$1"|wc -l`
+ if [ $warning_count -gt 0 ]; then
+ echo_error "WARNING: $warning_count warnings. See $1"
+ fi
+}
+
compilations() {
cd $OPENAIR_DIR/cmake_targets/$1/build
set +e
@@ -153,6 +167,7 @@ compilations() {
if [ -s $3 ] ; then
cp $3 $4
echo_success "$2 compiled"
+ check_warnings "$dlog/$2.$REL.txt"
else
echo_error "$2 compilation failed"
exit 1
@@ -171,7 +186,7 @@ install_protobuf_from_source(){
echo "Downloading protobuf"
rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
- tar -xzvf protobuf-2.6.1.tar.gz
+ tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
cd protobuf-2.6.1/
./configure
echo "Compiling protobuf"
@@ -208,15 +223,19 @@ check_install_usrp_uhd_driver(){
#The new USRP repository
$SUDO add-apt-repository ppa:ettusresearch/uhd -y
$SUDO apt-get update
- $SUDO apt-get -y install python python-tk libboost-all-dev libusb-1.0-0-dev
- $SUDO apt-get -y install libuhd-dev libuhd003 uhd-host
+ $SUDO apt-get -y --allow-unauthenticated install python python-tk libboost-all-dev libusb-1.0-0-dev
+ $SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host
}
install_usrp_uhd_driver() {
# We move uhd-host apart because it depends on linux kernel version
# On newer kernels, it fails to install
$SUDO apt-get -y install uhd-host
- $SUDO uhd_images_downloader
+ if [ -z $1 ]; then
+ $SUDO uhd_images_downloader
+ else
+ $SUDO uhd_images_downloader -i $1
+ fi
}
check_install_bladerf_driver(){
@@ -224,9 +243,9 @@ check_install_bladerf_driver(){
$SUDO add-apt-repository -y ppa:bladerf/bladerf
$SUDO apt-get update
fi
- $SUDO apt-get install -y bladerf libbladerf-dev
- $SUDO apt-get install -y bladerf-firmware-fx3
- $SUDO apt-get install -y bladerf-fpga-hostedx40
+ $SUDO apt-get install -y--allow-unauthenticated bladerf libbladerf-dev
+ $SUDO apt-get install -y --allow-unauthenticated bladerf-firmware-fx3
+ $SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40
}
flash_firmware_bladerf() {
@@ -450,19 +469,18 @@ install_asn1c_from_source(){
################################################
install_nas_tools() {
- cd $1
- if [ ! -f .ue.nvram ]; then
+ if [ ! -f .ue.nvram0 ]; then
echo_success "generate .ue_emm.nvram .ue.nvram"
- ./nvram --gen
+ ./nvram --gen -c $1 -o $2
else
- [ ./nvram -nt .ue.nvram -o ./nvram -nt .ue_emm.nvram ] && ./nvram --gen
+ [ ./nvram -nt .ue.nvram0 -o ./nvram -nt .ue_emm.nvram0 ] && ./nvram --gen -c $1 -o $2
fi
- if [ ! -f .usim.nvram ]; then
+ if [ ! -f .usim.nvram0 ]; then
echo_success "generate .usim.nvram"
- ./usim --gen
+ ./usim --gen -c $1 -o $2
else
- [ ./usim -nt .usim.nvram ] && ./usim --gen
+ [ ./usim -nt .usim.nvram0 ] && ./usim --gen -c $1 -o $2
fi
}
diff --git a/cmake_targets/tools/run_enb_ue_virt_s1 b/cmake_targets/tools/run_enb_ue_virt_s1
index ecd5993ff4..ff65946803 100755
--- a/cmake_targets/tools/run_enb_ue_virt_s1
+++ b/cmake_targets/tools/run_enb_ue_virt_s1
@@ -247,12 +247,6 @@ function main()
if [ $? -ne 0 ]; then
echo "200 lte " >> /etc/iproute2/rt_tables
fi
- ip rule add fwmark 1 table lte
- ifconfig oip1 up
- ip route add default dev oip1 table lte
- # the actual IP address depends on the EPC/MME config file for address pool
- ip route add from 192.188.0.0/24 table lte
- ip route add to 192.188.0.0/24 table lte
exe_arguments="$exe_arguments -s15 -AAWGN -y1 -b1 -u1 -Q0"
diff --git a/common/utils/Makefile.inc b/common/utils/Makefile.inc
deleted file mode 100644
index 33c126b8d7..0000000000
--- a/common/utils/Makefile.inc
+++ /dev/null
@@ -1,59 +0,0 @@
-export KERNEL_DIR=/lib/modules/$(shell uname -r)/
-CC=gcc
-CCC=gcc
-linux := $(shell if [ `uname` = "Linux" ] ; then echo "1" ; else echo "0" ; fi)
-
-
-CFLAGS += -std=gnu99
-CFLAGS += -Wall -g -ggdb -Wstrict-prototypes -fno-strict-aliasing
-
-# Need to force this option because default kernel module builder is wrong
-CFLAGS += $(call cc-option,-mpreferred-stack-boundary=4)
-
-#For performance, if some option doesn't exist in all gcc versions, use $(call cc-option,MY_OPTION)
-#CFLAGS += -O2
-#CFLAGS += -funroll-loops
-CFLAGS += -Wno-packed-bitfield-compat
-
-# This is the minimum CPU faetures for OAI
-CFLAGS += -mmmx -msse -msse2 -mssse3 -msse4.1
-# Add CPU features from local CPU
-#CFLAGS += -march=native
-
-ifeq ($(OSTYPE),Cygwin)
-cygwin=1
-CFLAGS += -DCYGWIN
-else
-cygwin=0
-endif
-
-ifeq ($(linux),1)
-CFLAGS +=
-LDFLAGS +=
-endif
-
-ITTI_DIR = $(COMMON_UTILS_DIR)/itti
-
-ITTI_OBJS = $(ITTI_DIR)/intertask_interface.o
-ITTI_OBJS += $(ITTI_DIR)/intertask_interface_dump.o
-ITTI_OBJS += $(ITTI_DIR)/backtrace.o
-ITTI_OBJS += $(ITTI_DIR)/memory_pools.o
-ITTI_OBJS += $(ITTI_DIR)/signals.o
-ITTI_OBJS += $(ITTI_DIR)/timer.o
-
-
-HASHTABLE_DIR = $(COMMON_UTILS_DIR)/collection/hashtable
-MSC_DIR = $(COMMON_UTILS_DIR)/msc
-
-HASHTABLE_OBJS = $(HASHTABLE_DIR)/hashtable.o
-HASHTABLE_OBJS += $(HASHTABLE_DIR)/obj_hashtable.o
-
-UTILS_OBJS = $(ITTI_OBJS) $(HASHTABLE_OBJS)
-
-UTILS_incl = \
- -I$(COMMON_UTILS_DIR) \
- -I$(HASHTABLE_DIR) \
- -I$(ITTI_DIR) \
- -I$(MSC_DIR)
-
-print-% : ; @echo $* = $($*)
diff --git a/common/utils/T/T.h b/common/utils/T/T.h
index 819615131e..37668a8309 100644
--- a/common/utils/T/T.h
+++ b/common/utils/T/T.h
@@ -184,8 +184,30 @@ extern T_cache_t *T_cache;
} while (0)
#endif
+/* we have 4 versions of T_HEADER:
+ * - bad quality C++ version with time
+ * - good quality C version with time
+ * - bad quality C++ version without time
+ * - good quality C version without time
+ */
+
#ifdef T_SEND_TIME
+#ifdef __cplusplus
+
+/* C++ version of T_HEADER with time */
+#define T_HEADER(x) \
+ do { \
+ struct timespec T_HEADER_time; \
+ if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \
+ memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \
+ T_LOCAL_size += sizeof(struct timespec); \
+ T_PUT_int(1, (int)(uintptr_t)(x)); \
+ } while (0)
+
+#else /* #ifdef __cplusplus */
+
+/* C version of T_HEADER with time */
#define T_HEADER(x) \
do { \
if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \
@@ -201,8 +223,21 @@ extern T_cache_t *T_cache;
T_PUT_int(1, (int)(uintptr_t)(x)); \
} while (0)
+#endif /* #ifdef __cplusplus */
+
#else /* #ifdef T_SEND_TIME */
+#ifdef __cplusplus
+
+/* C++ version of T_HEADER without time */
+#define T_HEADER(x) \
+ do { \
+ T_PUT_int(1, (int)(uintptr_t)(x)); \
+ } while (0)
+
+#else /* #ifdef __cplusplus */
+
+/* C version of T_HEADER without time */
#define T_HEADER(x) \
do { \
if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \
@@ -214,6 +249,8 @@ extern T_cache_t *T_cache;
T_PUT_int(1, (int)(uintptr_t)(x)); \
} while (0)
+#endif /* #ifdef __cplusplus */
+
#endif /* #ifdef T_SEND_TIME */
#define T1(t) \
diff --git a/common/utils/itti/assertions.h b/common/utils/itti/assertions.h
index df8251d105..a411bd5397 100644
--- a/common/utils/itti/assertions.h
+++ b/common/utils/itti/assertions.h
@@ -65,7 +65,7 @@ _Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3)
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
-_Assert_(cOND, _Assert_Exit_, #vALUE1": %"PRIdMAX"\n"#vALUE2": %"PRIdMAX"\n"#vALUE3": %"PRIdMAX"\n"#vALUE4": %"PRIdMAX"\n\n", \
+_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4)
#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3)
diff --git a/common/utils/time_utils.h b/common/utils/time_utils.h
new file mode 100644
index 0000000000..ee82c8cf95
--- /dev/null
+++ b/common/utils/time_utils.h
@@ -0,0 +1,23 @@
+#ifndef _TIME_UTILS_H_
+#define _TIME_UTILS_H_
+
+#include
+#include
+
+static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end)
+{
+ struct timespec temp;
+ int64_t temp_ns;
+
+ if ((end.tv_nsec-start.tv_nsec)<0) {
+ temp.tv_sec = end.tv_sec-start.tv_sec-1;
+ temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
+ } else {
+ temp.tv_sec = end.tv_sec-start.tv_sec;
+ temp.tv_nsec = end.tv_nsec-start.tv_nsec;
+ }
+ temp_ns = (int64_t)(temp.tv_sec) * (int64_t)1000000000 + (temp.tv_nsec);
+ return temp_ns;
+}
+
+#endif /* _TIME_UTILS_H_ */
diff --git a/common/utils/utils.c b/common/utils/utils.c
new file mode 100644
index 0000000000..a807a27096
--- /dev/null
+++ b/common/utils/utils.c
@@ -0,0 +1,107 @@
+#include
+#include
+#include
+#include
+#include "utils.h"
+
+void *calloc_or_fail(size_t size) {
+ void *ptr = calloc(1, size);
+ if (ptr == NULL) {
+ fprintf(stderr, "[UE] Failed to calloc %zu bytes", size);
+ exit(EXIT_FAILURE);
+ }
+ return ptr;
+}
+
+void *malloc_or_fail(size_t size) {
+ void *ptr = malloc(size);
+ if (ptr == NULL) {
+ fprintf(stderr, "[UE] Failed to malloc %zu bytes", size);
+ exit(EXIT_FAILURE);
+ }
+ return ptr;
+}
+
+/****************************************************************************
+ ** **
+ ** Name: hex_char_to_hex_value() **
+ ** **
+ ** Description: Converts an hexadecimal ASCII coded digit into its value. **
+ ** **
+ ** Inputs: c: A char holding the ASCII coded value **
+ ** Others: None **
+ ** **
+ ** Outputs: None **
+ ** Return: Converted value (-1 on error) **
+ ** Others: None **
+ ** **
+ ***************************************************************************/
+int hex_char_to_hex_value (char c)
+{
+ if (!((c >= 'a' && c <= 'f') ||
+ (c >= 'A' && c <= 'F') ||
+ (c >= '0' && c <= '9')))
+ return -1;
+
+ if (c >= 'A') {
+ /* Remove case bit */
+ c &= ~('a' ^ 'A');
+
+ return (c - 'A' + 10);
+ } else {
+ return (c - '0');
+ }
+}
+
+/****************************************************************************
+ ** **
+ ** Name: hex_string_to_hex_value() **
+ ** **
+ ** Description: Converts an hexadecimal ASCII coded string into its value.**
+ ** **
+ ** Inputs: hex_value: A pointer to the location to store the **
+ ** conversion result **
+ ** size: The size of hex_value in bytes **
+ ** Others: None **
+ ** **
+ ** Outputs: hex_value: Converted value **
+ ** Return: 0 on success, -1 on error **
+ ** Others: None **
+ ** **
+ ***************************************************************************/
+int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size)
+{
+ int i;
+
+ if (strlen(hex_string) != size*2) {
+ fprintf(stderr, "the string '%s' should be of length %d\n", hex_string, size*2);
+ return -1;
+ }
+
+ for (i=0; i < size; i++) {
+ int a = hex_char_to_hex_value(hex_string[2 * i]);
+ int b = hex_char_to_hex_value(hex_string[2 * i + 1]);
+ if (a == -1 || b == -1) goto error;
+ hex_value[i] = (a << 4) | b;
+ }
+ return 0;
+
+error:
+ fprintf(stderr, "the string '%s' is not a valid hexadecimal string\n", hex_string);
+ for (i=0; i < size; i++)
+ hex_value[i] = 0;
+ return -1;
+}
+
+char *itoa(int i) {
+ char buffer[64];
+ int ret;
+
+ ret = snprintf(buffer, sizeof(buffer), "%d",i);
+ if ( ret <= 0 ) {
+ return NULL;
+ }
+
+ return strdup(buffer);
+}
+
diff --git a/common/utils/utils.h b/common/utils/utils.h
new file mode 100644
index 0000000000..cfe3df34b9
--- /dev/null
+++ b/common/utils/utils.h
@@ -0,0 +1,17 @@
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include
+#include
+
+void *calloc_or_fail(size_t size);
+void *malloc_or_fail(size_t size);
+
+// Converts an hexadecimal ASCII coded digit into its value. **
+int hex_char_to_hex_value (char c);
+// Converts an hexadecimal ASCII coded string into its value.**
+int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size);
+
+char *itoa(int i);
+
+#endif
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
old mode 100644
new mode 100755
index f6f8d8f858..d0556a0235
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -665,34 +665,34 @@ void phy_config_dedicated_eNB(uint8_t Mod_id,
if (physicalConfigDedicated->antennaInfo) {
switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) {
case AntennaInfoDedicated__transmissionMode_tm1:
- eNB->transmission_mode[UE_id] = 1;
- break;
+ eNB->transmission_mode[UE_id] = 1;
+ break;
case AntennaInfoDedicated__transmissionMode_tm2:
- eNB->transmission_mode[UE_id] = 2;
- break;
+ eNB->transmission_mode[UE_id] = 2;
+ break;
case AntennaInfoDedicated__transmissionMode_tm3:
- eNB->transmission_mode[UE_id] = 3;
- break;
+ eNB->transmission_mode[UE_id] = 3;
+ break;
case AntennaInfoDedicated__transmissionMode_tm4:
- eNB->transmission_mode[UE_id] = 4;
- break;
+ eNB->transmission_mode[UE_id] = 4;
+ break;
case AntennaInfoDedicated__transmissionMode_tm5:
- eNB->transmission_mode[UE_id] = 5;
- break;
+ eNB->transmission_mode[UE_id] = 5;
+ break;
case AntennaInfoDedicated__transmissionMode_tm6:
- eNB->transmission_mode[UE_id] = 6;
- break;
+ eNB->transmission_mode[UE_id] = 6;
+ break;
case AntennaInfoDedicated__transmissionMode_tm7:
lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti);
- eNB->do_precoding = 1;
- eNB->transmission_mode[UE_id] = 7;
- break;
+ eNB->do_precoding = 1;
+ eNB->transmission_mode[UE_id] = 7;
+ break;
default:
- LOG_E(PHY,"Unknown transmission mode!\n");
- break;
+ LOG_E(PHY,"Unknown transmission mode!\n");
+ break;
}
LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]);
-
+
} else {
LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id);
}
@@ -838,31 +838,31 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
LOG_D(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;
+ phy_vars_ue->transmission_mode[eNB_id] = 1;
+ break;
case AntennaInfoDedicated__transmissionMode_tm2:
- phy_vars_ue->transmission_mode[eNB_id] = 2;
- break;
+ phy_vars_ue->transmission_mode[eNB_id] = 2;
+ break;
case AntennaInfoDedicated__transmissionMode_tm3:
- phy_vars_ue->transmission_mode[eNB_id] = 3;
- break;
+ phy_vars_ue->transmission_mode[eNB_id] = 3;
+ break;
case AntennaInfoDedicated__transmissionMode_tm4:
- phy_vars_ue->transmission_mode[eNB_id] = 4;
- break;
+ phy_vars_ue->transmission_mode[eNB_id] = 4;
+ break;
case AntennaInfoDedicated__transmissionMode_tm5:
- phy_vars_ue->transmission_mode[eNB_id] = 5;
- break;
+ phy_vars_ue->transmission_mode[eNB_id] = 5;
+ break;
case AntennaInfoDedicated__transmissionMode_tm6:
- phy_vars_ue->transmission_mode[eNB_id] = 6;
- break;
+ 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[eNB_id]->crnti);
- phy_vars_ue->transmission_mode[eNB_id] = 7;
- break;
+ phy_vars_ue->transmission_mode[eNB_id] = 7;
+ break;
default:
- LOG_E(PHY,"Unknown transmission mode!\n");
- break;
- }
+ 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);
}
@@ -906,29 +906,29 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
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);
+ // 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;
- }
+ 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) {
@@ -1016,8 +1016,9 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
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*) );
- pdsch->llr128_2ndstream = (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*) );
@@ -1026,11 +1027,12 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
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_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" );
@@ -1046,15 +1048,14 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
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_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 phy_init_lte_ue(PHY_VARS_UE *ue,
int nb_connected_eNB,
uint8_t abstraction_flag)
@@ -1072,7 +1073,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
LTE_UE_PDCCH** const pdcch_vars = ue->pdcch_vars;
LTE_UE_PRACH** const prach_vars = ue->prach_vars;
- int i,j,k;
+ int i,j,k,l;
int eNB_id;
printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
@@ -1160,44 +1161,72 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
phy_init_lte_ue__PDSCH( pdsch_vars_th1[eNB_id], fp );
// thread 0
- pdsch_vars_th0[eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
- pdsch_vars_th0[eNB_id]->llr_shifts_p = pdsch_vars_th0[eNB_id]->llr_shifts;
- pdsch_vars_th0[eNB_id]->dl_ch_mag1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
- pdsch_vars_th0[eNB_id]->dl_ch_magb1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
- pdsch_vars_th0[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+ pdsch_vars_th0[eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
+ pdsch_vars_th0[eNB_id]->llr_shifts_p = pdsch_vars_th0[eNB_id]->llr_shifts;
+ pdsch_vars_th0[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+ pdsch_vars_th0[eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) );
+ pdsch_vars_th0[eNB_id]->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
- for (k=0; k<8; k++)
- pdsch_vars_th0[eNB_id]->rxdataF_comp1[k] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ // thread 0
+ pdsch_vars_th1[eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
+ pdsch_vars_th1[eNB_id]->llr_shifts_p = pdsch_vars_th0[eNB_id]->llr_shifts;
+ pdsch_vars_th1[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+ pdsch_vars_th1[eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) );
+ pdsch_vars_th1[eNB_id]->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
- // thread 1
- pdsch_vars_th1[eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
- pdsch_vars_th1[eNB_id]->llr_shifts_p = pdsch_vars_th1[eNB_id]->llr_shifts;
- pdsch_vars_th1[eNB_id]->dl_ch_mag1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
- pdsch_vars_th1[eNB_id]->dl_ch_magb1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
- pdsch_vars_th1[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
- for (k=0; k<8; k++)
- pdsch_vars_th1[eNB_id]->rxdataF_comp1[k] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+
+
+ for (int i=0; inb_antennas_rx; i++){
+ pdsch_vars_th0[eNB_id]->rho[i] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+ pdsch_vars_th1[eNB_id]->rho[i] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+ }
+
+ pdsch_vars_th0[eNB_id]->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ pdsch_vars_th1[eNB_id]->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
for (i=0; inb_antennas_rx; i++)
for (j=0; j<4; j++) {
- int idx = (j<<1)+i;
- pdsch_vars_th0[eNB_id]->dl_ch_mag1[idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
- pdsch_vars_th0[eNB_id]->dl_ch_magb1[idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-
- pdsch_vars_th1[eNB_id]->dl_ch_mag1[idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
- pdsch_vars_th1[eNB_id]->dl_ch_magb1[idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-
- for (k=0; k<8; k++)
- {
- pdsch_vars_th0[eNB_id]->rxdataF_comp1[idx][k] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*14) );
- pdsch_vars_th1[eNB_id]->rxdataF_comp1[idx][k] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*14) );
- }
+ const int idx = (j<<1)+i;
+ const size_t num = 7*2*fp->N_RB_DL*12+4;
+ pdsch_vars_th0[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+ pdsch_vars_th1[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
+ pdsch_vars_th0[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ pdsch_vars_th0[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ pdsch_vars_th0[eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ pdsch_vars_th0[eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+
+ pdsch_vars_th1[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ pdsch_vars_th1[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ pdsch_vars_th1[eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+ pdsch_vars_th1[eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+
+
+ for (int i=0; inb_antennas_rx; i++)
+ for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
+ const int idx = (j<<1)+i;
+ pdsch_vars_th0[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_th0[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+ pdsch_vars_th0[eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+ pdsch_vars_th0[eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+
+ pdsch_vars_th1[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_th1[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+ pdsch_vars_th1[eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+ pdsch_vars_th1[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_mch[eNB_id], fp );
+
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
pdcch_vars[eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
pdcch_vars[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
@@ -1267,7 +1296,11 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
ue->sinr_CQI_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
ue->init_averaging = 1;
- ue->pdsch_config_dedicated->p_a = dB0; // default value until overwritten by RRCConnectionReconfiguration
+ // 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;
@@ -1290,9 +1323,11 @@ 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;
- int i, j, eNB_id, UE_id;
+
+ int i, j, eNB_id, UE_id;
int re;
+
eNB->total_dlsch_bitrate = 0;
eNB->total_transmitted_bits = 0;
eNB->total_system_throughput = 0;
@@ -1307,17 +1342,17 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
lte_gold(fp,eNB->lte_gold_table,fp->Nid_cell);
generate_pcfich_reg_mapping(fp);
generate_phich_reg_mapping(fp);
-
+
for (UE_id=0; UE_idfirst_run_timing_advance[UE_id] =
- 1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
+ 1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
// clear whole structure
bzero( &eNB->UE_stats[UE_id], sizeof(LTE_eNB_UE_stats) );
-
+
eNB->physicalConfigDedicated[UE_id] = NULL;
}
-
+
eNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
}
@@ -1325,131 +1360,142 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
{
eNB_id=0;
if (abstraction_flag==0) {
-
+
// TX vars
if (eNB->node_function != NGFI_RCC_IF4p5)
- common_vars->txdata[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_tx*sizeof(int32_t*));
+
+ common_vars->txdata[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_tx*sizeof(int32_t*));
common_vars->txdataF[eNB_id] = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*));
common_vars->txdataF_BF[eNB_id] = (int32_t **)malloc16(fp->nb_antennas_tx*sizeof(int32_t*));
if (eNB->node_function != NGFI_RRU_IF5) {
- for (i=0; inb_antenna_ports_eNB || i==5) {
- common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
+ for (i=0; inb_antenna_ports_eNB || i==5) {
+ common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
#ifdef DEBUG_PHY
- printf("[openair][LTE_PHY][INIT] common_vars->txdataF[%d][%d] = %p (%lu bytes)\n",
- eNB_id,i,common_vars->txdataF[eNB_id][i],
- fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t));
+ printf("[openair][LTE_PHY][INIT] common_vars->txdataF[%d][%d] = %p (%lu bytes)\n",
+ eNB_id,i,common_vars->txdataF[eNB_id][i],
+ fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t));
#endif
- }
- }
+ }
+ }
}
+
for (i=0; inb_antennas_tx; i++) {
- common_vars->txdataF_BF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t) );
- if (eNB->node_function != NGFI_RCC_IF4p5)
+ common_vars->txdataF_BF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t) );
+ if (eNB->node_function != NGFI_RCC_IF4p5)
- // Allocate 10 subframes of I/Q TX signal data (time) if not
- common_vars->txdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
+ // Allocate 10 subframes of I/Q TX signal data (time) if not
+ common_vars->txdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
#ifdef DEBUG_PHY
- printf("[openair][LTE_PHY][INIT] common_vars->txdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->txdata[eNB_id][i],
- fp->samples_per_tti*10*sizeof(int32_t));
+ printf("[openair][LTE_PHY][INIT] common_vars->txdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->txdata[eNB_id][i],
+ fp->samples_per_tti*10*sizeof(int32_t));
#endif
}
-
+
for (i=0; inb_antenna_ports_eNB || i==5) {
- common_vars->beam_weights[eNB_id][i] = (int32_t **)malloc16_clear(fp->nb_antennas_tx*sizeof(int32_t*));
- for (j=0; jnb_antennas_tx; j++) {
- common_vars->beam_weights[eNB_id][i][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 (((i<4) && (i==j)) || ((i==4) && (j==0))) {
- for (re=0; reofdm_symbol_size; re++)
- common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff;
- }
- else if (i>4) {
- for (re=0; reofdm_symbol_size; re++)
- common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff/fp->nb_antennas_tx;
- }
+ if (inb_antenna_ports_eNB || i==5) {
+ common_vars->beam_weights[eNB_id][i] = (int32_t **)malloc16_clear(fp->nb_antennas_tx*sizeof(int32_t*));
+ for (j=0; jnb_antennas_tx; j++) {
+ common_vars->beam_weights[eNB_id][i][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 (((i<4) && (i==j)) || ((i==4) && (j==0))) {
+ for (re=0; reofdm_symbol_size; re++)
+ common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff;
+ }
+ else if (i>4) {
+ for (re=0; reofdm_symbol_size; re++)
+ common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff/fp->nb_antennas_tx;
+ }
#ifdef DEBUG_PHY
- msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%d bytes)\n",
- eNB_id,i,j,common_vars->beam_weights[eNB_id][i][j],
- fp->ofdm_symbol_size*sizeof(int32_t));
+ msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%zu bytes)\n",
+ eNB_id,i,j,common_vars->beam_weights[eNB_id][i][j],
+ fp->ofdm_symbol_size*sizeof(int32_t));
#endif
- }
- }
+ }
+ }
}
+
// RX vars
if (eNB->node_function != NGFI_RCC_IF4p5) {
- common_vars->rxdata[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
- common_vars->rxdata_7_5kHz[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
+ common_vars->rxdata[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
+ common_vars->rxdata_7_5kHz[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
}
+
common_vars->rxdataF[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
- for (i=0; inb_antennas_rx; i++) {
- if (eNB->node_function != NGFI_RCC_IF4p5) {
- // allocate 2 subframes of I/Q signal data (time) if not an RCC (no time-domain signals)
- common_vars->rxdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
- if (eNB->node_function != NGFI_RRU_IF5)
- // allocate 2 subframes of I/Q signal data (time, 7.5 kHz offset)
- common_vars->rxdata_7_5kHz[eNB_id][i] = (int32_t*)malloc16_clear( 2*fp->samples_per_tti*2*sizeof(int32_t) );
- }
- if (eNB->node_function != NGFI_RRU_IF5)
- // allocate 2 subframes of I/Q signal data (frequency)
- common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) );
+ for (i=0; inb_antennas_rx; i++) {
+ if (eNB->node_function != NGFI_RCC_IF4p5) {
+ // allocate 2 subframes of I/Q signal data (time) if not an RCC (no time-domain signals)
+ common_vars->rxdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
+
+ if (eNB->node_function != NGFI_RRU_IF5)
+ // allocate 2 subframes of I/Q signal data (time, 7.5 kHz offset)
+ common_vars->rxdata_7_5kHz[eNB_id][i] = (int32_t*)malloc16_clear( 2*fp->samples_per_tti*2*sizeof(int32_t) );
+ }
+
+ if (eNB->node_function != NGFI_RRU_IF5)
+ // allocate 2 subframes of I/Q signal data (frequency)
+ common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) );
+
#ifdef DEBUG_PHY
- printf("[openair][LTE_PHY][INIT] common_vars->rxdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata[eNB_id][i],fp->samples_per_tti*10*sizeof(int32_t));
- if (eNB->node_function != NGFI_RRU_IF5)
- printf("[openair][LTE_PHY][INIT] common_vars->rxdata_7_5kHz[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata_7_5kHz[eNB_id][i],fp->samples_per_tti*2*sizeof(int32_t));
+ printf("[openair][LTE_PHY][INIT] common_vars->rxdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata[eNB_id][i],fp->samples_per_tti*10*sizeof(int32_t));
+ if (eNB->node_function != NGFI_RRU_IF5)
+ printf("[openair][LTE_PHY][INIT] common_vars->rxdata_7_5kHz[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata_7_5kHz[eNB_id][i],fp->samples_per_tti*2*sizeof(int32_t));
#endif
common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(fp->ofdm_symbol_size*fp->symbols_per_tti) );
}
-
+
+
if ((eNB->node_function != NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5)) {
- // Channel estimates for SRS
- for (UE_id=0; UE_idnb_antennas_rx*sizeof(int32_t*) );
- srs_vars[UE_id].srs_ch_estimates_time[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-
- for (i=0; inb_antennas_rx; i++) {
- srs_vars[UE_id].srs_ch_estimates[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size );
- srs_vars[UE_id].srs_ch_estimates_time[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
- }
- } //UE_id
-
- common_vars->sync_corr[eNB_id] = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_tti );
+
+ // Channel estimates for SRS
+ for (UE_id=0; UE_idnb_antennas_rx*sizeof(int32_t*) );
+ srs_vars[UE_id].srs_ch_estimates_time[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+
+ for (i=0; inb_antennas_rx; i++) {
+ srs_vars[UE_id].srs_ch_estimates[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size );
+ srs_vars[UE_id].srs_ch_estimates_time[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
+ }
+ } //UE_id
+
+ common_vars->sync_corr[eNB_id] = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_tti );
}
} // abstraction_flag = 0
else { //UPLINK abstraction = 1
eNB->sinr_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
}
} //eNB_id
-
-
-
+
+
+
if (abstraction_flag==0) {
if ((eNB->node_function != NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5)) {
generate_ul_ref_sigs_rx();
-
+
// SRS
for (UE_id=0; UE_idofdm_symbol_size*sizeof(int32_t));
+ srs_vars[UE_id].srs = (int32_t*)malloc16_clear(2*fp->ofdm_symbol_size*sizeof(int32_t));
}
}
}
-
-
-
+
+
+
// ULSCH VARS, skip if NFGI_RRU_IF4
-
+
+
if ((eNB->node_function!=NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5))
+
prach_vars->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int16_t) );
-
+
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
"nb_antennas_rx too large");
@@ -1459,10 +1505,11 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
printf("[openair][LTE_PHY][INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
#endif
}
-
+
if ((eNB->node_function != NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5)) {
+
AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->prach_ifft) / sizeof(prach_vars->prach_ifft[0]),
- "nb_antennas_rx too large");
+ "nb_antennas_rx too large");
for (i=0; inb_antennas_rx; i++) {
prach_vars->prach_ifft[i] = (int16_t*)malloc16_clear(1024*2*sizeof(int16_t));
#ifdef DEBUG_PHY
@@ -1471,77 +1518,81 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
}
for (UE_id=0; UE_idrxdataF_ext[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
- pusch_vars[UE_id]->rxdataF_ext2[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
- pusch_vars[UE_id]->drs_ch_estimates[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
- pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
- pusch_vars[UE_id]->rxdataF_comp[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
- pusch_vars[UE_id]->ul_ch_mag[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
- pusch_vars[UE_id]->ul_ch_magb[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-
- for (i=0; inb_antennas_rx; i++) {
- // RK 2 times because of output format of FFT!
- // FIXME We should get rid of this
- pusch_vars[UE_id]->rxdataF_ext[eNB_id][i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
- pusch_vars[UE_id]->rxdataF_ext2[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
- pusch_vars[UE_id]->drs_ch_estimates[eNB_id][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[eNB_id][i] = (int32_t*)malloc16_clear( 2*2*sizeof(int32_t)*fp->ofdm_symbol_size );
- pusch_vars[UE_id]->rxdataF_comp[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
- pusch_vars[UE_id]->ul_ch_mag[eNB_id][i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
- pusch_vars[UE_id]->ul_ch_magb[eNB_id][i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
- }
- } //eNB_id
-
- pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+ for (eNB_id=0; eNB_id<3; eNB_id++) {
+
+ pusch_vars[UE_id]->rxdataF_ext[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+ pusch_vars[UE_id]->rxdataF_ext2[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+ pusch_vars[UE_id]->drs_ch_estimates[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+ pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+ pusch_vars[UE_id]->rxdataF_comp[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+ pusch_vars[UE_id]->ul_ch_mag[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+ pusch_vars[UE_id]->ul_ch_magb[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+
+ for (i=0; inb_antennas_rx; i++) {
+ // RK 2 times because of output format of FFT!
+ // FIXME We should get rid of this
+ pusch_vars[UE_id]->rxdataF_ext[eNB_id][i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
+ pusch_vars[UE_id]->rxdataF_ext2[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
+ pusch_vars[UE_id]->drs_ch_estimates[eNB_id][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[eNB_id][i] = (int32_t*)malloc16_clear( 2*2*sizeof(int32_t)*fp->ofdm_symbol_size );
+ pusch_vars[UE_id]->rxdataF_comp[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
+ pusch_vars[UE_id]->ul_ch_mag[eNB_id][i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
+ pusch_vars[UE_id]->ul_ch_magb[eNB_id][i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
+ }
+ } //eNB_id
+
+ pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
} // abstraction_flag
} //UE_id
-
+
if (abstraction_flag==0) {
if (is_secondary_eNB) {
- for (eNB_id=0; eNB_id<3; eNB_id++) {
- eNB->dl_precoder_SeNB[eNB_id] = (int **)malloc16(4*sizeof(int*));
-
- if (eNB->dl_precoder_SeNB[eNB_id]) {
+ for (eNB_id=0; eNB_id<3; eNB_id++) {
+ eNB->dl_precoder_SeNB[eNB_id] = (int **)malloc16(4*sizeof(int*));
+
+ if (eNB->dl_precoder_SeNB[eNB_id]) {
#ifdef DEBUG_PHY
- printf("[openair][SECSYS_PHY][INIT] eNB->dl_precoder_SeNB[%d] allocated at %p\n",eNB_id,
- eNB->dl_precoder_SeNB[eNB_id]);
+ printf("[openair][SECSYS_PHY][INIT] eNB->dl_precoder_SeNB[%d] allocated at %p\n",eNB_id,
+ eNB->dl_precoder_SeNB[eNB_id]);
#endif
- } else {
- printf("[openair][SECSYS_PHY][INIT] eNB->dl_precoder_SeNB[%d] not allocated\n",eNB_id);
- return(-1);
- }
-
- for (j=0; jnb_antennas_tx; j++) {
- eNB->dl_precoder_SeNB[eNB_id][j] = (int *)malloc16(2*sizeof(int)*(fp->ofdm_symbol_size)); // repeated format (hence the '2*')
-
- if (eNB->dl_precoder_SeNB[eNB_id][j]) {
+ } else {
+ printf("[openair][SECSYS_PHY][INIT] eNB->dl_precoder_SeNB[%d] not allocated\n",eNB_id);
+ return(-1);
+ }
+
+ for (j=0; jnb_antennas_tx; j++) {
+ eNB->dl_precoder_SeNB[eNB_id][j] = (int *)malloc16(2*sizeof(int)*(fp->ofdm_symbol_size)); // repeated format (hence the '2*')
+
+ if (eNB->dl_precoder_SeNB[eNB_id][j]) {
#ifdef DEBUG_PHY
- printf("[openair][LTE_PHY][INIT] eNB->dl_precoder_SeNB[%d][%d] allocated at %p\n",eNB_id,j,
- eNB->dl_precoder_SeNB[eNB_id][j]);
+ printf("[openair][LTE_PHY][INIT] eNB->dl_precoder_SeNB[%d][%d] allocated at %p\n",eNB_id,j,
+ eNB->dl_precoder_SeNB[eNB_id][j]);
#endif
- memset(eNB->dl_precoder_SeNB[eNB_id][j],0,2*sizeof(int)*(fp->ofdm_symbol_size));
- } else {
- printf("[openair][LTE_PHY][INIT] eNB->dl_precoder_SeNB[%d][%d] not allocated\n",eNB_id,j);
- return(-1);
- }
- } //for(j=...nb_antennas_tx
-
- } //for(eNB_id...
+ memset(eNB->dl_precoder_SeNB[eNB_id][j],0,2*sizeof(int)*(fp->ofdm_symbol_size));
+ } else {
+ printf("[openair][LTE_PHY][INIT] eNB->dl_precoder_SeNB[%d][%d] not allocated\n",eNB_id,j);
+ return(-1);
+ }
+ } //for(j=...nb_antennas_tx
+
+ } //for(eNB_id...
}
}
-
+
for (UE_id=0; UE_idUE_stats_ptr[UE_id] = &eNB->UE_stats[UE_id];
-
- eNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
+
+ //defaul value until overwritten by RRCConnectionReconfiguration
+ if (fp->nb_antenna_ports_eNB==2)
+ eNB->pdsch_config_dedicated->p_a = dBm3;
+ else
+ eNB->pdsch_config_dedicated->p_a = dB0;
init_prach_tables(839);
} // node_function != NGFI_RRU_IF4p5
diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c
index 4625eba430..f3833b7709 100644
--- a/openair1/PHY/INIT/lte_param_init.c
+++ b/openair1/PHY/INIT/lte_param_init.c
@@ -121,9 +121,9 @@ void lte_param_init(unsigned char N_tx_port_eNB,
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 = dB0; // 4 = 0dB
+ eNB->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB
((eNB->frame_parms).pdsch_config_common).p_b = 1;
- UE->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB
+ UE->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB
((UE->frame_parms).pdsch_config_common).p_b = 1;
}
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 df6a55eaf3..02b5102ae5 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
@@ -1,31 +1,24 @@
-/*******************************************************************************
- OpenAirInterface
- Copyright(c) 1999 - 2014 Eurecom
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
- OpenAirInterface is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
-
- OpenAirInterface is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with OpenAirInterface.The full GNU General Public License is
- included in this distribution in the file called "COPYING". If not,
- see .
-
- Contact Information
- OpenAirInterface Admin: openair_admin@eurecom.fr
- OpenAirInterface Tech : openair_tech@eurecom.fr
- OpenAirInterface Dev : openair4g-devel@eurecom.fr
-
- Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
-
- *******************************************************************************/
#ifdef USER_MODE
#include
#endif
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
index e6551033f3..6ce10723c6 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
@@ -581,10 +581,10 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
*peak_val_out = peak_val;
if (peak_val <= (40*(uint32_t)mean_val)) {
- LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%u,%u)\n",peak_pos,peak_val,mean_val,40*mean_val);
+ LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%"PRIu64",%"PRIu64")\n",peak_pos,peak_val,mean_val,40*mean_val);
return(-1);
} else {
- LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %u\n",peak_pos,peak_val,mean_val);
+ LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %"PRIu64"\n",peak_pos,peak_val,mean_val);
return(peak_pos);
}
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index db8fe548a2..d075d0ca50 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -197,9 +197,9 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
if (ue->frame_parms.Ncp==NORMAL) {
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
+
rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
-
//-ve spectrum from SSS
// printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]);
@@ -298,8 +298,9 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
// note this is a dummy pointer, the pss is not really there!
// in FDD the pss is in the symbol after the sss, but not in TDD
+
rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
-
+
//-ve spectrum from SSS
// ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
@@ -312,14 +313,14 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
// ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
-
+
ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(6));
- ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx];
- }
+ ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx];
+ }
ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(6*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);
-
-
+
+
}
#endif
}
@@ -363,7 +364,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
// if ((ue->frame_rx&0x3ff) == 0)
// printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
-
+
off+=12;
if (off>=(ue->frame_parms.ofdm_symbol_size<<1))
@@ -474,6 +475,14 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
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;
+ ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
+
+ if (ue->transmission_mode[eNB_id]!=4)
+ ue->measurements.rank[eNB_id] = 0;
+ else
+ ue->measurements.rank[eNB_id] = 1;
+ // printf ("tx mode %d\n", ue->transmission_mode[eNB_id]);
+ // printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]);
switch (N_RB_DL) {
case 6:
@@ -625,6 +634,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
}
for (aarx=0; aarxnb_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)
#if defined(__x86_64__) || defined(__i386__)
@@ -644,9 +654,11 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
// pmi
#if defined(__x86_64__) || defined(__i386__)
- pmi128_re = _mm_setzero_si128();
- pmi128_im = _mm_setzero_si128();
+
+ 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
@@ -659,18 +671,52 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
for (i=0; imeasurements.rank[eNB_id] = 0;
+ //ue->measurements.rank[eNB_id] = 0;
for (i=0; imeasurements.selected_rx_antennas[eNB_id][i] = 0;
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h
index 74c150ccab..c250e7c10a 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.h
+++ b/openair1/PHY/LTE_TRANSPORT/dci.h
@@ -2969,3 +2969,53 @@ struct DCI0A_20_MHz {
#define sizeof_DCI0A_20MHz 17
#define MAX_DCI_SIZE_BITS 45
+
+struct DCI_INFO_EXTRACTED {
+ /// type = 0 => DCI Format 0, type = 1 => DCI Format 1A
+ uint8_t type;
+ /// Resource Allocation Header
+ uint8_t rah;
+ /// HARQ Process
+ uint8_t harq_pid;
+ /// CQI Request
+ uint8_t cqi_req;
+ /// SRS Request
+ uint8_t srs_req;
+ /// Power Control
+ uint8_t TPC;
+ /// Localized/Distributed VRB
+ uint8_t vrb_type;
+ /// RB Assignment (ceil(log2(N_RB_DL/P)) bits)
+ uint32_t rballoc;
+ // Applicable only when vrb_type = 1
+ uint8_t Ngap;
+ /// Cyclic shift
+ uint8_t cshift;
+ /// Hopping flag
+ uint8_t hopping;
+ /// Downlink Assignment Index
+ uint8_t dai;
+ /// DAI (TDD)
+ uint8_t ulindex;
+
+ /// TB swap
+ uint8_t tb_swap;
+ /// TPMI information for precoding
+ uint8_t tpmi;
+ /// Redundancy version 2
+ uint8_t rv2;
+ /// New Data Indicator 2
+ uint8_t ndi2;
+ /// Modulation and Coding Scheme and Redundancy Version 2
+ uint8_t mcs2;
+ /// Redundancy version 1
+ uint8_t rv1;
+ /// New Data Indicator 1
+ uint8_t ndi1;
+ /// Modulation and Coding Scheme and Redundancy Version 1
+ uint8_t mcs1;
+
+ /// Scrambling ID
+ uint64_t ap_si_nl_id:3;
+};
+typedef struct DCI_INFO_EXTRACTED DCI_INFO_EXTRACTED_t;
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index b262dbccf9..9f4749cdc6 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -37,6 +37,9 @@
#endif
#include "assertions.h"
+
+//#define DEBUG_HARQ
+
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
@@ -399,7 +402,7 @@ uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs)
}
// Convert a DCI Format 1C RIV to a Format 1A RIV
-// This extracts the start and length in PRBs from the 1C rballoc and
+// 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) {
@@ -443,7 +446,7 @@ uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) {
}
// 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) {
@@ -451,11 +454,11 @@ 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:
@@ -466,19 +469,19 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
return ((3*odd_slot) + 2*(vrb&3) + 5)%6;
break;
case 4: // even: 4->1, odd: 4->4
- return ((3*odd_slot) + 1)%6;
+ 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);
+ 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);
+ return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14);
}
if (vrb==12)
return (3+(7*odd_slot)) % 14;
@@ -486,71 +489,71 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
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;
+ offset=4;
else
- offset=0;
+ 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&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);
+ return offset+((23*odd_slot) + 22-12+1);
if (vrb==45) // even: 45->10, odd: 45->33
- return offset+((23*odd_slot) + 22+12);
+ return offset+((23*odd_slot) + 22+12);
if (vrb==46)
- return offset+46+((23*odd_slot) + 23-12+1) % 46;
+ return offset+46+((23*odd_slot) + 23-12+1) % 46;
if (vrb==47)
- return offset+46+((23*odd_slot) + 23+12) % 46;
+ return offset+46+((23*odd_slot) + 23+12) % 46;
if (vrb==48)
- return offset+46+((23*odd_slot) + 23-12+1) % 46;
+ return offset+46+((23*odd_slot) + 23-12+1) % 46;
if (vrb==49)
- return offset+46+((23*odd_slot) + 23+12) % 46;
+ return offset+46+((23*odd_slot) + 23+12) % 46;
}
else {
// Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27
if (vrb>=9)
- offset=18;
+ offset=18;
else
- offset=0;
-
+ 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;
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
}
break;
default:
@@ -558,7 +561,7 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
return 0;
}
return 0;
-
+
}
@@ -737,7 +740,7 @@ void generate_RIV_tables()
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);
+// printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist);
if (nVRB_even_dist<32)
@@ -745,16 +748,16 @@ void generate_RIV_tables()
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));
+ allocdist2_0_even |= (1<<(nVRB_even_dist-64));
else
- allocdist3_0_even |= (1<<(nVRB_even_dist-96));
+ 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
- );
+ 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);
@@ -763,9 +766,9 @@ void generate_RIV_tables()
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));
+ allocdist2_0_odd |= (1<<(nVRB_odd_dist-64));
else
- allocdist3_0_odd |= (1<<(nVRB_odd_dist-96));
+ allocdist3_0_odd |= (1<<(nVRB_odd_dist-96));
// Distributed Gap2, even slot
@@ -775,9 +778,9 @@ void generate_RIV_tables()
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));
+ allocdist2_1_even |= (1<<(nVRB_even_dist-64));
else
- allocdist3_1_even |= (1<<(nVRB_even_dist-96));
+ allocdist3_1_even |= (1<<(nVRB_even_dist-96));
// Distributed Gap2, odd slot
@@ -787,9 +790,9 @@ void generate_RIV_tables()
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));
+ allocdist2_1_odd |= (1<<(nVRB_odd_dist-64));
else
- allocdist3_1_odd |= (1<<(nVRB_odd_dist-96));
+ allocdist3_1_odd |= (1<<(nVRB_odd_dist-96));
RIV=computeRIV(100,RBstart,Lcrbs);
@@ -855,7 +858,7 @@ uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti)
}
int generate_eNB_dlsch_params_from_dci(int frame,
- uint8_t subframe,
+ uint8_t subframe,
void *dci_pdu,
uint16_t rnti,
DCI_format_t dci_format,
@@ -866,14 +869,14 @@ int generate_eNB_dlsch_params_from_dci(int frame,
uint16_t ra_rnti,
uint16_t p_rnti,
uint16_t DL_pmi_single,
- uint8_t beamforming_mode)
+ uint8_t beamforming_mode)
{
uint8_t harq_pid = UINT8_MAX;
uint32_t rballoc = UINT32_MAX;
uint32_t RIV_max = 0;
uint8_t NPRB,tbswap,tpmi=0;
- LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1;
+ LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
uint8_t frame_type=frame_parms->frame_type;
uint8_t vrb_type=0;
uint8_t mcs=0,mcs1=0,mcs2=0;
@@ -881,6 +884,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
uint8_t rv=0,rv1=0,rv2=0;
uint8_t rah=0;
uint8_t TPC=0;
+ uint8_t TB0_active=0,TB1_active=0;
LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
// printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);
@@ -921,13 +925,14 @@ int generate_eNB_dlsch_params_from_dci(int frame,
}
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+ dlsch0_harq->codeword=0;
if (vrb_type==LOCALIZED) {
- dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rballoc];
+ dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rballoc];
}
else {
- LOG_E(PHY,"Distributed RB allocation not done yet\n");
- mac_xface->macphy_exit("exiting");
+ LOG_E(PHY,"Distributed RB allocation not done yet\n");
+ mac_xface->macphy_exit("exiting");
}
dlsch0_harq->vrb_type = vrb_type;
dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc];//NPRB;
@@ -959,13 +964,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
+
if (vrb_type==LOCALIZED) {
- dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rballoc];
+ dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rballoc];
}
else {
- LOG_E(PHY,"Distributed RB allocation not done yet\n");
- mac_xface->macphy_exit("exiting");
+ LOG_E(PHY,"Distributed RB allocation not done yet\n");
+ mac_xface->macphy_exit("exiting");
}
dlsch0_harq->vrb_type = vrb_type;
dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc];//NPRB;
@@ -994,12 +999,12 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
if (vrb_type==LOCALIZED) {
- dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rballoc];
+ dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rballoc];
+ dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rballoc];
}
else {
- LOG_E(PHY,"Distributed RB allocation not done yet\n");
- mac_xface->macphy_exit("exiting");
+ LOG_E(PHY,"Distributed RB allocation not done yet\n");
+ mac_xface->macphy_exit("exiting");
}
@@ -1031,14 +1036,14 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq->vrb_type = vrb_type;
if (vrb_type==LOCALIZED) {
- dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rballoc];
- dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rballoc];
- dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rballoc];
+ dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rballoc];
+ dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rballoc];
+ dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rballoc];
+ dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rballoc];
}
else {
- LOG_E(PHY,"Distributed RB allocation not done yet\n");
- mac_xface->macphy_exit("exiting");
+ LOG_E(PHY,"Distributed RB allocation not done yet\n");
+ mac_xface->macphy_exit("exiting");
}
@@ -1211,6 +1216,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
}
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+ dlsch0_harq->codeword=0;
// printf("DCI: Setting subframe_tx for subframe %d\n",subframe);
dlsch[0]->subframe_tx[subframe] = 1;
@@ -1240,7 +1246,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq->mimo_mode = TM7;
else
LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
-
+
dlsch0_harq->dl_power_off = 1;
/*
if (dlsch[0]->harq_processes[harq_pid]->first_tx == 1) {
@@ -1283,12 +1289,12 @@ int generate_eNB_dlsch_params_from_dci(int frame,
break;
- case format2:
+ case format2: // DL Scheduling assignment for MIMO including closed loop spatial multiplexing
switch (frame_parms->N_RB_DL) {
case 6:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
if (frame_type == TDD) {
mcs1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -1308,7 +1314,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tbswap = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
tpmi = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) {
if (frame_type == TDD) {
mcs1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -1329,13 +1335,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
case 25:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
if (frame_type == TDD) {
mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -1357,7 +1363,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) {
if (frame_type == TDD) {
mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -1380,13 +1386,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
case 50:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
if (frame_type == TDD) {
mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -1408,7 +1414,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) {
if (frame_type == TDD) {
mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -1431,13 +1437,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
case 100:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
if (frame_type == TDD) {
mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -1459,7 +1465,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) {
if (frame_type == TDD) {
mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -1482,7 +1488,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
@@ -1497,149 +1503,240 @@ int generate_eNB_dlsch_params_from_dci(int frame,
// Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
// note that we must set tbswap=0 in eNB scheduler if one TB is deactivated
- if (tbswap == 0) {
- dlsch0 = dlsch[0];
- dlsch1 = dlsch[1];
- } else {
- dlsch0 = dlsch[1];
- dlsch1 = dlsch[0];
+ TB0_active = 1;
+ TB1_active = 1;
+
+ if ((rv1 == 1) && (mcs1 == 0)) {
+ TB0_active=0;
+ }
+ if ((rv2 == 1) && (mcs2 == 0)) {
+ TB1_active=0;
+ }
+#ifdef DEBUG_HARQ
+ printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rv1, rv2, mcs1, mcs2);
+#endif
+ if (TB0_active && TB1_active && tbswap==0) {
+ dlsch0=dlsch[0];
+ dlsch1=dlsch[1];
+ dlsch0->active = 1;
+ dlsch1->active = 1;
+ dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ dlsch0_harq->mcs = mcs1;
+ dlsch1_harq->mcs = mcs2;
+ dlsch0_harq->rvidx = rv1;
+ dlsch1_harq->rvidx = rv2;
+ dlsch0_harq->status = ACTIVE;
+ dlsch1_harq->status = ACTIVE;
+ dlsch0_harq->codeword=0;
+ dlsch1_harq->codeword=1;
+#ifdef DEBUG_HARQ
+ printf("\n ENB: BOTH ACTIVE\n");
+#endif
+ }
+ else if (TB0_active && TB1_active && tbswap==1) {
+ dlsch0=dlsch[0];
+ dlsch1=dlsch[1];
+ dlsch0->active = 1;
+ dlsch1->active = 1;
+ dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ dlsch0_harq->mcs = mcs1;
+ dlsch1_harq->mcs = mcs2;
+ dlsch0_harq->rvidx = rv1;
+ dlsch1_harq->rvidx = rv2;
+ dlsch0_harq->status = ACTIVE;
+ dlsch1_harq->status = ACTIVE;
+ dlsch0_harq->codeword=1;
+ dlsch1_harq->codeword=0;
+ }
+ else if (TB0_active && (TB1_active==0)) {
+ dlsch0=dlsch[0];
+ dlsch0->active = 1;
+ dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ dlsch0_harq->mcs = mcs1;
+ dlsch0_harq->rvidx = rv1;
+ dlsch0_harq->status = ACTIVE;
+ dlsch0_harq->codeword = 0;
+ dlsch1=NULL;
+ dlsch1_harq = NULL;
+#ifdef DEBUG_HARQ
+ printf("\n ENB: TB1 is deactivated, retransmit TB0 transmit in TM6\n");
+#endif
+ }
+ else if ((TB0_active==0) && TB1_active) {
+ dlsch1=dlsch[1];
+ dlsch1->active = 1;
+ dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ dlsch1_harq->mcs = mcs2;
+ dlsch1_harq->rvidx = rv2;
+ dlsch1_harq->status = ACTIVE;
+ dlsch1_harq->codeword = 0;
+ dlsch0=NULL;
+ dlsch0_harq = NULL;
+#ifdef DEBUG_HARQ
+ printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
+#endif
}
- dlsch0_harq = dlsch0->harq_processes[harq_pid];
- dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ if (dlsch0 != NULL){
+ dlsch0->subframe_tx[subframe] = 1;
- dlsch0->subframe_tx[subframe] = 1;
+ dlsch0->current_harq_pid = harq_pid;
+ dlsch0->harq_ids[subframe] = harq_pid;
+ }
- dlsch0->current_harq_pid = harq_pid;
- dlsch1->current_harq_pid = harq_pid;
- dlsch0->harq_ids[subframe] = harq_pid;
- dlsch1->harq_ids[subframe] = harq_pid;
- // printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
+ if (dlsch1_harq != NULL){
+ dlsch1->current_harq_pid = harq_pid;
+ dlsch1->harq_ids[subframe] = harq_pid;
+ }
- conv_rballoc(rah,
- rballoc,
- frame_parms->N_RB_DL,
- dlsch0_harq->rb_alloc);
+ if (dlsch0 != NULL ){
+ conv_rballoc(rah,
+ rballoc,
+ frame_parms->N_RB_DL,
+ dlsch0_harq->rb_alloc);
- dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
- dlsch0_harq->nb_rb = conv_nprb(rah,
- rballoc,
- frame_parms->N_RB_DL);
- dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
+ dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL);
- if (dlsch0_harq->nb_rb == 0)
- return(-1);
+ if (dlsch1 != NULL){
+ dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
+ dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
+ }
+ } else if ((dlsch0 == NULL ) && (dlsch1 != NULL )){
+ conv_rballoc(rah,
+ rballoc,
+ frame_parms->N_RB_DL,
+ dlsch1_harq->rb_alloc);
+
+ dlsch1_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL);
+ }
+
+
+ /*if (dlsch0_harq->nb_rb == 0)
+ return(-1);*/
- dlsch0_harq->mcs = mcs1;
- dlsch1_harq->mcs = mcs2;
- dlsch0_harq->rvidx = rv1;
- dlsch1_harq->rvidx = rv2;
// assume both TBs are active
- dlsch0_harq->Nl = 1;
- dlsch1_harq->Nl = 1;
- dlsch0->active = 1;
- dlsch1->active = 1;
+ if (dlsch0_harq != NULL)
+ dlsch0_harq->Nl = 1;
+ if (dlsch1_harq != NULL)
+ dlsch1_harq->Nl = 1;
// check if either TB is disabled (see 36-213 V11.3 Section )
- if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
- dlsch0->active = 0;
- }
- if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
- dlsch1->active = 0;
- }
-
- if (frame_parms->nb_antennas_tx == 2) {
- if (dlsch1->active == 1) { // both TBs are active
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
+ if ((dlsch0 != NULL) && (dlsch1 != NULL)) { //two CW active
+ dlsch0_harq->dl_power_off = 1;
+ dlsch1_harq->dl_power_off = 1;
+ dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+ dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
switch (tpmi) {
case 0:
- dlsch0_harq->mimo_mode = UNIFORM_PRECODING11;
- dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0);
- dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1);
+ 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 = UNIFORM_PRECODING1j;
- dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2);
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3);
- break;
+ dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj;
+ dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj;
+ dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1);
+ dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1);
+ break;
case 2: // PUSCH precoding
dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING;
- dlsch0_harq->pmi_alloc = DL_pmi_single;
+ dlsch0_harq->pmi_alloc = DL_pmi_single;
dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING;
- dlsch1_harq->pmi_alloc = DL_pmi_single;
+ dlsch1_harq->pmi_alloc = DL_pmi_single;
break;
-
default:
break;
}
-
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
- } else { // only one is active
+ } else if ((dlsch0 != NULL) && (dlsch1 == NULL)) { // only CW 0 active
+ dlsch0_harq->dl_power_off = 1;
+ dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
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);
+ 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);
+ 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);
+ 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);
+ dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0);
break;
-
case 5:
dlsch0_harq->mimo_mode = PUSCH_PRECODING0;
- dlsch0_harq->pmi_alloc = DL_pmi_single;
+ dlsch0_harq->pmi_alloc = DL_pmi_single;
break;
-
case 6:
dlsch0_harq->mimo_mode = PUSCH_PRECODING1;
- dlsch0_harq->pmi_alloc = DL_pmi_single;
+ dlsch0_harq->pmi_alloc = DL_pmi_single;
break;
}
+ } else if ((dlsch0 == NULL) && (dlsch1 != NULL)) {
+ dlsch1_harq->dl_power_off = 1;
+ dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+ switch (tpmi) {
+ case 0 :
+ dlsch1_harq->mimo_mode = ALAMOUTI;
+ break;
+ case 1:
+ dlsch1_harq->mimo_mode = UNIFORM_PRECODING11;
+ dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,0);
+ break;
+ case 2:
+ dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1;
+ dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1,0);
+ break;
+ case 3:
+ dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j;
+ dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2,0);
+ break;
+ case 4:
+ dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj;
+ dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3,0);
+ break;
+ case 5:
+ dlsch1_harq->mimo_mode = PUSCH_PRECODING0;
+ dlsch1_harq->pmi_alloc = DL_pmi_single;
+ break;
+ case 6:
+ dlsch1_harq->mimo_mode = PUSCH_PRECODING1;
+ dlsch1_harq->pmi_alloc = DL_pmi_single;
+ break;
+ }
+ }
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
- }
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) {
// fill in later
}
// reset HARQ process if this is the first transmission
- if (dlsch0_harq->round == 0)
+ /* if (dlsch0_harq->round == 0)
dlsch0_harq->status = ACTIVE;
if (dlsch1_harq->round == 0)
- dlsch1_harq->status = ACTIVE;
-
- dlsch0->rnti = rnti;
- dlsch1->rnti = rnti;
-
- dlsch0_harq->dl_power_off = 0;
- dlsch1_harq->dl_power_off = 0;
+ dlsch1_harq->status = ACTIVE;*/
+ if (dlsch0_harq != NULL)
+ dlsch0->rnti = rnti;
+ if (dlsch1 != NULL)
+ dlsch1->rnti = rnti;
break;
@@ -1648,7 +1745,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
switch (frame_parms->N_RB_DL) {
case 6:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->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;
@@ -1666,7 +1763,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
harq_pid = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
tbswap = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->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;
@@ -1687,13 +1784,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
case 25:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->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;
@@ -1713,7 +1810,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
harq_pid = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
tbswap = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->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;
@@ -1736,13 +1833,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
case 50:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->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;
@@ -1762,7 +1859,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
harq_pid = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
tbswap = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->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;
@@ -1785,13 +1882,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
case 100:
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->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;
@@ -1811,7 +1908,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
harq_pid = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
tbswap = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->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;
@@ -1834,7 +1931,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
tpmi = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
}
} else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
}
break;
@@ -1849,6 +1946,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
// Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
// note that we must set tbswap=0 in eNB scheduler if one TB is deactivated
+ // This must be set as in TM4, does not work properly now.
if (tbswap == 0) {
dlsch0 = dlsch[0];
dlsch1 = dlsch[1];
@@ -1904,15 +2002,16 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch1->active = 0;
}
- dlsch0_harq->dl_power_off = 0;
- dlsch1_harq->dl_power_off = 0;
+ // dlsch0_harq->dl_power_off = 0;
+ // dlsch1_harq->dl_power_off = 0;
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
if ((dlsch0->active==1) && (dlsch1->active==1)) {
+
dlsch0_harq->mimo_mode = LARGE_CDD;
dlsch1_harq->mimo_mode = LARGE_CDD;
dlsch0_harq->dl_power_off = 1;
@@ -1921,7 +2020,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq->mimo_mode = ALAMOUTI;
dlsch1_harq->mimo_mode = ALAMOUTI;
}
- } else if (frame_parms->nb_antennas_tx == 4) { // 4 antenna case
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) { // 4 antenna case
if ((dlsch0->active==1) && (dlsch1->active==1)) {
switch (tpmi) {
case 0: // one layer per transport block
@@ -2004,7 +2103,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
}
}
} else {
- LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antennas_tx);
+ LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antenna_ports_eNB);
}
// reset HARQ process if this is the first transmission
@@ -2133,16 +2232,21 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq = dlsch0->harq_processes[harq_pid];
dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ // Needs to be checked
+ dlsch0_harq->codeword=0;
+ dlsch1_harq->codeword=1;
+
conv_rballoc(rah,
rballoc,
frame_parms->N_RB_DL,
dlsch0_harq->rb_alloc);
- dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
- dlsch0_harq->nb_rb = conv_nprb(rah,
- rballoc,
- frame_parms->N_RB_DL);
- dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
+ dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
+
+ dlsch0_harq->nb_rb = conv_nprb(rah,
+ rballoc,
+ frame_parms->N_RB_DL);
+ dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
dlsch0_harq->mcs = mcs1;
dlsch1_harq->mcs = mcs2;
@@ -2293,6 +2397,10 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq = dlsch0->harq_processes[harq_pid];
dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ // Needs to be checked
+ dlsch0_harq->codeword=0;
+ dlsch1_harq->codeword=1;
+
conv_rballoc(rah,
rballoc,
frame_parms->N_RB_DL,
@@ -2336,14 +2444,14 @@ int generate_eNB_dlsch_params_from_dci(int frame,
}
// check TPMI information to compute TBS
- if (frame_parms->nb_antennas_tx == 2) {
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
if (dlsch1->active == 1) { // both TBs are active
dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
} else {
dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) {
}
@@ -2465,6 +2573,10 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq = dlsch0->harq_processes[harq_pid];
dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ // Needs to be checked
+ dlsch0_harq->codeword=0;
+ dlsch1_harq->codeword=1;
+
conv_rballoc(rah,
rballoc,
frame_parms->N_RB_DL,
@@ -2546,6 +2658,8 @@ int generate_eNB_dlsch_params_from_dci(int frame,
//dlsch1->harq_ids[subframe] = harq_pid;
// printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
dlsch0_harq = dlsch0->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,
@@ -2586,27 +2700,30 @@ int generate_eNB_dlsch_params_from_dci(int frame,
case 1:
dlsch0_harq->mimo_mode = UNIFORM_PRECODING11;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0);
+ 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);
+ 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);
+ 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);
+ dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0);
break;
case 5:
dlsch0_harq->mimo_mode = PUSCH_PRECODING0;
- dlsch0_harq->pmi_alloc = DL_pmi_single;
+ dlsch0_harq->pmi_alloc = DL_pmi_single;
break;
case 6:
@@ -2652,7 +2769,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
break;
}
-
+
if (dlsch0_harq) {
dlsch0_harq->frame = frame;
dlsch0_harq->subframe = subframe;
@@ -2678,12 +2795,33 @@ int generate_eNB_dlsch_params_from_dci(int frame,
printf("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode);
}
+ if (dlsch1) {
+ printf("dlsch1 eNB: dlsch1 %p\n",dlsch1);
+ printf("dlsch1 eNB: rnti %x\n",dlsch1->rnti);
+ printf("dlsch1 eNB: NBRB %d\n",dlsch1_harq->nb_rb);
+ printf("dlsch1 eNB: rballoc %x\n",dlsch1_harq->rb_alloc[0]);
+ printf("dlsch1 eNB: harq_pid %d\n",harq_pid);
+ printf("dlsch1 eNB: round %d\n",dlsch1_harq->round);
+ printf("dlsch1 eNB: rvidx %d\n",dlsch1_harq->rvidx);
+ printf("dlsch1 eNB: TBS %d (NPRB %d)\n",dlsch1_harq->TBS,NPRB);
+ printf("dlsch1 eNB: mcs %d\n",dlsch1_harq->mcs);
+ printf("dlsch1 eNB: tpmi %d\n",tpmi);
+ printf("dlsch1 eNB: mimo_mode %d\n",dlsch1_harq->mimo_mode);
+ }
+
#endif
// compute DL power control parameters
- computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off);
+ if (dlsch0 != NULL){
+ computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
+}
+ if (dlsch1 != NULL){
+ computeRhoA_eNB(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
+ computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off);
+ }
+
return(0);
}
@@ -3074,45 +3212,45 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
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)]);
+ ((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_antennas_tx == 2) {
+ 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",
@@ -3195,7 +3333,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
DevParam (frame_parms->N_RB_DL, 0, 0);
break;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } 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",
@@ -3280,7 +3418,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
}
}
} else if (frame_parms->frame_type == FDD) {
- if (frame_parms->nb_antennas_tx == 2) {
+ 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",
@@ -3300,7 +3438,9 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
break;
case 25:
- LOG_D(PHY,"DCI format2 2 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",
+
+ 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,
@@ -3358,7 +3498,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
DevParam (frame_parms->N_RB_DL, 0, 0);
break;
}
- } else if (frame_parms->nb_antennas_tx == 4) {
+ } else if (frame_parms->nb_antenna_ports_eNB == 4) {
switch(frame_parms->N_RB_DL) {
case 6:
@@ -3801,8 +3941,1907 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
}
+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,
+ 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 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 NPRB = 0;
+ long long int RIV_max = 0;
+
+#ifdef DEBUG_DCI
+ LOG_I(PHY,"[DCI-FORMAT-1-1A] dci_format %d\n", 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 %d \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;
+ uint8_t ndi1 = pdci_info_extarcted->ndi1;
+ uint8_t ndi2 = pdci_info_extarcted->ndi2;
+
+ uint8_t NPRB = 0;
+ long long RIV_max = 0;
+
+ LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format);
+ 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 pif %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);
+
+ // 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) && (mcs1 != pdlsch0_harq->mcs))
+ {
+ // DCI false detection
+ 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 %d\n", rballoc, RIV_max);
+ return(0);
+ }
+
+ if(NPRB == 0)
+ {
+ // DCI false detection
+ LOG_I(PHY,"bad NPRB\n");
+ return(0);
+ }
+
+ return(1);
+}
+
+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,
+ uint8_t subframe,
+ uint16_t 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;
+
+ if(dci_format == format1A)
+ {
+ if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
+ {
+ NPRB = (TPC&1) + 2;
+ }
+ else
+ {
+ 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);
+ }
+
+ 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->first_tx = 1;
+ pdlsch0_harq->status = ACTIVE;
+ }
+ else //CRNTI
+ {
+ // DCI has been toggled or this is the first transmission
+ if (ndi1!=pdlsch0_harq->DCINdi)
+ {
+ pdlsch0_harq->round = 0;
+ pdlsch0_harq->first_tx = 1;
+ pdlsch0_harq->status = ACTIVE;
+ }
+
+ if( ((ndi1 == pdlsch0_harq->DCINdi) && (pdlsch0_harq->round == 0)) ||
+ ((rv1 != 0) && (pdlsch0_harq->round == 0))
+ )
+ {
+ 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;
+ }
+ }
+
+ 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->mode1_flag == 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][NPRB-1];
+ pdlsch0_harq->Qm = 2;
+ }
+ else
+ {
+ if(mcs1 < 29)
+ {
+ pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB-1];
+ pdlsch0_harq->Qm = get_Qm(mcs1);
+ }
+ }
+}
+
+void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
+ DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ 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->mode1_flag == 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;
+ }
+}
+
+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;
+ }
+ 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);
+ #ifdef DEBUG_HARQ
+ printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc);
+ #endif
+ break;
+ case 6:
+ dlsch_harq->mimo_mode = PUSCH_PRECODING1;
+ dlsch_harq->pmi_alloc = pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
+ #ifdef DEBUG_HARQ
+ printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc);
+ #endif
+ break;
+ }
+}
+
+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,
+ 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 = 0;
+ uint8_t TB1_active = 0;
+
+
+
+ // check if either TB is disabled (see 36-213 V8.6 p. 26)
+ TB0_active = 1;
+ TB1_active = 1;
+
+ 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;
+
+
+ if (TB0_active && TB1_active && tbswap==1) {
+ dlsch0_harq->codeword = 1;
+ dlsch1_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]: TB1 is deactivated, retransmit TB0 transmit in TM6\n");
+#endif
+ }
+
+
+#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;
+ }
+ } 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);
+ } 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, pdlsch0->pmi_alloc, frame_parms, dlsch1_harq);
+ }
+ //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode);
+ if ((frame_parms->mode1_flag == 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);
+ }
+
+ // reset round + compute Qm
+ if (TB0_active) {
+ if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) {
+ dlsch0_harq->round = 0;
+
+ if ( dlsch0_harq->first_tx==1) {
+ LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n");
+ dlsch0_harq->first_tx = 0;
+ }
+ }else{
+ if(dlsch0_harq->round == 0) {
+ // 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;
+ }
+ }
+
+ dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+ 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;
+ }
+
+ if (TB1_active) {
+ if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) {
+ dlsch1_harq->round = 0;
+ if (dlsch1_harq->first_tx==1) {
+ LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n");
+ dlsch1_harq->first_tx = 0;
+ }
+ }else{
+ if(dlsch1_harq->round == 0) {
+ // 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;
+ }
+ }
+
+ dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+ if(dlsch0_harq->Nl == 2)
+ dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
+
+ if (mcs2 <= 28)
+ dlsch1_harq->Qm = get_Qm(mcs2);
+ else if (mcs1<=31)
+ dlsch1_harq->Qm = (mcs2-28)<<1;
+ }
+
+#ifdef DEBUG_HARQ
+ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+#endif
+
+ #ifdef DEBUG_HARQ
+ 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,
+ uint8_t subframe,
void *dci_pdu,
uint16_t rnti,
DCI_format_t dci_format,
@@ -3816,1481 +5855,431 @@ int generate_ue_dlsch_params_from_dci(int frame,
uint16_t tc_rnti)
{
- uint8_t harq_pid=0;
- uint32_t rballoc=0,RIV_max=0;
- uint8_t frame_type=frame_parms->frame_type;
- uint8_t vrb_type=0;
- uint8_t mcs=0,mcs1=0,mcs2=0;
- uint8_t rv=0,rv1=0,rv2=0;
- uint8_t ndi=0,ndi1=0,ndi2=0;
- uint8_t rah=0;
- uint8_t TPC=0;
- uint8_t NPRB=0,tbswap=0,tpmi=0;
- uint8_t Ngap;
- uint8_t dai=0;
- LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
- LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq;
+
+ 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,
+ &dci_info_extarcted,
+ dlsch0_harq);
+ if(status == 0)
+ 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,
+ subframe,
+ 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,
+ 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_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"
- ))))))))))))));
+ 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,
+ &dci_info_extarcted,
+ dlsch0_harq);
+ if(status == 0)
+ return(-1);
- switch (dci_format) {
+ // 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,
+ subframe,
+ rnti,
+ si_rnti,
+ ra_rnti,
+ p_rnti,
+ dlsch0_harq,
+ dlsch0);
+ break;
+ }
- case format0: // This is an ULSCH allocation so nothing here, inform MAC
- LOG_E(PHY,"format0 not possible\n");
- return(-1);
+ case format2:
+ {
+ // extract dci infomation
+ LOG_I(PHY,"[DCI-format2] extract dci infomation \n");
+ 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 = 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[harq_pid];
+ dlsch1_harq = dlsch1->harq_processes[harq_pid];
+
+ 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,
+ subframe,
+ dlsch0_harq,
+ dlsch1_harq,
+ dlsch0,
+ dlsch1);
+
+ }
break;
- case format1A:
-
- switch (frame_parms->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);
- }
-
- if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { //
- harq_pid = 0;
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- // see 36-212 V8.6.0 p. 45
- NPRB = (TPC&1) + 2;
- } else {
-
- if (harq_pid>=8) {
- LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid);
- return(-1);
- }
-
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- NPRB = RIV2nb_rb_LUT6[rballoc];
- dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
- }
-
- if (vrb_type == LOCALIZED) {
- dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc];
- }
- else {
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc];
- }
- dlsch0_harq->vrb_type = vrb_type;
-
-
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc];//NPRB;
- RIV_max = RIV_max6;
-
- 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);
- }
-
- if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { //
- harq_pid = 0;
- // see 36-212 V8.6.0 p. 45
- NPRB = (TPC&1) + 2;
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- } else {
-
- if (harq_pid>=8) {
- LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid);
- return(-1);
- }
-
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- NPRB = RIV2nb_rb_LUT25[rballoc];
- dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
- }
-
- if (vrb_type == LOCALIZED) {
- dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc];
- }
- else {
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc];
- }
- dlsch0_harq->vrb_type = vrb_type;
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc];
- RIV_max = RIV_max25;
-
- 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);
- }
-
- if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { //
- harq_pid = 0;
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- // see 36-212 V8.6.0 p. 45
- NPRB = (TPC&1) + 2;
- } else {
-
- if (harq_pid>=8) {
- LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid);
- return(-1);
- }
-
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- NPRB = RIV2nb_rb_LUT50[rballoc];
- dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
- }
-
- if (vrb_type == LOCALIZED) {
- dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc];
- // printf("rballoc: %08x.%08x\n",dlsch0_harq->rb_alloc_even[0],dlsch0_harq->rb_alloc_even[1]);
- } else { // DISTRIBUTED
- if ((rballoc&(1<<10)) == 0) {
- rballoc = rballoc&(~(1<<10));
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
- }
- else {
- rballoc = rballoc&(~(1<<10));
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
- }
- }
- dlsch0_harq->vrb_type = vrb_type;
-
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc];//NPRB;
- RIV_max = RIV_max50;
- 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);
- }
-
- if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { //
- harq_pid = 0;
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- // see 36-212 V8.6.0 p. 45
- NPRB = (TPC&1) + 2;
- } else {
-
- if (harq_pid>=8) {
- LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid);
- return(-1);
- }
-
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- NPRB = RIV2nb_rb_LUT100[rballoc];
- dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
- }
-
- if (vrb_type == LOCALIZED) {
- dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc];
- } else {
- if ((rballoc&(1<<10)) == 0) { //Gap 1
- rballoc = rballoc&(~(1<<12));
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc];
- }
- else { //Gap 2
- rballoc = rballoc&(~(1<<12));
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc];
- }
- }
- dlsch0_harq->vrb_type = vrb_type;
-
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc];//NPRB;
- RIV_max = RIV_max100;
- break;
- }
-
- if (rballoc>RIV_max) {
- LOG_E(PHY,"Format 1A: rb_alloc > RIV_max\n");
- return(-1);
- }
-
- if (NPRB==0) {
- LOG_E(PHY,"Format 1A: NPRB=0\n");
- return(-1);
- }
-
- if((mcs>28) && ( (dlsch0_harq->round == 0) || (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) ))
+ case format2A:
{
- // DCI false detection
- return(-1);
- }
- if((rv!=0) && (dlsch0_harq->round == 0) && (rnti != si_rnti) && (rnti != p_rnti) && (rnti != ra_rnti))
- {
- // DCI false detection
- return(-1);
- }
+ // extract dci infomation
+ LOG_I(PHY,"[DCI-format2A] extract dci infomation \n");
+ extract_dci2A_info(frame_parms->N_RB_DL,
+ frame_type,
+ frame_parms->nb_antenna_ports_eNB,
+ dci_pdu,
+ &dci_info_extarcted);
- // change the mcs limit from 7 to 8, supported by MAC
- /* if (mcs > 10) {
- LOG_E(PHY,"Format 1A: subframe %d unlikely mcs for format 1A (%d), TPC %d rv %d\n",subframe,mcs,TPC,rv);
- return(-1);
- }*/
-
- if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { //
- // if ((dlsch0_harq->round == 4) || ( {
- dlsch0_harq->round = 0;
- dlsch0_harq->first_tx = 1;
- // }
-
- // if (dlsch0_harq->round == 0)
- // ndi = 1-dlsch0_harq->DCINdi;
- }
-
- dlsch[0]->current_harq_pid = harq_pid;
-
- dlsch0_harq->rvidx = rv;
- dlsch0_harq->Nl = 1;
- // dlsch[0]->layer_index = 0;
-
- dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
- dlsch0_harq->dl_power_off = 1; //no power offset
-
- dlsch[0]->active = 1; // fix no DLSCH decoding for downlink retransmission
-
- if ((ndi!=dlsch0_harq->DCINdi) || // DCI has been toggled or this is the first transmission
- (dlsch0_harq->first_tx==1)) {
- dlsch0_harq->round = 0;
-
- if (dlsch0_harq->first_tx==1) {
- //LOG_I(PHY,"[PDSCH %x/%d] Format 1A DCI First TX: Clearing flag\n");
- dlsch0_harq->first_tx = 0;
- }
- } else if (dlsch0_harq->round == 0) { // duplicated PDSCH received. possibly eNB missed the previous DL ACK/NACK feedback
-
- // skip PDSCH decoding
+ // 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;
- // report ACK back to eNB for this duplicated PDSCH
- dlsch0_harq->status = SCH_IDLE;
- dlsch0_harq->round = 0;
- dlsch[0]->harq_ack[subframe].ack = 1;
+ 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,
+ 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;
- dlsch[0]->harq_ack[subframe].send_harq_status = 1;
- LOG_D(PHY,"UE (%x/%d): Format1A DCI: Duplicated PDSCH. Setting ACK for subframe %d (pid %d, round 0)\n",
- dlsch[0]->rnti,harq_pid, subframe,harq_pid);
- }
- LOG_D(PHY,"UE (%x/%d): SFN/SF %4d/%1d Format1A DCI: dai %d, ndi %d, old_ndi %d (first tx %d), harq_status %d, round %d\n",
- rnti,
- harq_pid,
- frame % 1024,
- subframe,
- dai,
- ndi,
- dlsch0_harq->DCINdi,
- dlsch0_harq->first_tx,
- dlsch0_harq->status,
- dlsch0_harq->round);
-
- if (rnti == tc_rnti) {
- dlsch0_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,dlsch0_harq->DCINdi);
- } else {
- dlsch0_harq->DCINdi = ndi;
- }
-
- dlsch[0]->harq_ack[subframe].vDAI_DL = dai+1;
- // this a retransmission
- if(dlsch0_harq->round)
- {
- // compare old TBS to new TBS
- if((mcs<29) && (dlsch0_harq->TBS != TBStable[get_I_TBS(mcs)][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");
- dlsch0_harq->round = 0;
- }
- }
-
- if(mcs<29)
- {
- dlsch0_harq->mcs = mcs;
- }
-
- if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) {
- dlsch0_harq->TBS = TBStable[mcs][NPRB-1];
- dlsch0_harq->Qm = 2;
- }
- else {
- if(mcs < 29)
- dlsch0_harq->TBS = TBStable[get_I_TBS(mcs)][NPRB-1];
- dlsch0_harq->Qm = get_Qm(mcs);
- }
- dlsch[0]->rnti = rnti;
- dlsch0 = dlsch[0];
- //printf("Format 1A: harq_pid %d, nb_rb %d, round %d\n",harq_pid,dlsch0_harq->nb_rb,dlsch0_harq->round);
- break;
-
- case format1C:
-
- harq_pid = 0;
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
- switch (frame_parms->N_RB_DL) {
- case 6:
- mcs = ((DCI1C_1_5MHz_t *)dci_pdu)->mcs;
- rballoc = conv_1C_RIV(((DCI1C_1_5MHz_t *)dci_pdu)->rballoc,6);
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc];
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc];
- RIV_max = RIV_max6;
-
- break;
-
- case 25:
- mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
- rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,25);
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc];
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc];
- RIV_max = RIV_max25;
-
- // printf("Format1C : %x : mcs %d, rballoc %d=>%d=>%x\n",((uint32_t*)dci_pdu)[0],
- // mcs,((DCI1C_5MHz_t *)dci_pdu)->rballoc,rballoc,dlsch0_harq->rb_alloc_even[0]);
- break;
-
- case 50:
- mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs;
- rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,50);
- Ngap = ((DCI1C_10MHz_t *)dci_pdu)->Ngap;
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc];
- if (Ngap == 0) {
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
- }
- else {
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc];
- }
- RIV_max = RIV_max50;
-
- break;
-
- case 100:
- mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs;
- rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,100);
- Ngap = ((DCI1C_20MHz_t *)dci_pdu)->Ngap;
- dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc];
- if (Ngap==0) {
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc];
- dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc];
- dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc];
- }
- else {
- dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc];
- dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc];
- dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc];
- dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc];
- dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc];
- dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc];
- dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc];
- }
- RIV_max = RIV_max100;
/*
- printf("Format1C : %x : mcs %d, rballoc %d=>%d=>(%08x.%08x.%08x.%08x), Ngap %d\n",((uint32_t*)dci_pdu)[0],
- mcs,((DCI1C_20MHz_t *)dci_pdu)->rballoc,rballoc,
- dlsch0_harq->rb_alloc_even[0],
- dlsch0_harq->rb_alloc_even[1],
- dlsch0_harq->rb_alloc_even[2],
- dlsch0_harq->rb_alloc_even[3],
- Ngap
- );
+ 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];
+ }
*/
- break;
-
- default:
- LOG_E(PHY,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL);
- return(-1);
- break;
- }
- if (rballoc>RIV_max) {
- LOG_E(PHY,"Format 1C: rb_alloc > RIV_max\n");
- return(-1);
- }
-
- dlsch0_harq->round = 0;
- dlsch0_harq->first_tx = 1;
- dlsch0_harq->vrb_type = DISTRIBUTED;
- dlsch[0]->current_harq_pid = harq_pid;
-
- if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321
- if (((frame&1) == 0) && (subframe == 5))
- dlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1
- else
- dlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs
- }
- else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3
- dlsch0_harq->rvidx = 0;
- }
-
-
- dlsch0_harq->Nl = 1;
- dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
- dlsch0_harq->dl_power_off = 1; //no power offset
-
- LOG_D(PHY,"UE (%x/%d): Subframe %d Format1C DCI: harq_status %d, round %d\n",
- dlsch[0]->rnti,
- harq_pid,
- subframe,
- dlsch0_harq->status,
- dlsch0_harq->round);
-
- dlsch0_harq->mcs = mcs;
-
- dlsch0_harq->TBS = TBStable1C[mcs];
- dlsch0_harq->Qm = 2;
- dlsch[0]->rnti = rnti;
- dlsch[0]->active = 1;
- dlsch0 = dlsch[0];
- break;
-
- case format1:
-
- switch (frame_parms->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;
- }
-
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
- if (harq_pid>=8) {
- LOG_E(PHY,"Format 1: harq_pid=%d >= 8\n", harq_pid);
- return(-1);
- }
-
- if((mcs>28) && (dlsch0_harq->round == 0) )
- {
- // DCI false detection
- return(-1);
- }
-
- if((rv!=0) && (dlsch0_harq->round == 0) )
- {
- // DCI false detection
- return(-1);
- }
-
-
- dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
-
- dlsch[0]->current_harq_pid = harq_pid;
- dlsch[0]->harq_ack[subframe].harq_id = harq_pid;
-
- 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];
-
- dlsch0_harq->nb_rb = conv_nprb(rah,
- rballoc,
- frame_parms->N_RB_DL);
-
- NPRB = dlsch0_harq->nb_rb;
-
- // printf("test PDSCH NPRB %d, rah %d, rballoc %x, rballoc2 %x\n",NPRB,rah,rballoc,dlsch0_harq->rb_alloc[0]);
-
- if (NPRB==0) {
- LOG_E(PHY,"Format 1: NPRB=0 (rballoc %x,mcs %d, frame_type %d N_RB_DL %d)\n",rballoc,mcs,frame_parms->frame_type,frame_parms->N_RB_DL);
- return(-1);
- }
-
-
- if (TPC!=1)
- LOG_D(PHY,"format1 TPC %d, dlsch0_harq->delta_PUCCH %d\n",TPC,dlsch0_harq->delta_PUCCH);
-
- dlsch0_harq->rvidx = rv;
-
- dlsch0_harq->Nl = 1;
- // dlsch[0]->layer_index = 0;
-
- dlsch0_harq->dl_power_off = 1; //no power offset
-
- LOG_D(PHY,"UE (%x/%d): Subframe %d Format1 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi,
- dlsch0_harq->first_tx,dlsch0_harq->status);
-
- if ((ndi!=dlsch0_harq->DCINdi)||
- (dlsch0_harq->first_tx==1)) {
- // printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx);
- dlsch0_harq->round=0;
- dlsch0_harq->status = ACTIVE;
- dlsch0_harq->DCINdi = ndi;
-
- dlsch[0]->harq_ack[subframe].send_harq_status = 1;
- if (dlsch0_harq->first_tx==1) {
- LOG_D(PHY,"[PDSCH %x/%d] Format 1 DCI First TX: Clearing flag\n",rnti,harq_pid);
- dlsch0_harq->first_tx = 0;
- }
- }
-
- dlsch0_harq->mcs = mcs;
-
- // this a retransmission
- if(dlsch0_harq->round)
- {
- // compare old TBS to new TBS
- if(dlsch0_harq->TBS != TBStable[get_I_TBS(mcs)][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,"Format1 Retransmission but TBS are different: consider it as new transmission !!! \n");
- dlsch0_harq->round = 0;
- }
- }
-
- dlsch0_harq->TBS = TBStable[get_I_TBS(mcs)][NPRB-1];
- if (mcs <= 28)
- dlsch0_harq->Qm = get_Qm(mcs);
- else if (mcs<=31)
- dlsch0_harq->Qm = (mcs-28)<<1;
- else
- LOG_E(PHY,"invalid mcs %d\n",mcs);
- // printf("test: MCS %d, NPRB %d, TBS %d\n",mcs,NPRB,dlsch0_harq->TBS);
- dlsch[0]->current_harq_pid = harq_pid;
-
- dlsch[0]->active = 1;
-
- dlsch[0]->rnti = rnti;
-
- if (beamforming_mode == 0)
- dlsch0_harq->mimo_mode = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
- else if (beamforming_mode == 7)
- dlsch0_harq->mimo_mode = TM7;
- else
- LOG_E(PHY,"Not supported beamforming mode %d\n",beamforming_mode);
-
-
- dlsch0 = dlsch[0];
-
- break;
-
- case format2:
- switch (frame_parms->N_RB_DL) {
-
- case 6:
- if (frame_parms->nb_antenna_ports_eNB == 2) {
- if (frame_type == TDD) {
- mcs1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
- mcs2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
- rballoc = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
- rv1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
- rv2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
- harq_pid = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
- tbswap = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
- tpmi = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
- } else {
- mcs1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
- mcs2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
- rballoc = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
- rv1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
- rv2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
- harq_pid = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
- tbswap = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
- tpmi = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
- }
- } else if (frame_parms->nb_antenna_ports_eNB == 4) {
- if (frame_type == TDD) {
- mcs1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
- mcs2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
- rballoc = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
- rv1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
- rv2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
- harq_pid = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
- tbswap = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
- tpmi = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
- } else {
- mcs1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
- mcs2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
- rballoc = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
- rv1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
- rv2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
- harq_pid = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
- tbswap = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
- tpmi = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
- }
- } else {
- LOG_E(PHY,"UE: subframe %d Format2 DCI: unsupported number of TX antennas %d\n",subframe,frame_parms->nb_antenna_ports_eNB);
- }
-
- break;
-
- case 25:
- if (frame_parms->nb_antenna_ports_eNB == 2) {
- if (frame_type == TDD) {
- 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;
- rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
- 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;
- } else {
- 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;
- rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
- 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;
- }
- } else if (frame_parms->nb_antenna_ports_eNB == 4) {
- if (frame_type == TDD) {
- 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;
- rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
- 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;
- } else {
- 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;
- rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
- 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;
- }
- } else {
- LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB);
- }
-
- break;
-
- case 50:
- if (frame_parms->nb_antenna_ports_eNB == 2) {
- if (frame_type == TDD) {
- 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;
- rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah;
- 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;
- } else {
- 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;
- rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah;
- 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;
- }
- } else if (frame_parms->nb_antenna_ports_eNB == 4) {
- if (frame_type == TDD) {
- 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;
- rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah;
- 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;
- } else {
- 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;
- rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah;
- 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;
- }
- } else {
- LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB);
- }
-
- break;
-
- case 100:
- if (frame_parms->nb_antenna_ports_eNB == 2) {
- if (frame_type == TDD) {
- 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;
- rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah;
- 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;
- } else {
- 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;
- rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah;
- 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;
- }
- } else if (frame_parms->nb_antenna_ports_eNB == 4) {
- if (frame_type == TDD) {
- 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;
- rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah;
- 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;
- } else {
- 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;
- rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah;
- 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;
- }
- } else {
- LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB);
- }
-
- break;
- }
-
- if (harq_pid>=8) {
- LOG_E(PHY,"Format 2_2A: 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 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-
- if (tbswap == 0) {
dlsch0 = dlsch[0];
- dlsch1 = dlsch[1];
- } else {
- dlsch0 = dlsch[1];
- dlsch1 = dlsch[0];
- }
- dlsch0_harq = dlsch0->harq_processes[harq_pid];
- dlsch1_harq = dlsch1->harq_processes[harq_pid];
- conv_rballoc(rah,
- rballoc,
- frame_parms->N_RB_DL,
- dlsch0_harq->rb_alloc_even);
+ 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];
+ 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;
- 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];
-
- dlsch0_harq->nb_rb = conv_nprb(rah,
- rballoc,
- frame_parms->N_RB_DL);
- dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
-
- dlsch0_harq->mcs = mcs1;
-
- dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[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 = mcs2;
- dlsch0_harq->rvidx = rv1;
- dlsch1_harq->rvidx = 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;
-
- 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);
- break;
-
- case 2:
- dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1);
- break;
-
- case 3:
- dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2);
- break;
-
- case 4:
- dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3);
- 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;
- }
+ 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 (frame_parms->mode1_flag == 1)
- dlsch0_harq->mimo_mode = SISO;
- if (ndi1!=dlsch0_harq->DCINdi) {
- dlsch0_harq->round = 0;
- dlsch0_harq->status = ACTIVE;
- dlsch0_harq->DCINdi = ndi1;
- } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 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->mcs = mcs1;
-
- if (dlsch0_harq->nb_rb>1) {
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
- if (mcs1 <= 28)
- dlsch0_harq->Qm = get_Qm(mcs1);
- else if (mcs1<=31)
- dlsch0_harq->Qm = (mcs1-28)<<1;
- else
- LOG_E(PHY,"invalid mcs1 %d\n",mcs1);
-
- } else
- dlsch0_harq->TBS =0;
-
-
- /*
- if (dlsch0_harq->mcs > 18)
- printf("mcs %d, TBS %d\n",dlsch0_harq->mcs,dlsch0_harq->TBS);
- */
-
- if (dlsch1_harq->DCINdi != ndi2) {
- dlsch1_harq->round=0;
- dlsch1_harq->status = ACTIVE;
- }
-
- dlsch1_harq->DCINdi = ndi2;
- dlsch1_harq->mcs = mcs2;
-
- if (dlsch1_harq->nb_rb>1) {
- dlsch1_harq->TBS = TBStable[dlsch1_harq->mcs][dlsch1_harq->nb_rb-1];
- if (mcs2 <= 28)
- dlsch1_harq->Qm = get_Qm(mcs2);
- else if (mcs1<=31)
- dlsch1_harq->Qm = (mcs2-28)<<1;
- else
- LOG_E(PHY,"invalid mcs2 %d\n",mcs2);
- } else
- dlsch1_harq->TBS = 0;
-
-
- dlsch0->rnti = rnti;
- dlsch1->rnti = rnti;
-
- dlsch0_harq->dl_power_off = 0; //no power offset
- dlsch1_harq->dl_power_off = 0; //no power offset
-
- dlsch0->active = 1;
- dlsch1->active = 1;
-
- break;
-
- case format2A:
-
- switch (frame_parms->N_RB_DL) {
-
- case 6:
- if (frame_parms->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;
- } 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;
+ /*
+ if (dlsch0_harq->mcs>20) {
+ printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs);
+ return(-1);
}
- } else if (frame_parms->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;
- } 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;
- }
- } else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+ */
+
+ //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;
}
- break;
+ //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
+ //dlsch1_harq->status = DISABLED;
+ //}
+ dlsch0_harq->Nl = 1;
- case 25:
- if (frame_parms->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;
- } 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;
- }
- } else if (frame_parms->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;
- } 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;
- }
- } else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+ //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;
}
- break;
- case 50:
- if (frame_parms->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;
- } 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;
- }
- } else if (frame_parms->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;
- } 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;
- }
- } else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
- }
-
- break;
-
- case 100:
- if (frame_parms->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;
- } 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;
- }
- } else if (frame_parms->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;
- } 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;
- }
- } else {
- LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
- }
-
- break;
- }
+ if (frame_parms->mode1_flag == 1)
+ dlsch0_harq->mimo_mode = SISO;
- if (harq_pid>=8) {
- LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
- return(-1);
- }
+ if (dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) {
- // printf("UE: format 2A, rballoc=%x, harq_pid= %d, mcs1=%d,mcs2=%d, rv1=%d, rv2=%d, ndi1=%d, ndi2=%d\n",rballoc, harq_pid, mcs1,mcs2,rv1,rv2,ndi1,ndi2);
-
- // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
- // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated
- if (tbswap == 0) {
- dlsch0 = dlsch[0];
- dlsch1 = dlsch[1];
- } else {
- dlsch0 = dlsch[1];
- dlsch1 = dlsch[0];
- }
-
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
- dlsch0->current_harq_pid = harq_pid;
- dlsch1->current_harq_pid = harq_pid;
- dlsch0->harq_ack[subframe].harq_id = harq_pid;
- dlsch1->harq_ack[subframe].harq_id = harq_pid;
-
- 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];
- 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];
-
- dlsch0_harq->nb_rb = conv_nprb(rah,
- rballoc,
- frame_parms->N_RB_DL);
-
- dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
-
- NPRB = dlsch0_harq->nb_rb;
-
-
- if (NPRB==0) {
- LOG_E(PHY,"Format 2A: NPRB=0 (rballoc %x,mcs %d, frame_type %d N_RB_DL %d)\n",rballoc,mcs,frame_parms->frame_type,frame_parms->N_RB_DL);
- return(-1);
- }
-
- // printf("NPRB %d\n",NPRB);
- dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
- dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
-
- dlsch0_harq->mcs = mcs1;
- dlsch1_harq->mcs = mcs2;
-
- dlsch0_harq->rvidx = rv1;
- dlsch1_harq->rvidx = rv2;
-
-
-
- dlsch0_harq->Nl = 1;
- dlsch1_harq->Nl = 1;
- // dlsch[0]->layer_index = 0;
-
- dlsch0_harq->dl_power_off = 1; //no power offset
- dlsch1_harq->dl_power_off = 1; //no power offset
-
- dlsch0->active = dlsch1->active = 1;
-
- // check if either TB is disabled (see 36-213 V11.3 Section )
- if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
- dlsch0->active = 0;
- }
-
- if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
- dlsch1->active = 0;
- }
-
-
- // printf("Format2A DCI (UE, hard pid %d): ndi %d, old_ndi %d (first tx %d)\n",harq_pid,ndi,dlsch0_harq->DCINdi,
- // dlsch0_harq->first_tx);
-
- if (dlsch0->active == 1) {
- if ((ndi1!=dlsch0_harq->DCINdi)||
- (dlsch0_harq->first_tx==1)) {
- // printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx);
- dlsch0_harq->round=0;
+ dlsch0_harq->round = 0;
dlsch0_harq->status = ACTIVE;
- dlsch0_harq->DCINdi = ndi1;
-
- if (dlsch0_harq->first_tx==1) {
- LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX0: Clearing flag\n",rnti,harq_pid);
- dlsch0_harq->first_tx = 0;
- }
} else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process,
// this happens if either another harq process in the same
// is NAK or an ACK was not received
@@ -5299,360 +6288,81 @@ int generate_ue_dlsch_params_from_dci(int frame,
dlsch0->harq_ack[subframe].harq_id = harq_pid;
dlsch0->harq_ack[subframe].send_harq_status = 1;
dlsch0->active = 0;
- // printf("Got NDI=0 for correctly decoded SDU (harq_pid %d) subframe %d\n",harq_pid,subframe);
+ return(0);
}
- }
- if (dlsch1->active == 1) {
- if ((ndi2!=dlsch1_harq->DCINdi)||
- (dlsch1_harq->first_tx==1)) {
- dlsch1_harq->round=0;
- dlsch1_harq->status = ACTIVE;
- dlsch1_harq->DCINdi = ndi2;
+ 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 (dlsch1_harq->first_tx==1) {
- LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX1: Clearing flag\n",rnti,harq_pid);
- dlsch1_harq->first_tx = 0;
- }
+ 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;
- } else if (dlsch1_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process,
- // this happens if either another harq process in the same
- // is NAK or an ACK was not received
+ dlsch0->rnti = rnti;
+ //dlsch1->rnti = rnti;
- dlsch1->harq_ack[subframe].ack = 1;
- dlsch1->harq_ack[subframe].harq_id = harq_pid;
- dlsch1->harq_ack[subframe].send_harq_status = 1;
- dlsch1->active = 0;
- // printf("Got NDI=0 for correctly decoded SDU (harq_pid %d) subframe %d\n",harq_pid,subframe);
- }
- }
+ dlsch0->active = 1;
+ //dlsch1->active = 1;
- if (frame_parms->nb_antenna_ports_eNB == 2) {
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-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;
-
- if ((dlsch0->active==1) && (dlsch1->active==1)) {
- dlsch0_harq->mimo_mode = LARGE_CDD;
- dlsch1_harq->mimo_mode = LARGE_CDD;
- dlsch0_harq->dl_power_off = 0; //apply power offset
- dlsch1_harq->dl_power_off = 0; //apply power offset
- } else {
- dlsch0_harq->mimo_mode = ALAMOUTI;
- dlsch1_harq->mimo_mode = ALAMOUTI;
- }
- } else if (frame_parms->nb_antenna_ports_eNB == 4) { // 4 antenna case
- if ((dlsch0->active==1) && (dlsch1->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 = 0; //apply power offset
- dlsch1_harq->dl_power_off = 0; //apply power offset
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-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;
- dlsch0_harq->dl_power_off = 0; //apply power offset
- dlsch1_harq->dl_power_off = 0; //apply power offset
- dlsch1_harq->Nl = 2;
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-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 = 0; //apply power offset
- dlsch1_harq->dl_power_off = 0; //apply power offset
-
- if (frame_parms->N_RB_DL <= 56) {
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
- } else {
- LOG_E(PHY,"Add implementation of Table 7.1.7.2.2-1 for two-layer TBS conversion with N_RB_DL > 56\n");
- }
-
- break;
-
- case 3: //
- LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
- break;
- }
- } else if (dlsch0->active == 1) {
- switch (tpmi) {
- case 0: // one layer per transport block
- dlsch0_harq->mimo_mode = ALAMOUTI;
- dlsch1_harq->mimo_mode = ALAMOUTI;
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
- break;
-
- case 1: // two-layers on TB 0
- dlsch0_harq->mimo_mode = LARGE_CDD;
- dlsch0_harq->Nl = 2;
- dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-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 (dlsch1->active == 1) {
- switch (tpmi) {
- case 0: // one layer per transport block
- dlsch0_harq->mimo_mode = ALAMOUTI;
- dlsch1_harq->mimo_mode = ALAMOUTI;
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
- break;
-
- case 1: // two-layers on TB 0
- dlsch1_harq->mimo_mode = LARGE_CDD;
- dlsch1_harq->Nl = 2;
- dlsch0_harq->dl_power_off = 1; //apply power offset
- dlsch1_harq->dl_power_off = 0; //apply power offset
- dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-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 {
- LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antenna_ports_eNB);
- }
-
- if (mcs1 <= 28)
- dlsch0_harq->Qm = get_Qm(mcs1);
- else if (mcs1<=31)
- dlsch0_harq->Qm = (mcs1-28)<<1;
- else
- LOG_E(PHY,"invalid mcs1 %d\n",mcs1);
-
- if (mcs2 <= 28)
- dlsch1_harq->Qm = get_Qm(mcs2);
- else if (mcs2<=31)
- dlsch1_harq->Qm = (mcs2-28)<<1;
- else
- LOG_E(PHY,"invalid mcs2 %d\n",mcs2);
-
- // 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);
-
-
- break;
-
- case format1E_2A_M10PRB:
-
- 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];
- 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);
- break;
-
- case 2:
- dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1);
- break;
-
- case 3:
- dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2);
- break;
-
- case 4:
- dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj;
- dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3);
- 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");
+ default:
+ LOG_E(PHY,"format %d not yet implemented\n",dci_format);
return(-1);
break;
}
- if (frame_parms->mode1_flag == 1)
- dlsch0_harq->mimo_mode = SISO;
+ #ifdef DEBUG_DCI
-
- if (dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) {
-
- dlsch0_harq->round = 0;
- dlsch0_harq->status = ACTIVE;
- } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 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);
+ if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
+ printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe);
+ printf("PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti);
+ printf("PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb);
+ printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]);
+ printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid);
+ printf("PDSCH dlsch0 UE: tpc %d\n",TPC);
+ printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch);
+ printf("PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round);
+ printf("PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi);
+ printf("PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx);
+ printf("PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS);
+ printf("PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs);
+ printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off);
}
- dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
- dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
+ #endif
- 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;
+ #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(0),
+ T_INT(dlsch[0]->rnti), T_INT(dci_format),
+ T_INT(harq_pid),
+ T_INT(dlsch0_harq->mcs),
+ T_INT(dlsch0_harq->TBS));
+ }
+ #endif
- break;
+ // 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);
+ }
- default:
- LOG_E(PHY,"format %d not yet implemented\n",dci_format);
- return(-1);
- break;
- }
+ 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);
+ }
-#ifdef DEBUG_DCI
-
- if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
- printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe);
- printf("PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti);
- printf("PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb);
- printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]);
- printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid);
- printf("PDSCH dlsch0 UE: tpc %d\n",TPC);
- printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch);
- printf("PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round);
- printf("PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi);
- printf("PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx);
- printf("PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS);
- printf("PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs);
- printf("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(0),
- 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
- computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off);
-
- computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
-
- return(0);
+ return(0);
}
@@ -5816,14 +6526,79 @@ uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, ui
}
-uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands)
+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;
- uint16_t pmivect = 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; i1 not supported!\n");
+ }
+
+ else if (rank==1) {
+ for (aarx=0; aarxnb_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);
}
@@ -6294,14 +7093,32 @@ void reset_cba_uci(void *o)
((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = 0x0;
}
-uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi)
+
+uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank)
{
- uint8_t i,wideband_pmi2=wideband_pmi&3;
+ uint8_t i,wideband_pmi2;
uint32_t pmi_ex = 0;
- for (i=0; i<14; i+=2)
- pmi_ex|=(wideband_pmi2<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<n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
#ifdef DEBUG_DCI
+
printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe);
printf("Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
printf("Format 0 DCI :ulsch (ue): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb);
@@ -7236,8 +8054,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
}
int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
- eNB_rxtx_proc_t *proc,
- void *dci_pdu,
+ eNB_rxtx_proc_t *proc,
+ void *dci_pdu,
uint16_t rnti,
DCI_format_t dci_format,
uint8_t UE_id,
@@ -7275,11 +8093,9 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
harq_pid = subframe2harq_pid(frame_parms,
pdcch_alloc2ul_frame(frame_parms,
- proc->frame_tx,
- subframe),
+ proc->frame_tx,
+ subframe),
pdcch_alloc2ul_subframe(frame_parms,subframe));
-
-
switch (frame_parms->N_RB_DL) {
case 6:
if (frame_parms->frame_type == TDD) {
@@ -7395,8 +8211,8 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
rb_alloc = rballoc;
if (rb_alloc>RIV_max) {
- LOG_E(PHY,"Format 0: rb_alloc > RIV_max\n");
- mac_xface->macphy_exit("Format 0: rb_alloc > RIV_max\n");
+ LOG_E(PHY,"Format 0: rb_alloc (%d) > RIV_max (%d)\n",rb_alloc,RIV_max);
+ mac_xface->macphy_exit("Format 0: error");
return(-1);
}
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
old mode 100644
new mode 100755
index 8e17697ff4..3b13c01c52
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -79,11 +79,17 @@
#if !defined(C_RNTI)
#define C_RNTI (rnti_t)0x1234
#endif
-
-#define PMI_2A_11 0
+// 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_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 {
SCH_IDLE,
@@ -158,6 +164,8 @@ typedef struct {
uint8_t Nlayers;
/// First layer for this PSCH transmission
uint8_t first_layer;
+ /// codeword this transport block is mapped to
+ uint8_t codeword;
} LTE_DL_eNB_HARQ_t;
typedef struct {
@@ -584,6 +592,8 @@ typedef struct {
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 {
@@ -754,6 +764,13 @@ typedef enum {
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 {
pucch_format1=0,
pucch_format1a,
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 8ec2a40d8d..90f8242cc8 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -40,6 +40,8 @@
#include "SCHED/defs.h"
#include "defs.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
+#include "UTIL/LOG/log.h"
+#include
//#define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1
@@ -85,11 +87,11 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
#endif
for (r=0; rharq_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;
@@ -98,17 +100,17 @@ 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)
@@ -148,7 +150,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
for (layer=0; layer<4; layer++) {
dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
-
+
for (aa=0; aanb_antennas_tx; aa++) {
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
for (re=0;recalib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
for (aa=0; aanb_antennas_tx; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
-
+
}
for (i=0; i<10; i++)
@@ -207,7 +209,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
exit_flag=3;
}
}
-
+
if (exit_flag==0) {
for (i=0; iharq_processes[i]->round=0;
@@ -218,7 +220,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
if (dlsch->harq_processes[i]->d[r])
dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
}
-
+
}
return(dlsch);
@@ -257,7 +259,7 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
for (r=0; rharq_processes[i]->d[r])
dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
-
+
}
}
}
@@ -347,12 +349,14 @@ int dlsch_encoding_2threads0(te_params *tep) {
extern int oai_exit;
void *te_thread(void *param) {
+ pthread_setname_np( pthread_self(),"te processing");
+ LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid));
eNB_proc_t *proc = &((te_params *)param)->eNB->proc;
while (!oai_exit) {
- if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break;
+ if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break;
dlsch_encoding_2threads0((te_params*)param);
@@ -432,14 +436,14 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
return(-1);
}
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
+ 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;
- // wakeup worker to do second half segments
+ // 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" );
@@ -497,8 +501,8 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
proc->tep.eNB = eNB;
proc->tep.dlsch = dlsch;
proc->tep.G = G;
-
- // wakeup worker to do second half segments
+
+ // 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" );
@@ -545,9 +549,9 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
// wait for worker to finish
- wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread");
+ wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread");
+
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
@@ -729,6 +733,186 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
return(0);
}
+
+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 = dlsch->current_harq_pid;
+ 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 = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
+
+ 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
+
+ /*
+ 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; rharq_processes[harq_pid]->C; r++) {
+
+ if (rharq_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; rharq_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);
+ 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,
+ get_Qm(dlsch->harq_processes[harq_pid]->mcs),
+ 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);
+}
+
+
+
+
#ifdef PHY_ABSTRACTION
void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
uint8_t *DLSCH_pdu,
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index 9629502cec..04794e3ffc 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
@@ -37,7 +37,7 @@
#include "SCHED/extern.h"
#include "SIMULATION/TOOLS/defs.h"
//#define DEBUG_DLSCH_DECODING
-
+
void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch)
{
@@ -343,7 +343,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
for (r=0; rC; r++) {
-
+
// Get Turbo interleaver parameters
if (rCminus)
Kr = harq_process->Kminus;
@@ -387,7 +387,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
harq_process->round);
#endif
-
+//printf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
if (lte_rate_matching_turbo_rx(harq_process->RTC[r],
G,
harq_process->w[r],
@@ -486,7 +486,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
stop_meas(dlsch_turbo_decoding_stats);
}
#else
- if ((harq_process->C == 1) ||
+ if ((harq_process->C == 1) ||
((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments
start_meas(dlsch_turbo_decoding_stats);
@@ -518,7 +518,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
}
else {
skipped_last=0;
-
+
if (Kr_last == Kr) { // decode 2 code segments with AVX2 version
#ifdef DEBUG_DLSCH_DECODING
printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]);
@@ -565,7 +565,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
exit(-1);*/
stop_meas(dlsch_turbo_decoding_stats);
- }
+ }
else { // Kr_last != Kr
start_meas(dlsch_turbo_decoding_stats);
ret = tc
@@ -585,7 +585,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
stop_meas(dlsch_turbo_decoding_stats);
-
+
start_meas(dlsch_turbo_decoding_stats);
ret = tc
(&harq_process->d[r][96],
@@ -604,7 +604,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
stop_meas(dlsch_turbo_decoding_stats);
-
+
}
}
}
@@ -747,7 +747,7 @@ int dlsch_abstraction_EESM(double* sinr_dB, uint8_t TM, uint32_t rb_alloc[4], ui
bler = interp(sinr_eff,&sinr_bler_map[mcs][0][0],&sinr_bler_map[mcs][1][0],table_length[mcs]);
-#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
+#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) {
LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM);
@@ -830,7 +830,7 @@ int dlsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint32_t rb_alloc[4], ui
bler = interp(sinr_eff,&sinr_bler_map[mcs][0][0],&sinr_bler_map[mcs][1][0],table_length[mcs]);
-#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
+#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) {
LOG_N(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
index 7d14e8aca7..601eacc620 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -29,8 +29,7 @@
* \note
* \warning
*/
-
-#include "PHY/defs.h"
+//#include "PHY/defs.h"
#include "PHY/extern.h"
#include "defs.h"
#include "extern.h"
@@ -43,13 +42,29 @@
#define NOCYGWIN_STATIC
#endif
+//#define DEBUG_HARQ
+
+//#undef LOG_D
+//#define LOG_D LOG_I
+
//#define DEBUG_PHY 1
//#define DEBUG_DLSCH_DEMOD 1
-int avg[4];
+int avg[4];
+int avg_0[2];
+int avg_1[2];
// [MCS][i_mod (0,1,2) = (2,4,6)]
unsigned char offset_mumimo_llr_drange_fix=0;
+uint8_t interf_unaw_shift0=0;
+uint8_t interf_unaw_shift1=0;
+uint8_t interf_unaw_shift=0;
+//inferference-free case
+unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
+ 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
+unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1,
+ 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous
+
/*
//original values from sebastion + same hand tuning
unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{6,6,6},{6,6,6},{6,6,6},{5,5,5},{4,4,4},{1,2,4}, // QPSK
@@ -78,7 +93,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
uint8_t subframe,
unsigned char symbol,
unsigned char first_symbol_flag,
- unsigned char dual_stream_flag,
+ RX_type_t rx_type,
unsigned char i_mod,
unsigned char harq_pid)
{
@@ -86,37 +101,72 @@ int rx_pdsch(PHY_VARS_UE *ue,
LTE_UE_COMMON *common_vars = &ue->common_vars;
LTE_UE_PDSCH **pdsch_vars;
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
- PHY_MEASUREMENTS *phy_measurements = &ue->measurements;
+ PHY_MEASUREMENTS *measurements = &ue->measurements;
LTE_UE_DLSCH_t **dlsch;
+
unsigned char aatx,aarx;
- unsigned short nb_rb=0;
+
+ unsigned short nb_rb = 0, round;
int avgs, rb;
LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
-
+
uint8_t beamforming_mode;
uint32_t *rballoc;
+ int32_t **rxdataF_comp_ptr;
+ int32_t **dl_ch_mag_ptr;
+ int32_t codeword_TB0;
+ int32_t codeword_TB1;
+
+
+
switch (type) {
case SI_PDSCH:
pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
- dlsch = &ue->dlsch_SI[eNB_id];
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+ dlsch = &ue->dlsch_SI[eNB_id];
+ dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
beamforming_mode = 0;
break;
case RA_PDSCH:
pdsch_vars = &ue->pdsch_vars_ra[eNB_id];
- dlsch = &ue->dlsch_ra[eNB_id];
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+ dlsch = &ue->dlsch_ra[eNB_id];
+ dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
beamforming_mode = 0;
break;
case PDSCH:
pdsch_vars = &ue->pdsch_vars[subframe&0x1][eNB_id];
- dlsch = ue->dlsch[eNB_id];
- dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
+ dlsch = ue->dlsch[eNB_id];
+ if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
+ (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)){
+ codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
+ codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
+ dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
+ dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
+#ifdef DEBUG_HARQ
+ printf("I am assuming both CW active\n");
+#endif
+ }
+ else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
+ (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) {
+ codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
+ dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+ dlsch1_harq = NULL;
+ codeword_TB1 = -1;
+ }
+ else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) &&
+ (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){
+ codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
+ dlsch0_harq = dlsch[1]->harq_processes[harq_pid];
+ dlsch1_harq = NULL;
+ codeword_TB0 = -1;
+ }
+ else {
+ LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe);
+ return(-1);
+ }
beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
break;
@@ -125,7 +175,13 @@ int rx_pdsch(PHY_VARS_UE *ue,
return(-1);
break;
}
+#ifdef DEBUG_HARQ
+ printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
+ printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
+#endif
+ DevAssert(dlsch0_harq);
+ round = dlsch0_harq->round;
if (eNB_id > 2) {
LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id);
@@ -138,7 +194,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
}
if (!dlsch[0]) {
- LOG_W(PHY,"dlsch_demodulation.c: Null dlsch pointer\n");
+ LOG_W(PHY,"dlsch_demodulation.c: Null dlsch_ue pointer\n");
return(-1);
}
@@ -152,17 +208,33 @@ int rx_pdsch(PHY_VARS_UE *ue,
return(-1);
}
-
if (((frame_parms->Ncp == NORMAL) && (symbol>=7)) ||
((frame_parms->Ncp == EXTENDED) && (symbol>=6)))
rballoc = dlsch0_harq->rb_alloc_odd;
else
rballoc = dlsch0_harq->rb_alloc_even;
+
+ if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) {
+ LOG_E(PHY,"This transmission mode is not yet supported!\n");
+ return(-1);
+ }
+
+
+
+ if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING))) {
+ DevAssert(dlsch1_harq);
+ if (eNB_id!=eNB_id_i) {
+ LOG_E(PHY,"TM3/TM4 requires to set eNB_id==eNB_id_i!\n");
+ return(-1);
+ }
+ }
+
if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) {
#ifdef DEBUG_DLSCH_MOD
LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]);
#endif
+
nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
pdsch_vars[eNB_id]->rxdataF_ext,
@@ -173,11 +245,18 @@ int rx_pdsch(PHY_VARS_UE *ue,
symbol,
subframe,
ue->high_speed_flag,
- frame_parms);
+ frame_parms,
+ dlsch0_harq->mimo_mode);
+//#ifdef DEBUG_DLSCH_MOD
+ /* printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc);
+ for (rb=0;rbpmi_ext[rb]);
+ printf("\n");*/
+//#endif
- if (dual_stream_flag==1) {
- if (eNB_id_in_connected_eNB)
- nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
+ if (rx_type >= rx_IC_single_stream) {
+ if (eNB_id_in_connected_eNB) // we are in TM5
+ nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
pdsch_vars[eNB_id_i]->rxdataF_ext,
pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
@@ -187,7 +266,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
symbol,
subframe,
ue->high_speed_flag,
- frame_parms);
+ frame_parms,
+ dlsch0_harq->mimo_mode);
else
nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
@@ -199,7 +279,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
symbol,
subframe,
ue->high_speed_flag,
- frame_parms);
+ frame_parms,
+ dlsch0_harq->mimo_mode);
}
} else if (beamforming_mode==0) { //else if nb_antennas_ports_eNB==1 && beamforming_mode == 0
nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
@@ -214,8 +295,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
ue->high_speed_flag,
frame_parms);
- if (dual_stream_flag==1) {
- if (eNB_id_in_connected_eNB)
+ if (rx_type==rx_IC_single_stream) {
+ if (eNB_id_in_connected_eNB)
nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
pdsch_vars[eNB_id_i]->rxdataF_ext,
@@ -227,7 +308,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
subframe,
ue->high_speed_flag,
frame_parms);
-
+ else
nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
pdsch_vars[eNB_id_i]->rxdataF_ext,
@@ -237,7 +318,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
rballoc,
symbol,
subframe,
- ue->high_speed_flag,
+ ue->high_speed_flag,
frame_parms);
}
} else if (beamforming_mode==7) { //else if beamforming_mode == 7
@@ -245,14 +326,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_bf_ch_estimates,
pdsch_vars[eNB_id]->rxdataF_ext,
pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
- rballoc,
+ rballoc,
symbol,
subframe,
ue->high_speed_flag,
frame_parms);
-
+
} else if(beamforming_mode>7) {
- LOG_W(PHY,"dlsch_demodulation:beamforming mode not supported yet.\n");
+ LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
}
// printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id);
@@ -261,42 +342,116 @@ int rx_pdsch(PHY_VARS_UE *ue,
return(-1);
}
- /*
- // DL power control: Scaling of Channel estimates for PDSCH
- dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
- frame_parms,
- dlsch,
- symbol,
- nb_rb);
- */
- if (first_symbol_flag==1) {
- if (beamforming_mode==0)
- dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
- frame_parms,
- avg,
- symbol,
- nb_rb);
- else if (beamforming_mode==7)
- dlsch_channel_level_TM7(pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
- frame_parms,
- avg,
- symbol,
- nb_rb);
-
+
#ifdef DEBUG_PHY
- LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
+ LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
+ LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
#endif
- // the channel gain should be the effective gain of precoding + channel
- // however lets be more conservative and set maxh = nb_tx*nb_rx*max(h_i)
- // in case of precoding we add an additional factor of two for the precoding gain
- avgs = 0;
+ aatx = frame_parms->nb_antenna_ports_eNB;
+ aarx = frame_parms->nb_antennas_rx;
- for (aatx=0; aatxnb_antenna_ports_eNB; aatx++)
- for (aarx=0; aarxnb_antennas_rx; aarx++)
- avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+ dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+ frame_parms,
+ dlsch,
+ symbol,
+ nb_rb);
- // avgs = cmax(avgs,avg[(aarx<<1)+aatx]);
+ if ((dlsch0_harq->mimo_moden_connected_eNB) && (dlsch0_harq->dl_power_off==0)) // TM5 two-user
+ dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
+ frame_parms,
+ dlsch,
+ symbol,
+ nb_rb);
+
+ if (first_symbol_flag==1) {
+ if (beamforming_mode==0){
+ if (dlsch0_harq->mimo_modedl_ch_estimates_ext,
+ frame_parms,
+ avg,
+ symbol,
+ nb_rb);
+ avgs = 0;
+ for (aatx=0;aatxnb_antenna_ports_eNB;aatx++)
+ for (aarx=0;aarxnb_antennas_rx;aarx++)
+ avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+
+ pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1;
+ }
+ else if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
+ ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+ (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING)))
+ {
+ dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+ frame_parms,
+ pdsch_vars[eNB_id]->pmi_ext,
+ avg_0,
+ avg_1,
+ symbol,
+ nb_rb,
+ dlsch0_harq->mimo_mode);
+
+ if (rx_type>rx_standard) {
+ avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift;
+ avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift;
+ pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
+ pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
+ //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0);
+ //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
+ }
+ else {
+ avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift;
+ avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift;
+ pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
+ pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
+ //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0);
+ //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
+ }
+ }
+ else if (dlsch0_harq->mimo_moden_connected_eNB) && (dlsch0_harq->dl_power_off==0)) {
+ dlsch_channel_level_TM56(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+ frame_parms,
+ pdsch_vars[eNB_id]->pmi_ext,
+ avg,
+ symbol,
+ nb_rb);
+ avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1];
+ pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0);
+
+ }
+ else if (dlsch0_harq->dl_power_off==1) { //TM6
+
+ dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+ frame_parms,
+ avg,
+ symbol,
+ nb_rb);
+
+ avgs = 0;
+ for (aatx=0;aatxnb_antenna_ports_eNB;aatx++)
+ for (aarx=0;aarxnb_antennas_rx;aarx++)
+ avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+
+ pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
+ pdsch_vars[eNB_id]->log2_maxh++;
+
+ }
+ }
+
+ }
+ else if (beamforming_mode==7)
+ dlsch_channel_level_TM7(pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
+ frame_parms,
+ avg,
+ symbol,
+ nb_rb);
+#ifdef DEBUG_PHY
+ LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
+ LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
+#endif
+ }
#if T_TRACER
if (type == PDSCH)
@@ -306,40 +461,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
}
#endif
- pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1;
- // + log2_approx(frame_parms->nb_antenna_ports_eNB-1) //-1 because log2_approx counts the number of bits
- // + log2_approx(frame_parms->nb_antennas_rx-1);
-
- if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) &&
- (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) &&
- (dlsch0_harq->dl_power_off==1)) // we are in TM 6
- pdsch_vars[eNB_id]->log2_maxh++;
-
- // this version here applies the factor .5 also to the extra terms. however, it does not work so well as the one above
- /* K = Nb_rx in TM1
- Nb_tx*Nb_rx in TM2,4,5
- Nb_tx^2*Nb_rx in TM6 */
- /*
- K = frame_parms->nb_antennas_rx*frame_parms->nb_antenna_ports_eNB; //that also covers TM1 since Nb_tx=1
- if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) &&
- (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) &&
- (dlsch0_harq->dl_power_off==1)) // we are in TM 6
- K *= frame_parms->nb_antenna_ports_eNB;
-
- pdsch_vars[eNB_id]->log2_maxh = (log2_approx(K*avgs)/2);
- */
-
-#ifdef DEBUG_PHY
- LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
- LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
-#endif
- }
-
- aatx = frame_parms->nb_antenna_ports_eNB;
- aarx = frame_parms->nb_antennas_rx;
-
- if (dlsch0_harq->mimo_modemimo_moderxdataF_ext,
pdsch_vars[eNB_id]->dl_ch_estimates_ext,
pdsch_vars[eNB_id]->dl_ch_mag0,
@@ -352,18 +475,13 @@ int rx_pdsch(PHY_VARS_UE *ue,
dlsch0_harq->Qm,
nb_rb,
pdsch_vars[eNB_id]->log2_maxh,
- phy_measurements); // log2_maxh+I0_shift
-#ifdef DEBUG_PHY
-
- if (symbol==5)
- write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
-
-#endif
-
- if ((dual_stream_flag==1) &&
+ measurements); // log2_maxh+I0_shift
+ /*if (symbol == 5) {
+ write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+ } */
+ if ((rx_type==rx_IC_single_stream) &&
(eNB_id_in_connected_eNB)) {
- // get MF output for interfering stream
- dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
+ dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
pdsch_vars[eNB_id_i]->dl_ch_mag0,
pdsch_vars[eNB_id_i]->dl_ch_magb0,
@@ -375,104 +493,79 @@ int rx_pdsch(PHY_VARS_UE *ue,
i_mod,
nb_rb,
pdsch_vars[eNB_id]->log2_maxh,
- phy_measurements); // log2_maxh+I0_shift
+ measurements); // log2_maxh+I0_shift
#ifdef DEBUG_PHY
-
if (symbol == 5) {
write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
}
-
#endif
- // compute correlation between signal and interference channels
dlsch_dual_stream_correlation(frame_parms,
symbol,
nb_rb,
pdsch_vars[eNB_id]->dl_ch_estimates_ext,
pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->log2_maxh);
}
- } else if (dlsch0_harq->mimo_mode == LARGE_CDD) { // TM3
- // LOG_I(PHY,"Running PDSCH RX for TM3\n");
- if (frame_parms->nb_antenna_ports_eNB == 2) {
- if (first_symbol_flag==1) {
- // effective channel of desired user is always stronger than interfering eff. channel
- dlsch_channel_level_TM3(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
- frame_parms,
- avg, symbol, nb_rb);
-
- // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]);
- avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->Qm>>1)-1];
-
- pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0);
- // printf("log2_maxh =%d\n",pdsch_vars[eNB_id]->log2_maxh);
- }
-
- dlsch_channel_compensation_TM3(frame_parms,
+ } else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+ (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){
+ dlsch_channel_compensation_TM34(frame_parms,
pdsch_vars[eNB_id],
- phy_measurements,
+ measurements,
eNB_id,
symbol,
dlsch0_harq->Qm,
dlsch1_harq->Qm,
+ harq_pid,
dlsch0_harq->round,
+ dlsch0_harq->mimo_mode,
nb_rb,
- pdsch_vars[eNB_id]->log2_maxh);
+ pdsch_vars[eNB_id]->log2_maxh0,
+ pdsch_vars[eNB_id]->log2_maxh1);
+ /* if (symbol == 5) {
+ write_output("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
+ write_output("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
+ write_output("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
+ write_output("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
+ } */
// compute correlation between signal and interference channels (rho12 and rho21)
- dlsch_dual_stream_correlation(frame_parms,
+ dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22
symbol,
nb_rb,
pdsch_vars[eNB_id]->dl_ch_estimates_ext,
&(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->log2_maxh);
- dlsch_dual_stream_correlation(frame_parms,
- symbol,
- nb_rb,
- &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
- pdsch_vars[eNB_id]->dl_ch_estimates_ext,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
- pdsch_vars[eNB_id]->log2_maxh);
+ pdsch_vars[eNB_id]->log2_maxh0);
+ //printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] );
+ //to be optimized (just take complex conjugate)
+ dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21
+ symbol,
+ nb_rb,
+ &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
+ pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->log2_maxh1);
+ // printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext );
//printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh);
+ /* if (symbol == 5) {
+ write_output("rho0_0.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
+ write_output("rho2_0.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
+ write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
+ write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
+ } */
- } else {
- LOG_E(PHY, "only 2 tx antennas supported for TM3\n");
- }
- } else if (dlsch0_harq->mimo_moden_connected_eNB)) { // TM5 two-user
-
- // Scale the channel estimates for interfering stream
-
- dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
- frame_parms,
- dlsch,
- symbol,
- nb_rb);
-
- /* compute new log2_maxh for effective channel */
- if (first_symbol_flag==1) {
- // effective channel of desired user is always stronger than interfering eff. channel
- dlsch_channel_level_TM56(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb);
-
- // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]);
- avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1];
-
- pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0);
- //printf("log1_maxh =%d\n",pdsch_vars[eNB_id]->log2_maxh);
- }
-
- dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext,
+ } else if (dlsch0_harq->mimo_moden_connected_eNB) && (dlsch0_harq->dl_power_off==0)) {
+ dlsch_channel_compensation_TM56(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,
pdsch_vars[eNB_id]->pmi_ext,
frame_parms,
- phy_measurements,
+ measurements,
eNB_id,
symbol,
dlsch0_harq->Qm,
@@ -480,33 +573,24 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->log2_maxh,
dlsch0_harq->dl_power_off);
- // if interference source is MU interference, assume opposite precoder was used at eNB
-
- // calculate opposite PMI
- for (rb=0; rbpmi_ext[rb]) {
- case 0:
- pdsch_vars[eNB_id_i]->pmi_ext[rb]=1;
- break;
-
- case 1:
- pdsch_vars[eNB_id_i]->pmi_ext[rb]=0;
- break;
-
- case 2:
- pdsch_vars[eNB_id_i]->pmi_ext[rb]=3;
- break;
-
- case 3:
- pdsch_vars[eNB_id_i]->pmi_ext[rb]=2;
- break;
- }
-
- // if (rb==0)
+ for (rb=0; rbpmi_ext[rb]) {
+ case 0:
+ pdsch_vars[eNB_id_i]->pmi_ext[rb]=1;
+ break;
+ case 1:
+ pdsch_vars[eNB_id_i]->pmi_ext[rb]=0;
+ break;
+ case 2:
+ pdsch_vars[eNB_id_i]->pmi_ext[rb]=3;
+ break;
+ case 3:
+ pdsch_vars[eNB_id_i]->pmi_ext[rb]=2;
+ break;
+ }
+ // if (rb==0)
// printf("pmi %d, pmi_i %d\n",pdsch_vars[eNB_id]->pmi_ext[rb],pdsch_vars[eNB_id_i]->pmi_ext[rb]);
-
}
-
dlsch_channel_compensation_TM56(pdsch_vars[eNB_id_i]->rxdataF_ext,
pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
pdsch_vars[eNB_id_i]->dl_ch_mag0,
@@ -514,32 +598,27 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id_i]->rxdataF_comp0,
pdsch_vars[eNB_id_i]->pmi_ext,
frame_parms,
- phy_measurements,
+ measurements,
eNB_id_i,
symbol,
i_mod,
nb_rb,
pdsch_vars[eNB_id]->log2_maxh,
dlsch0_harq->dl_power_off);
-
#ifdef DEBUG_PHY
-
if (symbol==5) {
write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
- write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+ write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
}
-
#endif
-
dlsch_dual_stream_correlation(frame_parms,
symbol,
nb_rb,
pdsch_vars[eNB_id]->dl_ch_estimates_ext,
pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->log2_maxh);
-
- } else {
+ } else if (dlsch0_harq->dl_power_off==1) {
dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext,
pdsch_vars[eNB_id]->dl_ch_estimates_ext,
pdsch_vars[eNB_id]->dl_ch_mag0,
@@ -547,66 +626,70 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->rxdataF_comp0,
pdsch_vars[eNB_id]->pmi_ext,
frame_parms,
- phy_measurements,
+ measurements,
eNB_id,
symbol,
dlsch0_harq->Qm,
nb_rb,
pdsch_vars[eNB_id]->log2_maxh,
1);
- }
- } else if (dlsch0_harq->mimo_mode==TM7) { //TM7
- dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
- pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_magb0,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
- frame_parms,
- symbol,
- first_symbol_flag,
- get_Qm(dlsch0_harq->mcs),
- nb_rb,
- //9,
- pdsch_vars[eNB_id]->log2_maxh,
- phy_measurements); // log2_maxh+I0_shift
+ }
+
+
+ } else if (dlsch0_harq->mimo_mode==TM7) { //TM7
+
+ dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
+ pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ pdsch_vars[eNB_id]->dl_ch_magb0,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
+ frame_parms,
+ symbol,
+ first_symbol_flag,
+ get_Qm(dlsch0_harq->mcs),
+ nb_rb,
+ //9,
+ pdsch_vars[eNB_id]->log2_maxh,
+ measurements); // log2_maxh+I0_shift
}
- // printf("MRC\n");
- if (frame_parms->nb_antennas_rx > 1) {
- if (dlsch0_harq->mimo_mode == LARGE_CDD) {
+// MRC
+
+
+ if (frame_parms->nb_antennas_rx > 1) {
+ if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
+ ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+ (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4
if (frame_parms->nb_antenna_ports_eNB == 2) {
- dlsch_detection_mrc(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round],
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->rho,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_magb0,
- pdsch_vars[eNB_id]->dl_ch_mag1,
- pdsch_vars[eNB_id]->dl_ch_magb1,
- symbol,
- nb_rb,
- dual_stream_flag);
+ dlsch_detection_mrc_TM34(frame_parms,
+ pdsch_vars[eNB_id],
+ harq_pid,
+ dlsch0_harq->round,
+ symbol,
+ nb_rb,
+ 1);
+ /* if (symbol == 5) {
+ write_output("rho0_mrc.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
+ write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
+ } */
}
} else {
-
dlsch_detection_mrc(frame_parms,
pdsch_vars[eNB_id]->rxdataF_comp0,
pdsch_vars[eNB_id_i]->rxdataF_comp0,
pdsch_vars[eNB_id]->rho,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->dl_ch_mag0,
pdsch_vars[eNB_id]->dl_ch_magb0,
pdsch_vars[eNB_id_i]->dl_ch_mag0,
pdsch_vars[eNB_id_i]->dl_ch_magb0,
symbol,
nb_rb,
- dual_stream_flag);
+ rx_type==rx_IC_single_stream);
}
}
-
// printf("Combining");
if ((dlsch0_harq->mimo_mode == SISO) ||
((dlsch0_harq->mimo_mode >= UNIFORM_PRECODING11) &&
@@ -620,122 +703,109 @@ int rx_pdsch(PHY_VARS_UE *ue,
nb_rb);
*/
} else if (dlsch0_harq->mimo_mode == ALAMOUTI) {
-
dlsch_alamouti(frame_parms,
pdsch_vars[eNB_id]->rxdataF_comp0,
pdsch_vars[eNB_id]->dl_ch_mag0,
pdsch_vars[eNB_id]->dl_ch_magb0,
symbol,
nb_rb);
-
- }
-
- else if (dlsch0_harq->mimo_mode == LARGE_CDD) {
-
- } else {
- LOG_W(PHY,"dlsch_rx: Unknown MIMO mode\n");
- return (-1);
}
// printf("LLR");
+ if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
+ ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+ (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) {
+ rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round];
+ dl_ch_mag_ptr = pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round];
+ }
+ else {
+ rxdataF_comp_ptr = pdsch_vars[eNB_id_i]->rxdataF_comp0;
+ dl_ch_mag_ptr = pdsch_vars[eNB_id_i]->dl_ch_mag0;
+ //i_mod should have been passed as a parameter
+ }
switch (dlsch0_harq->Qm) {
case 2 :
- if (dlsch0_harq->mimo_mode != LARGE_CDD) {
- if (dual_stream_flag == 0)
+ if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
dlsch_qpsk_llr(frame_parms,
pdsch_vars[eNB_id]->rxdataF_comp0,
pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
+ symbol,
+ first_symbol_flag,
+ nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
pdsch_vars[eNB_id]->llr128,
beamforming_mode);
- else if (i_mod == 2) {
- dlsch_qpsk_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- } else if (i_mod == 4) {
- dlsch_qpsk_16qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- } else {
- dlsch_qpsk_64qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
-
- }
- } else { // TM3
- DevAssert(dlsch1_harq);
-
- if (dlsch1_harq->Qm == 2) {
- /* dlsch_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- */
- dlsch_qpsk_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round],
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- dlsch_qpsk_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round],
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_rho2_ext,
- pdsch_vars[eNB_id]->llr[1],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128_2ndstream);
- } else if (dlsch1_harq->Qm == 4) {
- dlsch_qpsk_16qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round],
- pdsch_vars[eNB_id]->dl_ch_mag1,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- } else {
- dlsch_qpsk_64qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round],
- pdsch_vars[eNB_id]->dl_ch_mag1,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
-
- }
}
-
+ else if (rx_type >= rx_IC_single_stream) {
+ if (dlsch1_harq->Qm == 2) {
+ dlsch_qpsk_qpsk_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_qpsk_qpsk_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ else if (dlsch1_harq->Qm == 4) {
+ dlsch_qpsk_16qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ dl_ch_mag_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_16qam_qpsk_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,//i
+ dl_ch_mag_ptr,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ else {
+ dlsch_qpsk_64qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ dl_ch_mag_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_64qam_qpsk_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,//i
+ dl_ch_mag_ptr,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ }
break;
-
case 4 :
- if (dual_stream_flag == 0) {
+ if ((rx_type==rx_standard ) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
dlsch_16qam_llr(frame_parms,
pdsch_vars[eNB_id]->rxdataF_comp0,
pdsch_vars[eNB_id]->llr[0],
@@ -744,44 +814,82 @@ int rx_pdsch(PHY_VARS_UE *ue,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128,
beamforming_mode);
- } else if (i_mod == 2) {
- dlsch_16qam_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- } else if (i_mod == 4) {
- dlsch_16qam_16qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id_i]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- } else {
- dlsch_16qam_64qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id_i]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
}
-
+ else if (rx_type >= rx_IC_single_stream) {
+ if (dlsch1_harq->Qm == 2) {
+ dlsch_16qam_qpsk_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_qpsk_16qam_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,//i
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ else if (dlsch1_harq->Qm == 4) {
+ dlsch_16qam_16qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ dl_ch_mag_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_16qam_16qam_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,//i
+ dl_ch_mag_ptr,
+ pdsch_vars[eNB_id]->dl_ch_mag0,//i
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ else {
+ dlsch_16qam_64qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ dl_ch_mag_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_64qam_16qam_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ dl_ch_mag_ptr,
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ }
break;
-
case 6 :
- if (dual_stream_flag == 0) {
+ if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
dlsch_64qam_llr(frame_parms,
pdsch_vars[eNB_id]->rxdataF_comp0,
pdsch_vars[eNB_id]->llr[0],
@@ -791,48 +899,130 @@ int rx_pdsch(PHY_VARS_UE *ue,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr128,
beamforming_mode);
- } else if (i_mod == 2) {
- dlsch_64qam_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
- } else if (i_mod == 4) {
- dlsch_64qam_16qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id_i]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
-
- } else {
- dlsch_64qam_64qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id_i]->rxdataF_comp0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id_i]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_rho_ext,
- pdsch_vars[eNB_id]->llr[0],
- symbol,first_symbol_flag,nb_rb,
- adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
- pdsch_vars[eNB_id]->llr128);
}
-
+ else if (rx_type >= rx_IC_single_stream) {
+ if (dlsch1_harq->Qm == 2) {
+ dlsch_64qam_qpsk_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_qpsk_64qam_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ else if (dlsch1_harq->Qm == 4) {
+ dlsch_64qam_16qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ dl_ch_mag_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_16qam_64qam_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,//i
+ dl_ch_mag_ptr,
+ pdsch_vars[eNB_id]->dl_ch_mag0,//i
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ else {
+ dlsch_64qam_64qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ rxdataF_comp_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ dl_ch_mag_ptr,//i
+ pdsch_vars[eNB_id]->dl_ch_rho2_ext,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128);
+ if (rx_type==rx_IC_dual_stream) {
+ dlsch_64qam_64qam_llr(frame_parms,
+ rxdataF_comp_ptr,
+ pdsch_vars[eNB_id]->rxdataF_comp0,//i
+ dl_ch_mag_ptr,
+ pdsch_vars[eNB_id]->dl_ch_mag0,//i
+ pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
+ pdsch_vars[eNB_id]->llr[1],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128_2ndstream);
+ }
+ }
+ }
break;
-
default:
LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
return(-1);
break;
}
+ if (dlsch1_harq) {
+ switch (get_Qm(dlsch1_harq->mcs)) {
+ case 2 :
+ if (rx_type==rx_standard) {
+ dlsch_qpsk_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pdsch_vars[eNB_id]->llr[0],
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128,
+ beamforming_mode);
+ }
+ break;
+ case 4:
+ if (rx_type==rx_standard) {
+ dlsch_16qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pdsch_vars[eNB_id]->llr[0],
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ symbol,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128,
+ beamforming_mode);
+ }
+ break;
+ case 6 :
+ if (rx_type==rx_standard) {
+ dlsch_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,first_symbol_flag,nb_rb,
+ adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
+ pdsch_vars[eNB_id]->llr128,
+ beamforming_mode);
+ }
+ break;
+ default:
+ LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
+ return(-1);
+ break;
+ }
+ }
+
#if T_TRACER
T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame%1024),
@@ -843,6 +1033,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
#endif
return(0);
+
}
//==============================================================================================
@@ -861,7 +1052,7 @@ void dlsch_channel_compensation(int **rxdataF_ext,
unsigned char mod_order,
unsigned short nb_rb,
unsigned char output_shift,
- PHY_MEASUREMENTS *phy_measurements)
+ PHY_MEASUREMENTS *measurements)
{
#if defined(__i386) || defined(__x86_64)
@@ -919,9 +1110,9 @@ void dlsch_channel_compensation(int **rxdataF_ext,
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);
- //print_ints("Re(ch):",(int16_t*)&mmtmpD0);
- //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
- //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]);
+ //print_ints("Re(ch):",(int16_t*)&mmtmpD0);
+ //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
+ //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]);
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);
@@ -1107,7 +1298,7 @@ void dlsch_channel_compensation(int **rxdataF_ext,
}
if (first_symbol_flag==1) {
- phy_measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12);
+ measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12);
}
}
}
@@ -1157,168 +1348,166 @@ void dlsch_channel_compensation(int **rxdataF_ext,
dl_ch_mag128b = (int16x8_t*)&dl_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
-
+
for (rb=0; rb2) {
- // get channel amplitude if not QPSK
- mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]);
- // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
- mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128[1]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
- mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128[2]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- if (pilots==0) {
- mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- }
+ if (mod_order>2) {
+ // get channel amplitude if not QPSK
+ mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]);
+ // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
+ mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128[1]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
+ mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128[2]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ if (pilots==0) {
+ mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ }
- dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
- dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
- dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
- dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
+ dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
+ dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
+ dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
+ dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
- if (pilots==0) {
- dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
- dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128);
- }
- }
-
- mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]);
- //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
- mmtmpD1 = vmull_s16(dl_ch128[1], rxdataF128[1]);
- //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
- mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
- //mmtmpD0 = [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])]
+ if (pilots==0) {
+ dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
+ dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128);
+ }
+ }
- mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]);
- //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
- mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]);
- //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
- mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
- //mmtmpD1 = [-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])]
+ mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]);
+ //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
+ mmtmpD1 = vmull_s16(dl_ch128[1], rxdataF128[1]);
+ //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ //mmtmpD0 = [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])]
- mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
- mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
- rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- mmtmpD0 = vmull_s16(dl_ch128[2], rxdataF128[2]);
- mmtmpD1 = vmull_s16(dl_ch128[3], rxdataF128[3]);
- mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
- mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]);
- mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]);
- mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
- mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
- mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
- rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]);
+ //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]);
+ //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ //mmtmpD1 = [-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])]
- if (pilots==0) {
- mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
- mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
- mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ mmtmpD0 = vmull_s16(dl_ch128[2], rxdataF128[2]);
+ mmtmpD1 = vmull_s16(dl_ch128[3], rxdataF128[3]);
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]);
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]);
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
- mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
- mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ if (pilots==0) {
+ mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
+ mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
-
- mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
- mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
- rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
-
- dl_ch128+=6;
- dl_ch_mag128+=3;
- dl_ch_mag128b+=3;
- rxdataF128+=6;
- rxdataF_comp128+=3;
-
- } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
- dl_ch128+=4;
- dl_ch_mag128+=2;
- dl_ch_mag128b+=2;
- rxdataF128+=4;
- rxdataF_comp128+=2;
- }
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
+
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+
+ dl_ch128+=6;
+ dl_ch_mag128+=3;
+ dl_ch_mag128b+=3;
+ rxdataF128+=6;
+ rxdataF_comp128+=3;
+
+ } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
+ dl_ch128+=4;
+ dl_ch_mag128+=2;
+ dl_ch_mag128b+=2;
+ rxdataF128+=4;
+ rxdataF_comp128+=2;
+ }
}
}
}
-
+
if (rho) {
for (aarx=0; aarxnb_antennas_rx; aarx++) {
rho128 = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch128_2 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
for (rb=0; rbrx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12);
+ measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12);
}
}
}
#endif
}
-
-
#if defined(__x86_64__) || defined(__i386__)
void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1)
@@ -1364,61 +1553,64 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1)
_mm_empty();
_m_empty();
}
-
#elif defined(__arm__)
-void prec2A_TM56_128(unsigned char pmi,int16x8_t* ch0,int16x8_t* ch1) {
+void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) {
- int16x8_t amp;
- int16_t conj[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
+ // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b,
+ //so removed it
- amp = vmovq_n_s16(ONE_OVER_SQRT2_Q15);
+ //__m128i amp;
+ //amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
switch (pmi) {
+
case 0 : // +1 +1
// print_shorts("phase 0 :ch0",ch0);
// print_shorts("phase 0 :ch1",ch1);
- ch0[0] = vqaddq_s16(ch0[0],ch1[0]);
+ ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]);
break;
-
case 1 : // +1 -1
// print_shorts("phase 1 :ch0",ch0);
// print_shorts("phase 1 :ch1",ch1);
- ch0[0] = vqsubq_s16(ch0[0],ch1[0]);
+ ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]);
// print_shorts("phase 1 :ch0-ch1",ch0);
break;
-
case 2 : // +1 +j
- ch1[0] = vrev32q_s16(vmulq_s16(ch1[0],*(int16x8_t*)conj));
- ch0[0] = vqsubq_s16(ch0[0],ch1[0]);
+ ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
+ ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
+ ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
+ ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]);
+
break; // +1 -j
-
case 3 :
- ch1[0] = vrev32q_s16(vmulq_s16(ch1[0],*(int16x8_t*)conj));
- ch0[0] = vqaddq_s16(ch0[0],ch1[0]);
+ ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
+ ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
+ ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
+ ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]);
break;
}
-
- ch0[0] = vqdmulhq_s16(ch0[0],amp);
+
+ //ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
+ //ch0[0] = _mm_slli_epi16(ch0[0],1);
+
+ _mm_empty();
+ _m_empty();
}
-
#endif
-
// precoding is stream 0 .5(1,1) .5(1,-1) .5(1,1) .5(1,-1)
// stream 1 .5(1,-1) .5(1,1) .5(1,-1) .5(1,1)
// store "precoded" channel for stream 0 in ch0, stream 1 in ch1
short TM3_prec[8]__attribute__((aligned(16))) = {1,1,-1,-1,1,1,-1,-1} ;
-#if defined(__x86_64__) || defined(__i386__)
+void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) {
-static inline void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) __attribute__((always_inline));
-static inline void prec2A_TM3_128(__m128i *ch0,__m128i *ch1)
-{
-
- // __m128i amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
+ __m128i amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
__m128i tmp0,tmp1;
+ // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b,
+ //so divide by 2 is replaced by divide by sqrt(2).
// print_shorts("prec2A_TM3 ch0 (before):",ch0);
// print_shorts("prec2A_TM3 ch1 (before):",ch1);
@@ -1434,86 +1626,71 @@ static inline void prec2A_TM3_128(__m128i *ch0,__m128i *ch1)
// print_shorts("prec2A_TM3 ch0 (mid):",&tmp0);
// print_shorts("prec2A_TM3 ch1 (mid):",ch1);
+ ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
+ ch0[0] = _mm_slli_epi16(ch0[0],1);
+ ch1[0] = _mm_mulhi_epi16(ch1[0],amp);
+ ch1[0] = _mm_slli_epi16(ch1[0],1);
- ch0[0] = _mm_srai_epi16(ch0[0],1);
- ch1[0] = _mm_srai_epi16(ch1[0],1);
+ // ch0[0] = _mm_srai_epi16(ch0[0],1);
+ // ch1[0] = _mm_srai_epi16(ch1[0],1);
// print_shorts("prec2A_TM3 ch0 (after):",ch0);
// print_shorts("prec2A_TM3 ch1 (after):",ch1);
+ _mm_empty();
+ _m_empty();
}
-#elif defined(__arm__)
-
-void prec2A_TM3_128(int16x8_t* ch0, int16x8_t* ch1)
-{
-
- int16x8_t tmp0,tmp1;
-
- tmp0 = ch0[0];
- tmp1 = vmulq_s16(ch1[0],((int16x8_t*)&TM3_prec)[0]);
- ch0[0] = vhaddq_s16(ch0[0],tmp1);
- ch1[0] = vhsubq_s16(tmp0,tmp1);
-}
-
-#endif
-
// pmi = 0 => stream 0 (1,1), stream 1 (1,-1)
// pmi = 1 => stream 0 (1,j), stream 2 (1,-j)
-#if defined(__x86_64__) || defined(__i386__)
+void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) {
-void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1)
-{
+// sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b,
+//so divide by 2 is replaced by divide by sqrt(2).
- __m128i amp;
- amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
+ // printf ("demod pmi=%d\n", pmi);
+ __m128i amp;
+ amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
__m128i tmp0,tmp1;
- if (pmi == 0) {
- ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]);
- ch1[0] = _mm_subs_epi16(ch0[0],ch1[0]);
- } else {
+ // print_shorts("prec2A_TM4 ch0 (before):",ch0);
+ // print_shorts("prec2A_TM4 ch1 (before):",ch1);
+
+ if (pmi == 0) { //[1 1;1 -1]
+ tmp0 = ch0[0];
+ tmp1 = ch1[0];
+ ch0[0] = _mm_adds_epi16(tmp0,tmp1);
+ ch1[0] = _mm_subs_epi16(tmp0,tmp1);
+ }
+ else { //ch0+j*ch1 ch0-j*ch1
tmp0 = ch0[0];
tmp1 = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1));
tmp1 = _mm_shufflehi_epi16(tmp1,_MM_SHUFFLE(2,3,0,1));
- ch0[0] = _mm_adds_epi16(tmp0,tmp1);
- ch1[0] = _mm_subs_epi16(tmp0,tmp1);
+ ch0[0] = _mm_subs_epi16(tmp0,tmp1);
+ ch1[0] = _mm_add_epi16(tmp0,tmp1);
}
+ //print_shorts("prec2A_TM4 ch0 (middle):",ch0);
+ //print_shorts("prec2A_TM4 ch1 (middle):",ch1);
+
ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
ch0[0] = _mm_slli_epi16(ch0[0],1);
ch1[0] = _mm_mulhi_epi16(ch1[0],amp);
ch1[0] = _mm_slli_epi16(ch1[0],1);
+
+ // ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2
+ // ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2
+ //print_shorts("prec2A_TM4 ch0 (end):",ch0);
+ //print_shorts("prec2A_TM4 ch1 (end):",ch1);
+ _mm_empty();
+ _m_empty();
+ // print_shorts("prec2A_TM4 ch0 (end):",ch0);
+ //print_shorts("prec2A_TM4 ch1 (end):",ch1);
}
-#elif defined(__arm__)
-
-void prec2A_TM4_128(int pmi,int16x8_t *ch0,int16x8_t *ch1)
-{
- int16x8_t amp;
- int16x8_t tmp0,tmp1;
- int16_t conj[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
-
- amp = vmovq_n_s16(ONE_OVER_SQRT2_Q15);
-
- if (pmi == 0) {
- ch0[0] = vqaddq_s16(ch0[0],ch1[0]);
- ch1[0] = vqsubq_s16(ch0[0],ch1[0]);
- } else {
- tmp0 = ch0[0];
- tmp1 = vrev32q_s16(vmulq_s16(ch1[0],*(int16x8_t*)conj));
- ch0[0] = vqaddq_s16(tmp0,tmp1);
- ch1[0] = vqsubq_s16(tmp0,tmp1);
- }
-
- ch0[0] = vqdmulhq_s16(ch0[0],amp);
- ch1[0] = vqdmulhq_s16(ch1[0],amp);
-}
-#endif
-
void dlsch_channel_compensation_TM56(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
@@ -1521,7 +1698,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
int **rxdataF_comp,
unsigned char *pmi_ext,
LTE_DL_FRAME_PARMS *frame_parms,
- PHY_MEASUREMENTS *phy_measurements,
+ PHY_MEASUREMENTS *measurements,
int eNB_id,
unsigned char symbol,
unsigned char mod_order,
@@ -1575,6 +1752,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]);
if (pilots==0) {
+
prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]);
}
@@ -1594,6 +1772,9 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
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);
+
+ //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]);
+
//print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]);
dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
@@ -1625,32 +1806,34 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
if (pilots==0) {
dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
+
}
}
// MF multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]);
- // print_ints("re",&mmtmpD0);
+ // print_ints("re",&mmtmpD0);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
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]);
- // print_ints("im",&mmtmpD1);
+
+ // 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);
+ // print_ints("re(shift)",&mmtmpD0);
mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
- // print_ints("im(shift)",&mmtmpD1);
+ // 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);
+ // 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);
+ // print_shorts("rx:",rxdataF128);
+ // print_shorts("ch:",dl_ch128);
+ // print_shorts("pack:",rxdataF_comp128);
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]);
@@ -1708,57 +1891,54 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
Nre = (pilots==0) ? 12 : 8;
precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
- (nb_rb*Nre))) - (phy_measurements->n0_power[aarx]));
+ (nb_rb*Nre))) - (measurements->n0_power[aarx]));
} // rx_antennas
- phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,phy_measurements->n0_power_tot);
+ measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,measurements->n0_power_tot);
//printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol,
- // phy_measurements->precoded_cqi_dB[eNB_id][0]);
-
- _mm_empty();
- _m_empty();
+ // measurements->precoded_cqi_dB[eNB_id][0]);
#elif defined(__arm__)
uint32_t rb,Nre;
uint32_t aarx,symbol_mod,pilots=0;
-
+
int16x4_t *dl_ch0_128,*dl_ch1_128,*rxdataF128;
int16x8_t *dl_ch0_128b,*dl_ch1_128b;
int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
int16x8_t *dl_ch_mag128,*dl_ch_mag128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp128;
int16x8_t QAM_amp128,QAM_amp128b;
-
+
int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
int32_t precoded_signal_strength=0;
-
- symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : 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->mode1_flag==1) // 10 out of 12 so don't reduce size
{ nb_rb=1+(5*nb_rb/6); }
-
+
else
{ pilots=1; }
}
-
-
+
+
if (mod_order == 4) {
QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10)
QAM_amp128b = vmovq_n_s16(0);
-
+
} else if (mod_order == 6) {
QAM_amp128 = vmovq_n_s16(QAM64_n1); //
QAM_amp128b = vmovq_n_s16(QAM64_n2);
}
-
+
// printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
-
+
for (aarx=0; aarxnb_antennas_rx; aarx++) {
-
-
-
+
+
+
dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
@@ -1767,144 +1947,153 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
dl_ch_mag128b = (int16x8_t*)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128 = (int16x8_t*)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12];
-
+
for (rb=0; rb%d\n",rb,pmi_ext[rb]);
#endif
prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[0],&dl_ch1_128b[0]);
prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[1],&dl_ch1_128b[1]);
-
+
if (pilots==0) {
- prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[2],&dl_ch1_128b[2]);
+ prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[2],&dl_ch1_128b[2]);
}
-
+
if (mod_order>2) {
- // get channel amplitude if not QPSK
- mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]);
- // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
- mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
- mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- if (pilots==0) {
- mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
-
- }
-
- dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
- dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
- dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
- dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
-
-
- if (pilots==0) {
- dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
- dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128);
- }
+ // get channel amplitude if not QPSK
+ mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]);
+ // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
+ mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
+ mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ if (pilots==0) {
+ mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+
+ }
+
+ dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
+ dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
+ dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
+ dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
+
+
+ if (pilots==0) {
+ dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
+ dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128);
+ }
}
mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]);
- //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
+ //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]);
- //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
+ //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
- //mmtmpD0 = [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])]
-
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ //mmtmpD0 = [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])]
+
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]);
//mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]);
//mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
//mmtmpD1 = [-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])]
-
+
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
rxdataF_comp128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
+
mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]);
mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]);
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
-
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]);
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]);
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
-
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
rxdataF_comp128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
+
if (pilots==0) {
- mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]);
- mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]);
- mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
-
- mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
- mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
- mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
-
-
- mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
- mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
- rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
-
- dl_ch0_128+=6;
- dl_ch1_128+=6;
- dl_ch_mag128+=3;
- dl_ch_mag128b+=3;
- rxdataF128+=6;
- rxdataF_comp128+=3;
-
+ mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]);
+ mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]);
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
+
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+
+ dl_ch0_128+=6;
+ dl_ch1_128+=6;
+ dl_ch_mag128+=3;
+ dl_ch_mag128b+=3;
+ rxdataF128+=6;
+ rxdataF_comp128+=3;
+
} else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
- dl_ch0_128+=4;
- dl_ch1_128+=4;
- dl_ch_mag128+=2;
- dl_ch_mag128b+=2;
- rxdataF128+=4;
- rxdataF_comp128+=2;
+ dl_ch0_128+=4;
+ dl_ch1_128+=4;
+ dl_ch_mag128+=2;
+ dl_ch_mag128b+=2;
+ rxdataF128+=4;
+ rxdataF_comp128+=2;
}
}
-
+
Nre = (pilots==0) ? 12 : 8;
-
+
+
precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
- (nb_rb*Nre))) - (phy_measurements->n0_power[aarx]));
+
+ (nb_rb*Nre))) - (measurements->n0_power[aarx]));
// rx_antennas
}
- phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,phy_measurements->n0_power_tot);
-
+ measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,measurements->n0_power_tot);
+
+ //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol,
+ // measurements->precoded_cqi_dB[eNB_id][0]);
+
#endif
+ _mm_empty();
+ _m_empty();
}
-void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
+void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *pdsch_vars,
PHY_MEASUREMENTS *measurements,
int eNB_id,
unsigned char symbol,
unsigned char mod_order0,
unsigned char mod_order1,
+ int harq_pid,
int round,
+ MIMO_mode_t mimo_mode,
unsigned short nb_rb,
- unsigned char output_shift)
-{
+ unsigned char output_shift0,
+ unsigned char output_shift1) {
#if defined(__x86_64__) || defined(__i386__)
@@ -1912,25 +2101,27 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
__m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag0_128,*dl_ch_mag1_128,*dl_ch_mag0_128b,*dl_ch_mag1_128b,*rxdataF128,*rxdataF_comp0_128,*rxdataF_comp1_128;
unsigned char aarx=0,symbol_mod,pilots=0;
int precoded_signal_strength0=0,precoded_signal_strength1=0;
+ int rx_power_correction;
int **rxdataF_ext = pdsch_vars->rxdataF_ext;
int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext;
int **dl_ch_mag0 = pdsch_vars->dl_ch_mag0;
- int **dl_ch_mag1 = pdsch_vars->dl_ch_mag1;
+ int **dl_ch_mag1 = pdsch_vars->dl_ch_mag1[harq_pid][round];
int **dl_ch_magb0 = pdsch_vars->dl_ch_magb0;
- int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1;
+ int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1[harq_pid][round];
int **rxdataF_comp0 = pdsch_vars->rxdataF_comp0;
- int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[round]; //?
+ int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round];
+ unsigned char *pmi_ext = pdsch_vars->pmi_ext;
__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b;
-
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
pilots=1;
+ rx_power_correction = 1;
- //printf("comp prec: symbol %d, pilots %d\n",symbol, pilots);
+ // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots);
if (mod_order0 == 4) {
QAM_amp0_128 = _mm_set1_epi16(QAM16_n1);
@@ -1948,39 +2139,83 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
QAM_amp1_128b = _mm_set1_epi16(QAM64_n2);
}
- for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ for (aarx=0;aarxnb_antennas_rx;aarx++) {
- dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // hr,0
- dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // hr,1
+ /* if (aarx==0) {
+ output_shift=output_shift0;
+ }
+ else {
+ output_shift=output_shift1;
+ } */
+
+ // printf("antenna %d\n", aarx);
+ // printf("symbol %d, rx antenna %d\n", symbol, aarx);
+
+ dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11
+ dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12
- dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12];
- dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];
- dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12];
- dl_ch_mag1_128b = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12];
- rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // yr
- rxdataF_comp0_128 = (__m128i *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; // yr,0 = yr * conj(hr,0)
- rxdataF_comp1_128 = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; // yr,1 = yr * conj(hr,1)
-
+ dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1
+ dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1
+ dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2
+ dl_ch_mag1_128b = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2
+ rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; //received signal on antenna of interest h11*x1+h12*x2
+ rxdataF_comp0_128 = (__m128i *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x1 on antenna of interest
+ rxdataF_comp1_128 = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x2 on antenna of interest
for (rb=0; rb2) {
// get channel amplitude if not QPSK
mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]);
- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]);
- mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
@@ -1991,6 +2226,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
// print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]);
+
dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
dl_ch_mag0_128b[1] = dl_ch_mag0_128[1];
dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128);
@@ -1998,7 +2234,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
if (pilots==0) {
mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]);
- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
@@ -2012,7 +2248,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b);
dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1);
- //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]);
+ // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]);
dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b);
dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1);
@@ -2027,10 +2263,10 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
// get channel amplitude if not QPSK
mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]);
- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]);
- mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
@@ -2039,7 +2275,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128);
dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1);
- //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]);
+ // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]);
dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
dl_ch_mag1_128b[1] = dl_ch_mag1_128[1];
@@ -2048,7 +2284,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
if (pilots==0) {
mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]);
- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
@@ -2062,7 +2298,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b);
dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1);
- //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]);
+ // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]);
dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b);
dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1);
@@ -2076,28 +2312,29 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
// layer 0
// MF multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]);
- //print_ints("re",&mmtmpD0);
+ // print_ints("re",&mmtmpD0);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
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,rxdataF128[0]);
- // print_ints("im",&mmtmpD1);
+ // print_ints("im",&mmtmpD1);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
- // printf("Shift: %d\n",output_shift);
- // print_ints("re(shift)",&mmtmpD0);
- mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
- // print_ints("im(shift)",&mmtmpD1);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
+ // printf("Shift: %d\n",output_shift);
+ // print_ints("re(shift)",&mmtmpD0);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
+ // 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);
+ // print_ints("c0",&mmtmpD2);
+ // print_ints("c1",&mmtmpD3);
rxdataF_comp0_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
- // print_shorts("rx:",rxdataF128);
- // print_shorts("ch:",dl_ch0_128);
- // print_shorts("pack:",rxdataF_comp0_128);
+
+ // print_shorts("rx:",rxdataF128);
+ // print_shorts("ch:",dl_ch0_128);
+ // print_shorts("pack:",rxdataF_comp0_128);
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]);
@@ -2107,15 +2344,15 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
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);
+ 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);
rxdataF_comp0_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
- // print_shorts("rx:",rxdataF128+1);
- // print_shorts("ch:",dl_ch0_128+1);
- // print_shorts("pack:",rxdataF_comp128+1);
+ // print_shorts("rx:",rxdataF128+1);
+ // print_shorts("ch:",dl_ch0_128+1);
+ // print_shorts("pack:",rxdataF_comp0_128+1);
if (pilots==0) {
// multiply by conjugated channel
@@ -2126,17 +2363,15 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
- mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+ 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);
rxdataF_comp0_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
- // print_shorts("rx:",rxdataF128+2);
- // print_shorts("ch:",dl_ch0_128+2);
- // print_shorts("pack:",rxdataF_comp128+2);
-
- } else {
+ // print_shorts("rx:",rxdataF128+2);
+ // print_shorts("ch:",dl_ch0_128+2);
+ // print_shorts("pack:",rxdataF_comp0_128+2);
}
@@ -2144,29 +2379,29 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
// layer 1
// MF multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],rxdataF128[0]);
- // print_ints("re",&mmtmpD0);
+ // print_ints("re",&mmtmpD0);
- // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+ // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_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]);
- // print_ints("im",&mmtmpD1);
+ // 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);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
+ // print_ints("re(shift)",&mmtmpD0);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
+ // 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);
+ // print_ints("c0",&mmtmpD2);
+ // print_ints("c1",&mmtmpD3);
rxdataF_comp1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
- // print_shorts("rx:",rxdataF128);
- // print_shorts("ch:",dl_ch128);
- // print_shorts("pack:",rxdataF_comp128);
+ // print_shorts("rx:",rxdataF128);
+ // print_shorts("ch:",dl_ch1_128);
+ // print_shorts("pack:",rxdataF_comp1_128);
- // multiply by conjugated channel
+ // multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch1_128[1],rxdataF128[1]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1));
@@ -2174,15 +2409,15 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
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);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
rxdataF_comp1_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
- // print_shorts("rx:",rxdataF128+1);
- // print_shorts("ch:",dl_ch128+1);
- // print_shorts("pack:",rxdataF_comp128+1);
+ // print_shorts("rx:",rxdataF128+1);
+ // print_shorts("ch:",dl_ch1_128+1);
+ // print_shorts("pack:",rxdataF_comp1_128+1);
if (pilots==0) {
// multiply by conjugated channel
@@ -2193,15 +2428,15 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
- mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
- mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
rxdataF_comp1_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
- // print_shorts("rx:",rxdataF128+2);
- // print_shorts("ch:",dl_ch128+2);
- // print_shorts("pack:",rxdataF_comp128+2);
+ // print_shorts("rx:",rxdataF128+2);
+ // print_shorts("ch:",dl_ch1_128+2);
+ // print_shorts("pack:",rxdataF_comp1_128+2);
dl_ch0_128+=3;
dl_ch1_128+=3;
@@ -2212,7 +2447,8 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
rxdataF128+=3;
rxdataF_comp0_128+=3;
rxdataF_comp1_128+=3;
- } else {
+ }
+ else {
dl_ch0_128+=2;
dl_ch1_128+=2;
dl_ch_mag0_128+=2;
@@ -2225,85 +2461,85 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
}
} // rb loop
- }
-
- Nre = (pilots==0) ? 12 : 8;
+ Nre = (pilots==0) ? 12 : 8;
- precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
- (nb_rb*Nre))) - (measurements->n0_power[aarx]));
+ precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
+ (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
- precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre],
- (nb_rb*Nre))) - (measurements->n0_power[aarx]));
+ precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre],
+ (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
+ } // rx_antennas
measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,measurements->n0_power_tot);
measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,measurements->n0_power_tot);
- //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol,
- // measurements->precoded_cqi_dB[eNB_id][0]);
+ // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol,
+ // measurements->precoded_cqi_dB[eNB_id][0]);
_mm_empty();
_m_empty();
-#elif defined(__arm__)
+ #elif defined(__arm__)
unsigned short rb,Nre;
unsigned char aarx,symbol_mod,pilots=0;
- int precoded_signal_strength0=0,precoded_signal_strength1=0;
+ int precoded_signal_strength0=0,precoded_signal_strength1=0, rx_power_correction;
int16x4_t *dl_ch0_128,*rxdataF128;
int16x4_t *dl_ch1_128;
int16x8_t *dl_ch0_128b,*dl_ch1_128b;
-
+
int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
int16x8_t *dl_ch_mag0_128,*dl_ch_mag0_128b,*dl_ch_mag1_128,*dl_ch_mag1_128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp0_128,*rxdataF_comp1_128;
int16x8_t QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b;
int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
-
+
int **rxdataF_ext = pdsch_vars->rxdataF_ext;
int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext;
int **dl_ch_mag0 = pdsch_vars->dl_ch_mag0;
- int **dl_ch_mag1 = pdsch_vars->dl_ch_mag1;
+ int **dl_ch_mag1 = pdsch_vars->dl_ch_mag1[harq_pid][round];
int **dl_ch_magb0 = pdsch_vars->dl_ch_magb0;
- int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1;
+ int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1[harq_pid][round];
int **rxdataF_comp0 = pdsch_vars->rxdataF_comp0;
- int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[round]; //?
-
+ int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round];
+
int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
-
+
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->mode1_flag==1) // 10 out of 12 so don't reduce size
{ nb_rb=1+(5*nb_rb/6); }
-
+
else
{ pilots=1; }
}
-
-
+
+ rx_power_correction=1;
+
if (mod_order0 == 4) {
QAM_amp0_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10)
QAM_amp0_128b = vmovq_n_s16(0);
-
+
} else if (mod_order0 == 6) {
QAM_amp0_128 = vmovq_n_s16(QAM64_n1); //
QAM_amp0_128b = vmovq_n_s16(QAM64_n2);
}
-
+
if (mod_order1 == 4) {
QAM_amp1_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10)
QAM_amp1_128b = vmovq_n_s16(0);
-
+
} else if (mod_order1 == 6) {
QAM_amp1_128 = vmovq_n_s16(QAM64_n1); //
QAM_amp1_128b = vmovq_n_s16(QAM64_n2);
}
-
+
// printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
-
+
for (aarx=0; aarxnb_antennas_rx; aarx++) {
-
-
-
+
+
+
dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
@@ -2315,195 +2551,215 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp0_128 = (int16x8_t*)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp1_128 = (int16x8_t*)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12];
-
- for (rb=0; rb%d\n",rb,pmi_ext[rb]);
-#endif
- prec2A_TM3_128(&dl_ch0_128b[0],&dl_ch1_128b[0]);
- prec2A_TM3_128(&dl_ch0_128b[1],&dl_ch1_128b[1]);
-
- if (pilots==0) {
- prec2A_TM3_128(&dl_ch0_128b[2],&dl_ch1_128b[2]);
+ for (rb=0; rb2) {
- // get channel amplitude if not QPSK
- mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]);
- // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
- mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
- mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
- if (pilots==0) {
- mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
-
- }
-
- dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b);
- dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b);
- dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128);
- dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128);
-
-
- if (pilots==0) {
- dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b);
- dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128);
- }
+ // get channel amplitude if not QPSK
+ mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]);
+ // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
+ mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
+ mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+ if (pilots==0) {
+ mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+
+ }
+
+ dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b);
+ dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b);
+ dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128);
+ dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128);
+
+
+ if (pilots==0) {
+ dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b);
+ dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128);
+ }
}
if (mod_order1>2) {
- // get channel amplitude if not QPSK
- mmtmpD0 = vmull_s16(dl_ch1_128[0], dl_ch1_128[0]);
- // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
- mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
- mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
- if (pilots==0) {
- mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]);
- mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
- mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]);
- mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
- mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
-
- }
-
- dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b);
- dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b);
- dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128);
- dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128);
-
-
- if (pilots==0) {
- dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b);
- dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128);
- }
+ // get channel amplitude if not QPSK
+ mmtmpD0 = vmull_s16(dl_ch1_128[0], dl_ch1_128[0]);
+ // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
+ mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
+ mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+ if (pilots==0) {
+ mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+
+ }
+
+ dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b);
+ dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b);
+ dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128);
+ dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128);
+
+
+ if (pilots==0) {
+ dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b);
+ dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128);
+ }
}
-
+
mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]);
- //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
+ //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]);
- //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
+ //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
- //mmtmpD0 = [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])]
-
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ //mmtmpD0 = [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])]
+
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]);
//mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]);
//mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
//mmtmpD1 = [-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])]
-
+
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
rxdataF_comp0_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
+
mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]);
mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]);
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
-
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]);
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]);
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
-
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
rxdataF_comp0_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
+
// second stream
mmtmpD0 = vmull_s16(dl_ch1_128[0], rxdataF128[0]);
mmtmpD1 = vmull_s16(dl_ch1_128[1], rxdataF128[1]);
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]);
-
+
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]);
//mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
//mmtmpD1 = [-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])]
-
+
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
rxdataF_comp1_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
+
mmtmpD0 = vmull_s16(dl_ch1_128[2], rxdataF128[2]);
mmtmpD1 = vmull_s16(dl_ch1_128[3], rxdataF128[3]);
mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
-
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]);
mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]);
mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
-
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
rxdataF_comp1_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
-
+
if (pilots==0) {
- mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]);
- mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]);
- mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
-
- mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
- mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
- mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
-
-
- mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
- mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
- rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
- mmtmpD0 = vmull_s16(dl_ch1_128[4], rxdataF128[4]);
- mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]);
- mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
- vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
-
- mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
- mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
- mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
- vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
-
-
- mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
- mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
- rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]);
+ mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]);
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
+
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ mmtmpD0 = vmull_s16(dl_ch1_128[4], rxdataF128[4]);
+ mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]);
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
+
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
}
}
-
-
-
+
+
+
Nre = (pilots==0) ? 12 : 8;
// rx_antennas
@@ -2513,11 +2769,9 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
Nre = (pilots==0) ? 12 : 8;
precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
- (nb_rb*Nre))) - (measurements->n0_power[aarx]));
-
+ (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre],
- (nb_rb*Nre))) - (measurements->n0_power[aarx]));
-
+ (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,measurements->n0_power_tot);
measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,measurements->n0_power_tot);
@@ -2525,6 +2779,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
#endif
}
+
void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
unsigned short nb_rb,
@@ -2552,6 +2807,9 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
for (aarx=0; aarxnb_antennas_rx; aarx++) {
+
+
+ //printf ("antenna %d", aarx);
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
if (dl_ch_estimates_ext_i == NULL) // TM3/4
@@ -2582,7 +2840,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
// print_ints("c0",&mmtmpD2);
// print_ints("c1",&mmtmpD3);
dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
-
+ // print_shorts("rho 0:",dl_ch_rho128);
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
@@ -2597,7 +2855,9 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
+
if (pilots==0) {
+
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
@@ -2612,15 +2872,17 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
- dl_ch128+=3;
+ dl_ch128+=3;
dl_ch128i+=3;
dl_ch_rho128+=3;
} else {
+
dl_ch128+=2;
dl_ch128i+=2;
dl_ch_rho128+=2;
}
}
+
}
_mm_empty();
@@ -2631,6 +2893,128 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
#endif
}
+
+/*void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms,
+ unsigned char symbol,
+ unsigned short nb_rb,
+ int **dl_ch_estimates_ext,
+ int **dl_ch_estimates_ext_i,
+ int **dl_ch_rho_ext,
+ unsigned char output_shift0,
+ unsigned char output_shift1)
+{
+
+#if defined(__x86_64__)||defined(__i386__)
+
+ unsigned short rb;
+ __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
+ unsigned char aarx,symbol_mod,pilots=0;
+ int output_shift;
+
+ // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol);
+
+ symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+ if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
+ pilots=1;
+ }
+
+ // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i);
+
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+
+ if (aarx==0) {
+ output_shift=output_shift0;
+ }
+ else {
+ output_shift=output_shift1;
+ }
+
+ //printf ("antenna %d", aarx);
+ dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
+
+ if (dl_ch_estimates_ext_i == NULL) // TM3/4
+ dl_ch128i = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
+ else
+ 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];
+
+
+ for (rb=0; rbN_RB_DL*12];
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
- for (i=0; iN_RB_DL*12];
rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
-
- for (i=0; irxdataF_comp0;
+ int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round];
+ int **dl_ch_rho_ext = pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for second stream
+ int **dl_ch_rho2_ext = pdsch_vars->dl_ch_rho2_ext;
+ int **dl_ch_mag0 = pdsch_vars->dl_ch_mag0;
+ int **dl_ch_mag1 = pdsch_vars->dl_ch_mag1[harq_pid][round];
+ int **dl_ch_magb0 = pdsch_vars->dl_ch_magb0;
+ int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1[harq_pid][round];
+
+ if (frame_parms->nb_antennas_rx>1) {
+
+ rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12];
+ rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[1][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[0][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[1][symbol*frame_parms->N_RB_DL*12];
+
+ // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
+ for (i=0;iN_RB_DL*12];
+ rho128_1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12];
+ for (i=0;iN_RB_DL*12];
+ rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12];
+ rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12];
+ rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_i1 = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_i0b = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12];
+ dl_ch_mag128_i1b = (__m128i *)&dl_ch_magb1[1][symbol*frame_parms->N_RB_DL*12];
+ for (i=0;isqrt_rho_b) : (dlsch[0]->sqrt_rho_a));
- // LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
+ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a));
+
+ LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
+ // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
@@ -2801,7 +3272,8 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext,
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
- for (rb=0; rb=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
@@ -2848,19 +3322,18 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
- for (rb=0; rbNcp-1)))&&(frame_parms->mode1_flag==0)) {
dl_ch128+=2;
- } else {
+ }
+ else {
avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
dl_ch128+=3;
}
-
/*
if (rb==0) {
print_shorts("dl_ch128",&dl_ch128[0]);
@@ -2882,7 +3355,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
((int*)&avg128D)[2] +
((int*)&avg128D)[3])/(nb_rb*nre);
- // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
+ // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
}
_mm_empty();
@@ -2950,14 +3423,157 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
}
//compute average channel_level of effective (precoded) channel
-void dlsch_channel_level_TM3(int **dl_ch_estimates_ext,
- LTE_DL_FRAME_PARMS *frame_parms,
- int *avg,
- uint8_t symbol,
- unsigned short nb_rb)
-{
+
+//compute average channel_level of effective (precoded) channel
+void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ unsigned char *pmi_ext,
+ int *avg_0,
+ int *avg_1,
+ uint8_t symbol,
+ unsigned short nb_rb,
+ MIMO_mode_t mimo_mode){
+
#if defined(__x86_64__)||defined(__i386__)
+
+ short rb;
+ unsigned char aarx,nre=12,symbol_mod;
+ __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp, avg_0_128D, avg_1_128D;
+
+ symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+ //clear average level
+ // avg_0_128D = _mm_setzero_si128();
+ // avg_1_128D = _mm_setzero_si128();
+ avg_0[0] = 0;
+ avg_0[1] = 0;
+ avg_1[0] = 0;
+ avg_1[1] = 0;
+ // 5 is always a symbol with no pilots for both normal and extended prefix
+
+ if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0))
+ nre=8;
+ else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1))
+ nre=10;
+ else
+ nre=12;
+
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
+ dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
+
+ avg_0_128D = _mm_setzero_si128();
+ avg_1_128D = _mm_setzero_si128();
+ for (rb=0; rbNcp-1)))&&(frame_parms->mode1_flag==0)) {
+ dl_ch0_128+=2;
+ dl_ch1_128+=2;
+ }
+ else {
+ dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]);
+ dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]);
+
+ if (mimo_mode==LARGE_CDD)
+ prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
+ prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
+ prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING)
+ prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
+
+ avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp));
+ avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
+
+ dl_ch0_128+=3;
+ dl_ch1_128+=3;
+ }
+ }
+
+
+
+ avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) +
+ (((int*)&avg_0_128D)[1])/(nb_rb*nre) +
+ (((int*)&avg_0_128D)[2])/(nb_rb*nre) +
+ (((int*)&avg_0_128D)[3])/(nb_rb*nre);
+ // printf("From Chan_level aver stream 0 %d =%d\n", aarx, avg_0[aarx]);
+
+ avg_1[aarx] = (((int*)&avg_1_128D)[0])/(nb_rb*nre) +
+ (((int*)&avg_1_128D)[1])/(nb_rb*nre) +
+ (((int*)&avg_1_128D)[2])/(nb_rb*nre) +
+ (((int*)&avg_1_128D)[3])/(nb_rb*nre);
+ // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]);
+ }
+//avg_0[0] = max(avg_0[0],avg_0[1]);
+//avg_1[0] = max(avg_1[0],avg_1[1]);
+//avg_0[0]= max(avg_0[0], avg_1[0]);
+
+ avg_0[0] = avg_0[0] + avg_0[1];
+ // printf("From Chan_level aver stream 0 final =%d\n", avg_0[0]);
+ avg_1[0] = avg_1[0] + avg_1[1];
+ // printf("From Chan_level aver stream 1 final =%d\n", avg_1[0]);
+ avg_0[0] = min (avg_0[0], avg_1[0]);
+ avg_1[0] = avg_0[0];
+
+ _mm_empty();
+ _m_empty();
+
+#elif defined(__arm__)
+
+#endif
+}
+
+
+
+/*void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ int *avg,
+ uint8_t symbol,
+ unsigned short nb_rb,
+ MIMO_mode_t mimo_mode){
+
+#if defined(__x86_64__)||defined(__i386__)
+
+
short rb;
unsigned char aarx,nre=12,symbol_mod;
__m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D;
@@ -2986,26 +3602,45 @@ void dlsch_channel_level_TM3(int **dl_ch_estimates_ext,
dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]);
dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]);
- prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ if (mimo_mode==LARGE_CDD)
+ prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
+ prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
+ prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+
// mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]);
dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]);
- prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ if (mimo_mode==LARGE_CDD)
+ prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
+ prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
+ prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+
// mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
dl_ch0_128+=2;
dl_ch1_128+=2;
- } else {
+ }
+ else {
dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]);
dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]);
- prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
- // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
+ if (mimo_mode==LARGE_CDD)
+ prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
+ prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+ else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
+ prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
+
+ // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
dl_ch0_128+=3;
@@ -3028,7 +3663,7 @@ void dlsch_channel_level_TM3(int **dl_ch_estimates_ext,
#elif defined(__arm__)
#endif
-}
+}*/
//compute average channel_level of effective (precoded) channel
void dlsch_channel_level_TM56(int **dl_ch_estimates_ext,
@@ -3083,12 +3718,13 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext,
if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
dl_ch0_128+=2;
dl_ch1_128+=2;
- } else {
+ }
+ else {
dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]);
dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]);
prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
- // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
+ // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
dl_ch0_128+=3;
@@ -3184,7 +3820,7 @@ void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext,
#endif
}
-
+//#define ONE_OVER_2_Q15 16384
void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp,
int **dl_ch_mag,
@@ -3196,14 +3832,15 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
#if defined(__x86_64__)||defined(__i386__)
short *rxF0,*rxF1;
- __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b, amp, *rxF0_128;
+ __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b, *rxF0_128;
unsigned char rb,re;
int jj = (symbol*frame_parms->N_RB_DL*12);
uint8_t symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
uint8_t pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0;
rxF0_128 = (__m128i*) &rxdataF_comp[0][jj];
- amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
+ //amp = _mm_set1_epi16(ONE_OVER_2_Q15);
+
// printf("Doing alamouti!\n");
rxF0 = (short*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y
@@ -3212,7 +3849,7 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
ch_mag1 = (__m128i *)&dl_ch_mag[2][jj];
ch_mag0b = (__m128i *)&dl_ch_magb[0][jj];
ch_mag1b = (__m128i *)&dl_ch_magb[2][jj];
-
+
for (rb=0; rbfirst_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs
- for (rb=0; rbN_RB_DL; rb++) {
+
+ for (rb=0;rbN_RB_DL;rb++) {
if (rb < 32)
rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
@@ -3352,7 +3998,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
else
rb_alloc_ind = 0;
- if (rb_alloc_ind == 1)
+ if (rb_alloc_ind == 1)
nb_rb++;
// For second half of RBs skip DC carrier
@@ -3391,17 +4037,17 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
/*
- printf("rb %d\n",rb);
- for (i=0;i<12;i++)
- printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
- printf("\n");
+ printf("rb %d\n",rb);
+ for (i=0;i<12;i++)
+ printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
+ printf("\n");
*/
if (pilots==0) {
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
/*
- printf("%d : (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),
- ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/
+ printf("%d : (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),
+ ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/
}
dl_ch0_ext+=12;
@@ -3433,7 +4079,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
else { // Odd number of RBs
for (rb=0; rbN_RB_DL>>1; rb++) {
#ifdef DEBUG_DLSCH_DEMOD
- printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
+ printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
#endif
skip_half=0;
@@ -3448,8 +4094,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
else
rb_alloc_ind = 0;
- if (rb_alloc_ind == 1)
- nb_rb++;
+ if (rb_alloc_ind == 1)
+ nb_rb++;
+
// PBCH
if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
@@ -3470,7 +4117,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
(l==sss_symb) ) {
rb_alloc_ind = 0;
}
-
//SSS
if (((subframe==0)||(subframe==5)) &&
(rb==((frame_parms->N_RB_DL>>1)-3)) &&
@@ -3483,10 +4129,11 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
//PSS in subframe 0/5 if FDD
if (frame_parms->frame_type == FDD) { //FDD
- if (((subframe==0)||(subframe==5)) &&
- (rb>((frame_parms->N_RB_DL>>1)-3)) &&
- (rb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==pss_symb) ) {
+
+ if (((subframe==0)||(subframe==5)) &&
+ (rb>((frame_parms->N_RB_DL>>1)-3)) &&
+ (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==pss_symb) ) {
rb_alloc_ind = 0;
}
@@ -3497,11 +4144,10 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
}
if ((frame_parms->frame_type == TDD) &&
- (subframe==6)) { //TDD Subframe 6
+ (subframe==6)){ //TDD Subframe 6
if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
rb_alloc_ind = 0;
}
-
if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
skip_half=1;
else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
@@ -3510,20 +4156,21 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
if (rb_alloc_ind==1) {
+
#ifdef DEBUG_DLSCH_DEMOD
- printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
+ printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
#endif
if (pilots==0) {
- // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+ // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
if (skip_half==1) {
memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));
for (i=0; i<6; i++) {
- rxF_ext[i]=rxF[i];
+ rxF_ext[i]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- }
+ }
dl_ch0_ext+=6;
rxF_ext+=6;
} else if (skip_half==2) {
@@ -3532,9 +4179,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
for (i=0; i<6; i++) {
rxF_ext[i]=rxF[(i+6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- }
+ }
dl_ch0_ext+=6;
rxF_ext+=6;
} else {
@@ -3545,12 +4192,12 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
#ifdef DEBUG_DLSCH_DEMOD
printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- }
+ }
dl_ch0_ext+=12;
rxF_ext+=12;
}
} else {
- // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+ // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
j=0;
if (skip_half==1) {
@@ -3563,14 +4210,14 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
dl_ch0_ext[j++]=dl_ch0[i];
}
}
- rxF_ext+=5;
+ rxF_ext+=5;
dl_ch0_ext+=5;
} else if (skip_half==2) {
for (i=0; i<6; i++) {
if (i!=((frame_parms->nushift+poffset)%6)) {
rxF_ext[j]=rxF[(i+6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
dl_ch0_ext[j++]=dl_ch0[i+6];
}
@@ -3584,7 +4231,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
(i!=((frame_parms->nushift+poffset+6)%12))) {
rxF_ext[j]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
dl_ch0_ext[j++]=dl_ch0[i];
@@ -3596,7 +4243,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
}
}
}
-
dl_ch0+=12;
rxF+=12;
} // first half loop
@@ -3616,12 +4262,13 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
if (rb_alloc_ind == 1)
- nb_rb++;
+ nb_rb++;
// PBCH
- if ((subframe==0) &&
- (l>=(nsymb>>1)) &&
- (l<((nsymb>>1) + 4))) {
+
+ if ((subframe==0) &&
+ (l>=(nsymb>>1)) &&
+ (l<((nsymb>>1) + 4))) {
rb_alloc_ind = 0;
}
@@ -3640,16 +4287,16 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
//PSS
if ((frame_parms->frame_type == TDD) &&
(subframe==6) &&
- (l==pss_symb) ) {
- rb_alloc_ind = 0;
+ (l==pss_symb) ) {
+ rb_alloc_ind = 0;
}
-
+
// printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
// printf("DC rb %d (%p)\n",rb,rxF);
if (rb_alloc_ind==1) {
#ifdef DEBUG_DLSCH_DEMOD
- printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
+ printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
#endif
if (pilots==0) {
for (i=0; i<6; i++) {
@@ -3687,14 +4334,13 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
rxF_ext[j++]=rxF[(1+i-6)];
#ifdef DEBUG_DLSCH_DEMOD
printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
-#endif
+#endif
}
}
dl_ch0_ext+=10;
rxF_ext+=10;
} // symbol_mod==0
-
} // rballoc==1
else {
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
@@ -3704,9 +4350,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
rxF+=7;
rb++;
- for (; rbN_RB_DL; rb++) {
- // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
- // printf("rb %d (%p)\n",rb,rxF);
+ for (;rbN_RB_DL;rb++) {
+ // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
+ // printf("rb %d (%p)\n",rb,rxF);
skip_half=0;
if (rb < 32)
@@ -3720,14 +4366,13 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
else
rb_alloc_ind = 0;
- if (rb_alloc_ind == 1)
- nb_rb++;
+ if (rb_alloc_ind == 1)
+ nb_rb++;
// PBCH
if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
rb_alloc_ind = 0;
}
-
//PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
skip_half=1;
@@ -3738,13 +4383,11 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
rb_alloc_ind = 0;
}
-
//SSS
if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb))
skip_half=1;
else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb))
skip_half=2;
-
if (frame_parms->frame_type == FDD) {
//PSS
if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
@@ -3752,6 +4395,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
}
//PSS
+
if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
skip_half=1;
else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
@@ -3759,6 +4403,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
}
if ((frame_parms->frame_type == TDD) &&
+
(subframe==6)) { //TDD Subframe 6
if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
rb_alloc_ind = 0;
@@ -3771,26 +4416,26 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
}
if (rb_alloc_ind==1) {
-#ifdef DEBUG_DLSCH_DEMOD
- printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
+#ifdef DEBUG_DLSCH_DEMOD
+ printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
#endif
/*
- printf("rb %d\n",rb);
+ printf("rb %d\n",rb);
for (i=0;i<12;i++)
printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
printf("\n");
*/
if (pilots==0) {
- // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+ // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
if (skip_half==1) {
memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));
for (i=0; i<6; i++) {
rxF_ext[i]=rxF[i];
-#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#ifdef DEBUG_DLSCH_DEMOD
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- }
+ }
dl_ch0_ext+=6;
rxF_ext+=6;
@@ -3800,9 +4445,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
for (i=0; i<6; i++) {
rxF_ext[i]=rxF[(i+6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- }
+ }
dl_ch0_ext+=6;
rxF_ext+=6;
@@ -3812,14 +4457,14 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- }
+ }
dl_ch0_ext+=12;
rxF_ext+=12;
}
} else {
- // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+ // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
j=0;
if (skip_half==1) {
@@ -3827,7 +4472,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
if (i!=((frame_parms->nushift+poffset)%6)) {
rxF_ext[j]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
dl_ch0_ext[j++]=dl_ch0[i];
}
@@ -3840,7 +4485,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
if (i!=((frame_parms->nushift+poffset)%6)) {
rxF_ext[j]=rxF[(i+6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
dl_ch0_ext[j++]=dl_ch0[i+6];
}
@@ -3854,12 +4499,11 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
(i!=((frame_parms->nushift+poffset+6)%12))) {
rxF_ext[j]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
dl_ch0_ext[j++]=dl_ch0[i];
}
}
-
dl_ch0_ext+=10;
rxF_ext+=10;
}
@@ -3871,7 +4515,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF,
}
}
}
-
+
return(nb_rb/frame_parms->nb_antennas_rx);
}
@@ -3886,9 +4530,8 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
unsigned char symbol,
unsigned char subframe,
uint32_t high_speed_flag,
- LTE_DL_FRAME_PARMS *frame_parms)
-{
-
+ LTE_DL_FRAME_PARMS *frame_parms,
+ MIMO_mode_t mimo_mode) {
int prb,nb_rb=0;
int prb_off,prb_off2;
@@ -3926,7 +4569,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
}
pmi_loc = pmi_ext;
-
+
// pointers to extracted RX signals and channel estimates
rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
@@ -3934,95 +4577,102 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
for (prb=0; prbN_RB_DL; prb++) {
skip_half=0;
-
+
if (prb < 32)
- rb_alloc_ind = (rb_alloc[0]>>prb) & 1;
+ rb_alloc_ind = (rb_alloc[0]>>prb) & 1;
else if (prb < 64)
- rb_alloc_ind = (rb_alloc[1]>>(prb-32)) & 1;
+ rb_alloc_ind = (rb_alloc[1]>>(prb-32)) & 1;
else if (prb < 96)
- rb_alloc_ind = (rb_alloc[2]>>(prb-64)) & 1;
+ rb_alloc_ind = (rb_alloc[2]>>(prb-64)) & 1;
else if (prb < 100)
- rb_alloc_ind = (rb_alloc[3]>>(prb-96)) & 1;
+ rb_alloc_ind = (rb_alloc[3]>>(prb-96)) & 1;
else
- rb_alloc_ind = 0;
+ rb_alloc_ind = 0;
if (rb_alloc_ind == 1)
nb_rb++;
-
+
if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs
- // PBCH
- if ((subframe==0) &&
- (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l>=(nsymb>>1)) &&
- (l<((nsymb>>1) + 4))) {
- rb_alloc_ind = 0;
- // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb);
- }
-
- //SSS
-
- if (((subframe==0)||(subframe==5)) &&
- (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==sss_symb) ) {
- rb_alloc_ind = 0;
- // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb);
- }
-
-
-
- //PSS in subframe 0/5 if FDD
- if (frame_parms->frame_type == FDD) { //FDD
- if (((subframe==0)||(subframe==5)) &&
- (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==pss_symb) ) {
- rb_alloc_ind = 0;
- // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb);
- }
- }
-
- if ((frame_parms->frame_type == TDD) &&
- (subframe==6)) { //TDD Subframe 6
- if ((prb>=((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==pss_symb) ) {
- rb_alloc_ind = 0;
- }
- }
-
- if (rb_alloc_ind==1) { // PRB is allocated
+ // PBCH
+ if ((subframe==0) &&
+ (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l>=(nsymb>>1)) &&
+ (l<((nsymb>>1) + 4))) {
+ rb_alloc_ind = 0;
+ // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb);
+ }
+
+ //SSS
+
+ if (((subframe==0)||(subframe==5)) &&
+ (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==sss_symb) ) {
+ rb_alloc_ind = 0;
+ // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb);
+ }
-
- prb_off = 12*prb;
- prb_off2 = 1+(12*(prb-(frame_parms->N_RB_DL>>1)));
- dl_ch0p = dl_ch0+(12*prb);
- dl_ch1p = dl_ch1+(12*prb);
- if (prb<(frame_parms->N_RB_DL>>1)){
- rxF = &rxdataF[aarx][prb_off+
- frame_parms->first_carrier_offset +
- (symbol*(frame_parms->ofdm_symbol_size))];
- }
- else {
- rxF = &rxdataF[aarx][prb_off2+
- (symbol*(frame_parms->ofdm_symbol_size))];
- }
+
+ //PSS in subframe 0/5 if FDD
+ if (frame_parms->frame_type == FDD) { //FDD
+ if (((subframe==0)||(subframe==5)) &&
+ (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==pss_symb) ) {
+ rb_alloc_ind = 0;
+ // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb);
+ }
+ }
+
+ if ((frame_parms->frame_type == TDD) &&
+ (subframe==6)) { //TDD Subframe 6
+ if ((prb>=((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==pss_symb) ) {
+ rb_alloc_ind = 0;
+ }
+ }
+
+ if (rb_alloc_ind==1) { // PRB is allocated
+
+
+
+ prb_off = 12*prb;
+ prb_off2 = 1+(12*(prb-(frame_parms->N_RB_DL>>1)));
+ dl_ch0p = dl_ch0+(12*prb);
+ dl_ch1p = dl_ch1+(12*prb);
+ if (prb<(frame_parms->N_RB_DL>>1)){
+ rxF = &rxdataF[aarx][prb_off+
+ frame_parms->first_carrier_offset +
+ (symbol*(frame_parms->ofdm_symbol_size))];
+ }
+ else {
+ rxF = &rxdataF[aarx][prb_off2+
+ (symbol*(frame_parms->ofdm_symbol_size))];
+ }
+
+ /*
+ if (mimo_mode <= PUSCH_PRECODING1)
*pmi_loc = (pmi>>((prb>>2)<<1))&3;
+ else
+ *pmi_loc=(pmi>>prb)&1;*/
+
+ *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb);
pmi_loc++;
-
-
+
+
if (pilots == 0) {
-
+
memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int));
memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int));
memcpy(rxF_ext,rxF,12*sizeof(int));
- dl_ch0_ext +=12;
- dl_ch1_ext +=12;
- rxF_ext +=12;
+ dl_ch0_ext +=12;
+ dl_ch1_ext +=12;
+ rxF_ext +=12;
} else { // pilots==1
j=0;
for (i=0; i<12; i++) {
@@ -4036,280 +4686,283 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
dl_ch1_ext[j++]=dl_ch1p[i];
}
}
- dl_ch0_ext+=8;
- dl_ch1_ext+=8;
- rxF_ext+=8;
+ dl_ch0_ext+=8;
+ dl_ch1_ext+=8;
+ rxF_ext+=8;
} // pilots==1
- }
+ }
} else { // Odd number of RBs
// PBCH
- if ((subframe==0) &&
- (prb>((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l>=(nsymb>>1)) &&
- (l<((nsymb>>1) + 4))) {
- rb_alloc_ind = 0;
- // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb);
- }
-
- //SSS
-
- if (((subframe==0)||(subframe==5)) &&
- (prb>((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==sss_symb) ) {
- rb_alloc_ind = 0;
- // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb);
- }
-
-
-
- //PSS in subframe 0/5 if FDD
- if (frame_parms->frame_type == FDD) { //FDD
- if (((subframe==0)||(subframe==5)) &&
- (prb>((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==pss_symb) ) {
- rb_alloc_ind = 0;
- // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb);
- }
- }
-
- if ((frame_parms->frame_type == TDD) &&
- ((subframe==1) || (subframe==6))) { //TDD Subframe 1-6
- if ((prb>((frame_parms->N_RB_DL>>1)-3)) &&
- (prb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==pss_symb) ) {
- rb_alloc_ind = 0;
- }
- }
+ if ((subframe==0) &&
+ (prb>((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l>=(nsymb>>1)) &&
+ (l<((nsymb>>1) + 4))) {
+ rb_alloc_ind = 0;
+ // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb);
+ }
- if (rb_alloc_ind == 1) {
- skip_half=0;
-
- //Check if we have to drop half a PRB due to PSS/SSS/PBCH
- // skip_half == 0 means full PRB
- // skip_half == 1 means first half is used (leftmost half-PRB from PSS/SSS/PBCH)
- // skip_half == 2 means second half is used (rightmost half-PRB from PSS/SSS/PBCH)
- //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
- if ((subframe==0) &&
- (prb==((frame_parms->N_RB_DL>>1)-3)) &&
- (l>=(nsymb>>1)) &&
- (l<((nsymb>>1) + 4)))
- skip_half=1;
- else if ((subframe==0) &&
- (prb==((frame_parms->N_RB_DL>>1)+3)) &&
- (l>=(nsymb>>1)) &&
- (l<((nsymb>>1) + 4)))
- skip_half=2;
-
- //SSS
- if (((subframe==0)||(subframe==5)) &&
- (prb==((frame_parms->N_RB_DL>>1)-3)) &&
- (l==sss_symb))
- skip_half=1;
- else if (((subframe==0)||(subframe==5)) &&
- (prb==((frame_parms->N_RB_DL>>1)+3)) &&
- (l==sss_symb))
- skip_half=2;
-
- //PSS Subframe 0,5
- if (((frame_parms->frame_type == FDD) &&
- (((subframe==0)||(subframe==5)))) || //FDD Subframes 0,5
- ((frame_parms->frame_type == TDD) &&
- (((subframe==1) || (subframe==6))))) { //TDD Subframes 1,6
-
- if ((prb==((frame_parms->N_RB_DL>>1)-3)) &&
- (l==pss_symb))
- skip_half=1;
- else if ((prb==((frame_parms->N_RB_DL>>1)+3)) &&
- (l==pss_symb))
- skip_half=2;
- }
-
-
- prb_off = 12*prb;
- prb_off2 = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1));
- dl_ch0p = dl_ch0+(12*prb);
- dl_ch1p = dl_ch1+(12*prb);
-
- if (prb<=(frame_parms->N_RB_DL>>1)){
- rxF = &rxdataF[aarx][prb_off+
- frame_parms->first_carrier_offset +
- (symbol*(frame_parms->ofdm_symbol_size))];
- }
- else {
- rxF = &rxdataF[aarx][prb_off2+
- (symbol*(frame_parms->ofdm_symbol_size))];
- }
+ //SSS
+
+ if (((subframe==0)||(subframe==5)) &&
+ (prb>((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==sss_symb) ) {
+ rb_alloc_ind = 0;
+ // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb);
+ }
+
+
+
+ //PSS in subframe 0/5 if FDD
+ if (frame_parms->frame_type == FDD) { //FDD
+ if (((subframe==0)||(subframe==5)) &&
+ (prb>((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==pss_symb) ) {
+ rb_alloc_ind = 0;
+ // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb);
+ }
+ }
+
+ if ((frame_parms->frame_type == TDD) &&
+ ((subframe==1) || (subframe==6))) { //TDD Subframe 1-6
+ if ((prb>((frame_parms->N_RB_DL>>1)-3)) &&
+ (prb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==pss_symb) ) {
+ rb_alloc_ind = 0;
+ }
+ }
+
+ if (rb_alloc_ind == 1) {
+ skip_half=0;
+
+ //Check if we have to drop half a PRB due to PSS/SSS/PBCH
+ // skip_half == 0 means full PRB
+ // skip_half == 1 means first half is used (leftmost half-PRB from PSS/SSS/PBCH)
+ // skip_half == 2 means second half is used (rightmost half-PRB from PSS/SSS/PBCH)
+ //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
+ if ((subframe==0) &&
+ (prb==((frame_parms->N_RB_DL>>1)-3)) &&
+ (l>=(nsymb>>1)) &&
+ (l<((nsymb>>1) + 4)))
+ skip_half=1;
+ else if ((subframe==0) &&
+ (prb==((frame_parms->N_RB_DL>>1)+3)) &&
+ (l>=(nsymb>>1)) &&
+ (l<((nsymb>>1) + 4)))
+ skip_half=2;
+
+ //SSS
+ if (((subframe==0)||(subframe==5)) &&
+ (prb==((frame_parms->N_RB_DL>>1)-3)) &&
+ (l==sss_symb))
+ skip_half=1;
+ else if (((subframe==0)||(subframe==5)) &&
+ (prb==((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==sss_symb))
+ skip_half=2;
+
+ //PSS Subframe 0,5
+ if (((frame_parms->frame_type == FDD) &&
+ (((subframe==0)||(subframe==5)))) || //FDD Subframes 0,5
+ ((frame_parms->frame_type == TDD) &&
+ (((subframe==1) || (subframe==6))))) { //TDD Subframes 1,6
+
+ if ((prb==((frame_parms->N_RB_DL>>1)-3)) &&
+ (l==pss_symb))
+ skip_half=1;
+ else if ((prb==((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==pss_symb))
+ skip_half=2;
+ }
+
+
+ prb_off = 12*prb;
+ prb_off2 = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1));
+ dl_ch0p = dl_ch0+(12*prb);
+ dl_ch1p = dl_ch1+(12*prb);
+
+ if (prb<=(frame_parms->N_RB_DL>>1)){
+ rxF = &rxdataF[aarx][prb_off+
+ frame_parms->first_carrier_offset +
+ (symbol*(frame_parms->ofdm_symbol_size))];
+ }
+ else {
+ rxF = &rxdataF[aarx][prb_off2+
+ (symbol*(frame_parms->ofdm_symbol_size))];
+ }
#ifdef DEBUG_DLSCH_DEMOD
- printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2);
+ printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2);
#endif
- *pmi_loc = (pmi>>((prb>>2)<<1))&3;
- // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext);
-
+ /* if (mimo_mode <= PUSCH_PRECODING1)
+ *pmi_loc = (pmi>>((prb>>2)<<1))&3;
+ else
+ *pmi_loc=(pmi>>prb)&1;
+ // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext);
+*/
+ *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb);
pmi_loc++;
- if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC
- if (pilots==0) {
- if (skip_half==1) {
- memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
- memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
- memcpy(rxF_ext,rxF,6*sizeof(int32_t));
+ if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC
+ if (pilots==0) {
+ if (skip_half==1) {
+ memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
+ memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
+ memcpy(rxF_ext,rxF,6*sizeof(int32_t));
#ifdef DEBUG_DLSCH_DEMOD
- for (i=0;i<6;i++)
- printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ for (i=0;i<6;i++)
+ printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- dl_ch0_ext+=6;
- dl_ch1_ext+=6;
- rxF_ext+=6;
- } else if (skip_half==2) {
- memcpy(dl_ch0_ext,dl_ch0p+6,6*sizeof(int32_t));
- memcpy(dl_ch1_ext,dl_ch1p+6,6*sizeof(int32_t));
- memcpy(rxF_ext,rxF+6,6*sizeof(int32_t));
+ dl_ch0_ext+=6;
+ dl_ch1_ext+=6;
+ rxF_ext+=6;
+ } else if (skip_half==2) {
+ memcpy(dl_ch0_ext,dl_ch0p+6,6*sizeof(int32_t));
+ memcpy(dl_ch1_ext,dl_ch1p+6,6*sizeof(int32_t));
+ memcpy(rxF_ext,rxF+6,6*sizeof(int32_t));
#ifdef DEBUG_DLSCH_DEMOD
- for (i=0;i<6;i++)
- printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ for (i=0;i<6;i++)
+ printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- dl_ch0_ext+=6;
- dl_ch1_ext+=6;
- rxF_ext+=6;
- } else { // skip_half==0
- memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int32_t));
- memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int32_t));
- memcpy(rxF_ext,rxF,12*sizeof(int32_t));
+ dl_ch0_ext+=6;
+ dl_ch1_ext+=6;
+ rxF_ext+=6;
+ } else { // skip_half==0
+ memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int32_t));
+ memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int32_t));
+ memcpy(rxF_ext,rxF,12*sizeof(int32_t));
#ifdef DEBUG_DLSCH_DEMOD
- for (i=0;i<12;i++)
- printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ for (i=0;i<12;i++)
+ printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- dl_ch0_ext+=12;
- dl_ch1_ext+=12;
- rxF_ext+=12;
- }
- } else { // pilots=1
- j=0;
-
- if (skip_half==1) {
- for (i=0; i<6; i++) {
- if ((i!=frame_parms->nushift) &&
- (i!=((frame_parms->nushift+3)%6))) {
- rxF_ext[j]=rxF[i];
-#ifdef DEBUG_DLSCH_DEMOD
- printf("(pilots,skip1)extract rb %d, re %d (%d)=> (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
-#endif
- dl_ch0_ext[j]=dl_ch0p[i];
- dl_ch1_ext[j++]=dl_ch1p[i];
- }
- }
- dl_ch0_ext+=4;
- dl_ch1_ext+=4;
- rxF_ext+=4;
- } else if (skip_half==2) {
- for (i=0; i<6; i++) {
- if ((i!=frame_parms->nushift) &&
- (i!=((frame_parms->nushift+3)%6))) {
- rxF_ext[j]=rxF[(i+6)];
-#ifdef DEBUG_DLSCH_DEMOD
- printf("(pilots,skip2)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
-#endif
- dl_ch0_ext[j]=dl_ch0p[i+6];
- dl_ch1_ext[j++]=dl_ch1p[i+6];
- }
- }
- dl_ch0_ext+=4;
- dl_ch1_ext+=4;
- rxF_ext+=4;
+ dl_ch0_ext+=12;
+ dl_ch1_ext+=12;
+ rxF_ext+=12;
+ }
+ } else { // pilots=1
+ j=0;
- } else { //skip_half==0
- for (i=0; i<12; i++) {
- if ((i!=frame_parms->nushift) &&
- (i!=frame_parms->nushift+3) &&
- (i!=frame_parms->nushift+6) &&
- (i!=((frame_parms->nushift+9)%12))) {
- rxF_ext[j]=rxF[i];
+ if (skip_half==1) {
+ for (i=0; i<6; i++) {
+ if ((i!=frame_parms->nushift) &&
+ (i!=((frame_parms->nushift+3)%6))) {
+ rxF_ext[j]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("(pilots)extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+ printf("(pilots,skip1)extract rb %d, re %d (%d)=> (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
- dl_ch0_ext[j] =dl_ch0p[i];
- dl_ch1_ext[j++]=dl_ch1p[i];
- }
- }
- dl_ch0_ext+=8;
- dl_ch1_ext+=8;
- rxF_ext+=8;
- } //skip_half==0
- } //pilots==1
- } else { // Do middle RB (around DC)
-
- if (pilots==0) {
- memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
- memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
- memcpy(rxF_ext,rxF,6*sizeof(int32_t));
+ dl_ch0_ext[j]=dl_ch0p[i];
+ dl_ch1_ext[j++]=dl_ch1p[i];
+ }
+ }
+ dl_ch0_ext+=4;
+ dl_ch1_ext+=4;
+ rxF_ext+=4;
+ } else if (skip_half==2) {
+ for (i=0; i<6; i++) {
+ if ((i!=frame_parms->nushift) &&
+ (i!=((frame_parms->nushift+3)%6))) {
+ rxF_ext[j]=rxF[(i+6)];
#ifdef DEBUG_DLSCH_DEMOD
- for (i=0; i<6; i++) {
- printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
- }
+ printf("(pilots,skip2)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
- rxF_ext+=6;
- dl_ch0_ext+=6;
- dl_ch1_ext+=6;
- dl_ch0p+=6;
- dl_ch1p+=6;
-
- rxF = &rxdataF[aarx][1+((symbol*(frame_parms->ofdm_symbol_size)))];
+ dl_ch0_ext[j]=dl_ch0p[i+6];
+ dl_ch1_ext[j++]=dl_ch1p[i+6];
+ }
+ }
+ dl_ch0_ext+=4;
+ dl_ch1_ext+=4;
+ rxF_ext+=4;
- memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
- memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
- memcpy(rxF_ext,rxF,6*sizeof(int32_t));
+ } else { //skip_half==0
+ for (i=0; i<12; i++) {
+ if ((i!=frame_parms->nushift) &&
+ (i!=frame_parms->nushift+3) &&
+ (i!=frame_parms->nushift+6) &&
+ (i!=((frame_parms->nushift+9)%12))) {
+ rxF_ext[j]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- for (i=0; i<6; i++) {
- printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
- }
+ printf("(pilots)extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
- rxF_ext+=6;
- dl_ch0_ext+=6;
- dl_ch1_ext+=6;
- } else { // pilots==1
- j=0;
-
- for (i=0; i<6; i++) {
- if ((i!=frame_parms->nushift) &&
- (i!=((frame_parms->nushift+3)%6))) {
- dl_ch0_ext[j]=dl_ch0p[i];
- dl_ch1_ext[j]=dl_ch1p[i];
- rxF_ext[j++]=rxF[i];
+ dl_ch0_ext[j] =dl_ch0p[i];
+ dl_ch1_ext[j++]=dl_ch1p[i];
+ }
+ }
+ dl_ch0_ext+=8;
+ dl_ch1_ext+=8;
+ rxF_ext+=8;
+ } //skip_half==0
+ } //pilots==1
+ } else { // Do middle RB (around DC)
+
+ if (pilots==0) {
+ memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
+ memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
+ memcpy(rxF_ext,rxF,6*sizeof(int32_t));
#ifdef DEBUG_DLSCH_DEMOD
- printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[i],*(1+(short*)&rxF[i]));
+ for (i=0; i<6; i++) {
+ printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ }
#endif
- }
- }
- rxF = &rxdataF[aarx][1+symbol*(frame_parms->ofdm_symbol_size)];
-
- for (; i<12; i++) {
- if ((i!=((frame_parms->nushift+6)%12)) &&
- (i!=((frame_parms->nushift+9)%12))) {
- dl_ch0_ext[j]=dl_ch0p[i];
- dl_ch1_ext[j]=dl_ch1p[i];
- rxF_ext[j++]=rxF[i-6];
+ rxF_ext+=6;
+ dl_ch0_ext+=6;
+ dl_ch1_ext+=6;
+ dl_ch0p+=6;
+ dl_ch1p+=6;
+
+ rxF = &rxdataF[aarx][1+((symbol*(frame_parms->ofdm_symbol_size)))];
+
+ memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
+ memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
+ memcpy(rxF_ext,rxF,6*sizeof(int32_t));
#ifdef DEBUG_DLSCH_DEMOD
- printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short*)&rxF[1+i-6]));
+ for (i=0; i<6; i++) {
+ printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ }
#endif
- }
- }
-
- dl_ch0_ext+=8;
- dl_ch1_ext+=8;
- rxF_ext+=8;
- } //pilots==1
- } // if Middle PRB
- } // if odd PRB
+ rxF_ext+=6;
+ dl_ch0_ext+=6;
+ dl_ch1_ext+=6;
+ } else { // pilots==1
+ j=0;
+
+ for (i=0; i<6; i++) {
+ if ((i!=frame_parms->nushift) &&
+ (i!=((frame_parms->nushift+3)%6))) {
+ dl_ch0_ext[j]=dl_ch0p[i];
+ dl_ch1_ext[j]=dl_ch1p[i];
+ rxF_ext[j++]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+ printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[i],*(1+(short*)&rxF[i]));
+#endif
+ }
+ }
+ rxF = &rxdataF[aarx][1+symbol*(frame_parms->ofdm_symbol_size)];
+
+ for (; i<12; i++) {
+ if ((i!=((frame_parms->nushift+6)%12)) &&
+ (i!=((frame_parms->nushift+9)%12))) {
+ dl_ch0_ext[j]=dl_ch0p[i];
+ dl_ch1_ext[j]=dl_ch1p[i];
+ rxF_ext[j++]=rxF[i-6];
+#ifdef DEBUG_DLSCH_DEMOD
+ printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short*)&rxF[1+i-6]));
+#endif
+ }
+ }
+
+ dl_ch0_ext+=8;
+ dl_ch1_ext+=8;
+ rxF_ext+=8;
+ } //pilots==1
+ } // if Middle PRB
+ } // if odd PRB
} // if rballoc==1
- } // for prb
+ } // for prb
} // for aarx
-
return(nb_rb/frame_parms->nb_antennas_rx);
}
@@ -4385,7 +5038,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
else
rb_alloc_ind = 0;
- if (rb_alloc_ind == 1)
+ if (rb_alloc_ind == 1)
nb_rb++;
// For second half of RBs skip DC carrier
@@ -4393,7 +5046,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
//dl_ch0++;
}
-
+
// PBCH
if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
rb_alloc_ind = 0;
@@ -4454,23 +5107,23 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
j=0;
- for (i=0; i<12; i++){
+ for (i=0; i<12; i++){
if (frame_parms->Ncp==0){
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
- rxF_ext[j] = rxF[i];
- dl_ch0_ext[j++]=dl_ch0[i];
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+ rxF_ext[j] = rxF[i];
+ dl_ch0_ext[j++]=dl_ch0[i];
}
} else{
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
- rxF_ext[j] = rxF[i];
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+ rxF_ext[j] = rxF[i];
dl_ch0_ext[j++]=dl_ch0[i];
- }
+ }
}
-
- }
-
+
+ }
+
dl_ch0_ext+=9-frame_parms->Ncp;
- rxF_ext+=9-frame_parms->Ncp;
+ rxF_ext+=9-frame_parms->Ncp;
} else {
msg("dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n");
@@ -4569,7 +5222,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
for (i=0; i<6; i++) {
rxF_ext[i]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
@@ -4581,7 +5234,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
for (i=0; i<6; i++) {
rxF_ext[i]=rxF[(i+6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
@@ -4609,7 +5262,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[i];
dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4622,7 +5275,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[(i+6)];
dl_ch0_ext[j++]=dl_ch0[i+6];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4656,7 +5309,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[i];
dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4665,11 +5318,11 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
} else{
for (i=0; i<6; i++) {
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
rxF_ext[j]=rxF[i];
dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4684,7 +5337,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[(i+6)];
dl_ch0_ext[j++]=dl_ch0[i+6];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4693,11 +5346,11 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
} else {
for (i=0; i<6; i++) {
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
rxF_ext[j]=rxF[(i+6)];
dl_ch0_ext[j++]=dl_ch0[i+6];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4707,35 +5360,35 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
} else {
- for (i=0; i<12; i++){
+ for (i=0; i<12; i++){
if (frame_parms->Ncp==0){
if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
- rxF_ext[j] = rxF[i];
- dl_ch0_ext[j++] = dl_ch0[i];
+ rxF_ext[j] = rxF[i];
+ dl_ch0_ext[j++] = dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
printf("extract rb %d, re %d, j %d => (%d,%d)\n",symbol,rb,i,j-1,*(short *)&dl_ch0[j],*(1+(short*)&dl_ch0[i]));
#endif
}
} else{
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
- rxF_ext[j] = rxF[i];
- dl_ch0_ext[j++]=dl_ch0[i];
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+ rxF_ext[j] = rxF[i];
+ dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
- }
+ }
}
-
- }
-
+
+ }
+
dl_ch0_ext+=9-frame_parms->Ncp;
- rxF_ext+=9-frame_parms->Ncp;
- }
-
+ rxF_ext+=9-frame_parms->Ncp;
+ }
+
} else {
msg("dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n");
exit(-1);
-
+
}
}
@@ -4792,7 +5445,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
dl_ch0_ext[i]=dl_ch0[i];
rxF_ext[i]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
@@ -4802,7 +5455,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
dl_ch0_ext[i]=dl_ch0[i];
rxF_ext[i]=rxF[(1+i-6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
@@ -4816,7 +5469,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
dl_ch0_ext[j]=dl_ch0[i];
rxF_ext[j++]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4828,7 +5481,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
dl_ch0_ext[j]=dl_ch0[i];
rxF_ext[j++]=rxF[(1+i-6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -4838,52 +5491,52 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
} else if(pilots==0 && uespec_pilots==1) {
j=0;
- for (i=0; i<6; i++) {
+ for (i=0; i<6; i++) {
if (frame_parms->Ncp==0){
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
- dl_ch0_ext[j]=dl_ch0[i];
- rxF_ext[j++] = rxF[i];
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+ dl_ch0_ext[j]=dl_ch0[i];
+ rxF_ext[j++] = rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
} else {
if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
- dl_ch0_ext[j]=dl_ch0[i];
- rxF_ext[j++] = rxF[i];
+ dl_ch0_ext[j]=dl_ch0[i];
+ rxF_ext[j++] = rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
- }
-
+ }
+
rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
for (; i<12; i++) {
if (frame_parms->Ncp==0){
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
dl_ch0_ext[j]=dl_ch0[i];
rxF_ext[j++]=rxF[(1+i-6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
} else {
if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
- dl_ch0_ext[j]=dl_ch0[i];
- rxF_ext[j++] = rxF[(1+i-6)];
+ dl_ch0_ext[j]=dl_ch0[i];
+ rxF_ext[j++] = rxF[(1+i-6)];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
}
-
+
dl_ch0_ext+=9-frame_parms->Ncp;
- rxF_ext+=9-frame_parms->Ncp;
-
- }// symbol_mod==0
+ rxF_ext+=9-frame_parms->Ncp;
+
+ }// symbol_mod==0
} // rballoc==1
else {
@@ -4976,7 +5629,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
for (i=0; i<6; i++) {
rxF_ext[i]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
@@ -4989,7 +5642,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
for (i=0; i<6; i++) {
rxF_ext[i]=rxF[i+6];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
@@ -5003,7 +5656,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
@@ -5020,7 +5673,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[i];
dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -5033,7 +5686,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[(i+6)];
dl_ch0_ext[j++]=dl_ch0[i+6];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -5065,7 +5718,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[i];
dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -5074,11 +5727,11 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
} else{
for (i=0; i<6; i++) {
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
rxF_ext[j]=rxF[i];
dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -5093,7 +5746,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
rxF_ext[j]=rxF[i+6];
dl_ch0_ext[j++]=dl_ch0[i+6];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -5102,11 +5755,11 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
} else {
for (i=0; i<6; i++) {
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
rxF_ext[j]=rxF[(i+6)];
dl_ch0_ext[j++]=dl_ch0[i+6];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
@@ -5115,31 +5768,31 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
}
} else {
- for (i=0; i<12; i++){
+ for (i=0; i<12; i++){
if (frame_parms->Ncp==0){
if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
- rxF_ext[j] = rxF[i];
- dl_ch0_ext[j++]=dl_ch0[i];
+ rxF_ext[j] = rxF[i];
+ dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
} else{
- if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
- rxF_ext[j] = rxF[i];
- dl_ch0_ext[j++]=dl_ch0[i];
+ if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+ rxF_ext[j] = rxF[i];
+ dl_ch0_ext[j++]=dl_ch0[i];
#ifdef DEBUG_DLSCH_DEMOD
- printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+ printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
}
}
- }
-
+ }
+
dl_ch0_ext+=9-frame_parms->Ncp;
- rxF_ext+=9-frame_parms->Ncp;
+ rxF_ext+=9-frame_parms->Ncp;
}
-
+
}// pilots=0
}
@@ -5154,16 +5807,14 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
return(nb_rb/frame_parms->nb_antennas_rx);
}
-
-
//==============================================================================================
#ifdef USER_MODE
-void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_bits_per_codeword,int round)
-{
+void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid)
+{
unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
char fname[32],vname[32];
int N_RB_DL=ue->frame_parms.N_RB_DL;
@@ -5222,7 +5873,13 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_
*/
sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round);
sprintf(vname,"dl_rho_r%d_%d",eNB_id,round);
- write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[0],12*N_RB_DL*nsymb,1,1);
+
+ write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
+
+ sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round);
+ sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round);
+
+ write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round);
@@ -5230,7 +5887,7 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_
if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round);
- write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][round],12*N_RB_DL*nsymb,1,1);
+ write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
}
sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round);
@@ -5257,7 +5914,7 @@ void print_bytes(char *s,__m128i *x)
printf("%s : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",s,
tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7],
tempb[8],tempb[9],tempb[10],tempb[11],tempb[12],tempb[13],tempb[14],tempb[15]
- );
+ );
}
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
index 8165bc1f23..0b73e2b023 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -31,11 +31,15 @@
*/
#include "PHY/defs.h"
+#include "PHY/TOOLS/defs.h"
#include "PHY/extern.h"
#include "defs.h"
#include "extern.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 ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
#if defined(__x86_64__) || defined(__i386__)
@@ -633,7 +637,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t nb_rb,
uint16_t pbch_pss_sss_adjust,
int16_t **llr32p,
- uint8_t beamforming_mode)
+ uint8_t beamforming_mode)
{
uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*frame_parms->N_RB_DL*12)];
@@ -667,11 +671,11 @@ 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);
-
+ //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);
+ //printf("ll32p=%p , dlsch_llr=%p, symbol=%d, flag=%d \n", llr32, dlsch_llr, symbol, first_symbol_flag);
for (i=0; iN_RB_DL*12];
+ int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
+ uint16_t amp_tmp;
+ uint16_t *llr16=(uint16_t*)dlsch_llr;
+ int i, len, nsymb;
+ uint8_t symbol, symbol_mod;
+ int len_acc=0;
+ uint16_t *sic_data;
+ uint16_t pbch_pss_sss_adjust;
+
+ nsymb = (frame_parms->Ncp==0) ? 14:12;
+
+ for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]);
+ int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]);
+ sic_data = (uint16_t*)&sic_buffer[0][((int16_t)len_acc)];
+
+ symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+
+
+
+ if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) //pilots=1
+ amp_tmp=0x1fff;//dlsch0->sqrt_rho_b; already taken into account
+ else //pilots=0
+ amp_tmp=0x1fff;//1.5*dlsch0->sqrt_rho_a; already taken into account
+
+ if (mod_order_0==6)
+ amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation to avoid overflow
+
+
+ pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,2,subframe,symbol);
+
+ if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
+ if (frame_parms->mode1_flag==0)
+ len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
+ else
+ len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
+ } else {
+ len = (nb_rb*12) - pbch_pss_sss_adjust;
+ }
+
+ // 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);
+
+ len_acc+=len; //accumulated length; this is done because in sic_buffer we have only data symbols
+
+ multadd_complex_vector_real_scalar((int16_t *)sic_data,
+ amp_tmp,
+ (int16_t *)rho_amp_x0, //this is in Q13
+ 1,
+ len);
+
+ mult_cpx_vector((int16_t *)rho_1, //Q15
+ (int16_t *)rho_amp_x0, //Q13
+ (int16_t*)rho_rho_amp_x0,
+ len,
+ 13);
+
+#ifdef DEBUG_LLR_SIC
+ write_output("rho_for_multipl.m","rho_for_m", rho_1,len,1,
+ symbol==num_pdcch_symbols ? 15 :
+ symbol==nsymb-1 ? 14 : 13);
+
+ write_output("rho_rho_in_llr.m","rho2", rho_rho_amp_x0,len,1,
+ symbol==num_pdcch_symbols ? 15 :
+ symbol==nsymb-1 ? 14 : 13);
+#endif
+
+ sub_cpx_vector16((int16_t *)rxF,
+ (int16_t *)rho_rho_amp_x0,
+ //(int16_t *)clean_x1,
+ (int16_t *)rxF,
+ len*2);
+
+#ifdef DEBUG_LLR_SIC
+ write_output("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1);
+ write_output("rxF_comp1.m","rxF_1_comp", rxF,len,1,
+ symbol==num_pdcch_symbols ? 15 :
+ symbol==nsymb-1 ? 14 : 13);
+#endif
+
+ //this is for QPSK only!!!
+ for (i=0; i>=2; // length in quad words (4 REs)
+ // printf("len>>=2=%d\n", len);
len+=(len_mod4==0 ? 0 : 1);
-
+ // printf("len+=%d\n", len);
for (i=0; iN_RB_DL*12];
+ int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
+ uint16_t amp_tmp;
+ uint32_t *llr32=(uint32_t*)dlsch_llr;
+ int i, len, nsymb;
+ uint8_t symbol, symbol_mod;
+ int len_acc=0;
+ uint16_t *sic_data;
+ uint16_t pbch_pss_sss_adjust;
+ unsigned char len_mod4=0;
+ __m128i llr128[2];
+ __m128i *ch_mag;
+ nsymb = (frame_parms->Ncp==0) ? 14:12;
+
+ for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]);
+ int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]);
+ ch_mag = (__m128i*)(&dl_ch_mag[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]);
+ sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]);
+
+ symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+ pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,4,subframe,symbol);
+
+ if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
+ amp_tmp=0x1fff;//dlsch0->sqrt_rho_b; already taken into account
+ if (frame_parms->mode1_flag==0)
+ len = nb_rb*8 - (2*pbch_pss_sss_adjust/3);
+ else
+ len = nb_rb*10 - (5*pbch_pss_sss_adjust/6);
+ } else {
+ amp_tmp=0x1fff;;//dlsch0->sqrt_rho_a; already taken into account
+ len = nb_rb*12 - pbch_pss_sss_adjust;
+ }
+
+ if (mod_order_0==6)
+ amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation
+
+ len_acc+=len;
+
+ multadd_complex_vector_real_scalar((int16_t *)sic_data,
+ amp_tmp,
+ (int16_t *)rho_amp_x0, //this is in Q13
+ 1,
+ len);
+
+ mult_cpx_vector((int16_t *)rho_1, //Q15
+ (int16_t *)rho_amp_x0, //Q13
+ (int16_t*)rho_rho_amp_x0,
+ len,
+ 13);
+
+ sub_cpx_vector16((int16_t *)rxF,
+ (int16_t *)rho_rho_amp_x0,
+ //(int16_t *)clean_x1,
+ (int16_t *)rxF,
+ len*2);
+
+ len_mod4 = len&3;
+ len>>=2; // length in quad words (4 REs)
+ len+=(len_mod4==0 ? 0 : 1);
+
+ for (i=0; iN_RB_DL*12];
+ int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
+ uint16_t amp_tmp;
+ uint16_t *llr32=(uint16_t*)dlsch_llr;
+ int i, len, nsymb, len2;
+ uint8_t symbol, symbol_mod;
+ int len_acc=0;
+ uint16_t *sic_data;
+ uint16_t pbch_pss_sss_adjust;
+ unsigned char len_mod4=0;
+ uint16_t *llr2;
+ __m128i *ch_mag,*ch_magb;
+ nsymb = (frame_parms->Ncp==0) ? 14:12;
+
+ for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]);
+ int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]);
+ ch_mag = (__m128i*)(&dl_ch_mag[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]);
+ ch_magb = (__m128i*)(&dl_ch_magb[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]);
+ sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]);
+
+ symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+ pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,6,subframe,symbol);
+
+ if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
+ amp_tmp = 0x1fff;//dlsch0->sqrt_rho_b; already taken into account
+ if (frame_parms->mode1_flag==0)
+ len = nb_rb*8 - (2*pbch_pss_sss_adjust/3);
+ else
+ len = nb_rb*10 - (5*pbch_pss_sss_adjust/6);
+ } else {
+ amp_tmp = 0x1fff; //dlsch0->sqrt_rho_a; already taken into account
+ len = nb_rb*12 - pbch_pss_sss_adjust;
+ }
+
+ if (mod_order_0==6)
+ amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation
+
+ len_acc+=len;
+
+ multadd_complex_vector_real_scalar((int16_t *)sic_data,
+ amp_tmp,
+ (int16_t *)rho_amp_x0, //this is in Q13
+ 1,
+ len);
+
+ mult_cpx_vector((int16_t *)rho_1, //Q15
+ (int16_t *)rho_amp_x0, //Q13
+ (int16_t*)rho_rho_amp_x0,
+ len,
+ 13);
+
+ sub_cpx_vector16((int16_t *)rxF,
+ (int16_t *)rho_rho_amp_x0,
+ //(int16_t *)clean_x1,
+ (int16_t *)rxF,
+ len*2);
+
+ llr2 = llr32;
+ llr32 += (len*6);
+
+ len_mod4 =len&3;
+ len2=len>>2; // length in quad words (4 REs)
+ len2+=(len_mod4?0:1);
+
+
+
+ for (i=0; i= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
+
if (first_symbol_flag == 1) {
llr16 = (int16_t*)dlsch_llr;
} else {
@@ -1597,7 +1973,7 @@ void qpsk_qam64(short *stream0_in,
short *stream0_out,
short *rho01,
int length
- )
+ )
{
/*
@@ -1849,7 +2225,7 @@ void qam16_qpsk(short *stream0_in,
short *stream0_out,
short *rho01,
int length
- )
+ )
{
/*
@@ -1883,7 +2259,7 @@ void qam16_qpsk(short *stream0_in,
__m128i y0i_over_sqrt10;
__m128i y0r_three_over_sqrt10;
__m128i y0i_three_over_sqrt10;
-
+
__m128i ch_mag_des;
__m128i ch_mag_over_10;
__m128i ch_mag_over_2;
@@ -2319,7 +2695,6 @@ int dlsch_16qam_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
llr16 = (int16_t*)(*llr16p);
}
-
if (!llr16) {
msg("dlsch_16qam_qpsk_llr: llr is null, symbol %d\n",symbol);
return(-1);
@@ -2360,7 +2735,7 @@ void qam16_qam16(short *stream0_in,
short *stream0_out,
short *rho01,
int length
- )
+ )
{
/*
@@ -2919,7 +3294,7 @@ void qam16_qam64(int16_t *stream0_in,
int16_t *stream0_out,
int16_t *rho01,
int32_t length
- )
+ )
{
/*
@@ -2945,7 +3320,7 @@ void qam16_qam64(int16_t *stream0_in,
__m128i *ch_mag_128i = (__m128i *)ch_mag;
__m128i *ch_mag_128i_i = (__m128i *)ch_mag_i;
-
+
__m128i ONE_OVER_SQRT_2 = _mm_set1_epi16(23170); // round(1/sqrt(2)*2^15)
__m128i ONE_OVER_SQRT_10 = _mm_set1_epi16(20724); // round(1/sqrt(10)*2^16)
__m128i THREE_OVER_SQRT_10 = _mm_set1_epi16(31086); // round(3/sqrt(10)*2^15)
@@ -3595,7 +3970,7 @@ void qam64_qpsk(int16_t *stream0_in,
int16_t *stream0_out,
int16_t *rho01,
int32_t length
- )
+ )
{
/*
@@ -3657,7 +4032,7 @@ void qam64_qpsk(int16_t *stream0_in,
#elif defined(__arm__)
#endif
-
+
int i,j;
for (i=0; i>2; i+=2) {
@@ -5118,7 +5493,7 @@ void qam64_qam16(short *stream0_in,
short *stream0_out,
short *rho01,
int length
- )
+ )
{
/*
@@ -5181,7 +5556,7 @@ void qam64_qam16(short *stream0_in,
__m128i y0i_three_over_sqrt_21;
__m128i y0i_five_over_sqrt_21;
__m128i y0i_seven_over_sqrt_21;
-
+
#elif defined(__arm__)
#endif
@@ -6663,7 +7038,7 @@ void qam64_qam64(short *stream0_in,
short *stream0_out,
short *rho01,
int length
- )
+ )
{
/*
@@ -6730,7 +7105,7 @@ void qam64_qam64(short *stream0_in,
__m128i y0i_seven_over_sqrt_21;
__m128i ch_mag_int_with_sigma2;
__m128i two_ch_mag_int_with_sigma2;
- __m128i three_ch_mag_int_with_sigma2;
+ __m128i three_ch_mag_int_with_sigma2;
#elif defined(__arm__)
#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index 1875ada878..e24edb8d68 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -75,12 +75,12 @@ uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp,
switch (beamforming_mode) {
case 7:
if (Ncp == NORMAL){
- if ((re!=nushift+offset) && (re!=((nushift+4+offset)%12)) && (re!=((nushift+8+offset)%12)))
+ if ((re!=nushift+offset) && (re!=((nushift+4+offset)%12)) && (re!=((nushift+8+offset)%12)))
return(1);
/*else{
printf("(is_no_UEspec_RS):lprime=%d, re=%d, nushift=%d, offset=%d\n",lprime, re,nushift,offset);
}*/
- } else {
+ } else {
if ((re!=nushift+offset) && (re!=((nushift+3+offset)%12)) && (re!=((nushift+6+offset)%12)) && (re!=((nushift+9+offset)%12)))
return(1);
}
@@ -158,26 +158,26 @@ uint32_t FOUR[2]={0,4};
uint32_t TWO[2]={0,2};
int allocate_REs_in_RB_no_pilots_16QAM_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)
+ 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;
@@ -190,10 +190,10 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
uint8_t *x0p;
if (skip_dc == 0) {
- for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
- re<12;
- re++,x0p+=4,tti_offset++) {
-
+ for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
+ re<12;
+ re++,x0p+=4,tti_offset++) {
+
qam16_table_offset_re=TWO[x0p[0]];
qam16_table_offset_im=TWO[x0p[1]];
qam16_table_offset_re+=x0p[2];
@@ -203,11 +203,11 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
}
}
else {
- // 1st half of PRB
- for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
- re<6;
- re++,x0p+=4,tti_offset++) {
-
+ // 1st half of PRB
+ for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
+ re<6;
+ re++,x0p+=4,tti_offset++) {
+
qam16_table_offset_re=TWO[x0p[0]];
qam16_table_offset_im=TWO[x0p[1]];
qam16_table_offset_re+=x0p[2];
@@ -215,11 +215,11 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im];
}
- // 2nd half of PRB
- for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
- re<12;
- re++,x0p+=4,tti_offset++) {
-
+ // 2nd half of PRB
+ for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
+ re<12;
+ re++,x0p+=4,tti_offset++) {
+
qam16_table_offset_re=TWO[x0p[0]];
qam16_table_offset_im=TWO[x0p[1]];
qam16_table_offset_re+=x0p[2];
@@ -230,33 +230,34 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
}
*re_allocated = *re_allocated + 12;
*jj=*jj + 48;
-
+
return(0);
}
int allocate_REs_in_RB_pilots_16QAM_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)
+ 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;
@@ -270,10 +271,10 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
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+=4) {
-
+ for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
+ re<12;
+ x0p+=4) {
+
qam16_table_offset_re=TWO[x0p[0]];
qam16_table_offset_im=TWO[x0p[1]];
qam16_table_offset_re+=x0p[2];
@@ -286,10 +287,10 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
}
}
else {
- for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
- re<6;
- x0p+=4) {
-
+ for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
+ re<6;
+ x0p+=4) {
+
qam16_table_offset_re=TWO[x0p[0]];
qam16_table_offset_im=TWO[x0p[1]];
qam16_table_offset_re+=x0p[2];
@@ -300,10 +301,10 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
re+=P1_SHIFT[re+1];
}
- for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
- re<12;
- x0p+=4) {
-
+ for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
+ re<12;
+ x0p+=4) {
+
qam16_table_offset_re=TWO[x0p[0]];
qam16_table_offset_im=TWO[x0p[1]];
qam16_table_offset_re+=x0p[2];
@@ -321,26 +322,26 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
}
int allocate_REs_in_RB_no_pilots_64QAM_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)
+ 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;
@@ -357,10 +358,10 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
x0p=&x0[*jj],tti_offset=symbol_offset+re_offset;
- /* for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
- re<12;
- re+=4,x0p+=24,tti_offset+=4) {*/
-
+ /* for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
+ re<12;
+ re+=4,x0p+=24,tti_offset+=4) {*/
+
qam64_table_offset_re=(x0p[0]<<2)|(x0p[2]<<1)|x0p[4];
qam64_table_offset_im=(x0p[1]<<2)|(x0p[3]<<1)|x0p[5];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
@@ -425,10 +426,10 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
// }
}
else {
- for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
- re<6;
- re++,x0p+=6,tti_offset++) {
-
+ for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
+ re<6;
+ re++,x0p+=6,tti_offset++) {
+
qam64_table_offset_re=FOUR[x0p[0]];
qam64_table_offset_im=FOUR[x0p[1]];
qam64_table_offset_re+=TWO[x0p[2]];
@@ -439,10 +440,10 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
}
- for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
- re<12;
- re++,x0p+=6,tti_offset++) {
-
+ for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
+ re<12;
+ re++,x0p+=6,tti_offset++) {
+
qam64_table_offset_re=FOUR[x0p[0]];
qam64_table_offset_im=FOUR[x0p[1]];
qam64_table_offset_re+=TWO[x0p[2]];
@@ -456,33 +457,34 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
*re_allocated = *re_allocated + 12;
*jj=*jj + 72;
-
+
return(0);
}
int allocate_REs_in_RB_pilots_64QAM_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)
+ 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;
@@ -496,10 +498,10 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
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+=6) {
-
+ for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
+ re<12;
+ x0p+=6) {
+
qam64_table_offset_re=FOUR[x0p[0]];
qam64_table_offset_im=FOUR[x0p[1]];
qam64_table_offset_re+=TWO[x0p[2]];
@@ -514,10 +516,10 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
}
}
else {
- for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
- re<6;
- x0p+=6) {
-
+ for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
+ re<6;
+ x0p+=6) {
+
qam64_table_offset_re=FOUR[x0p[0]];
qam64_table_offset_im=FOUR[x0p[1]];
qam64_table_offset_re+=TWO[x0p[2]];
@@ -530,10 +532,10 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
re+=P1_SHIFT[re+1];
}
- for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
- re<12;
- x0p+=6) {
-
+ for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
+ re<12;
+ x0p+=6) {
+
qam64_table_offset_re=FOUR[x0p[0]];
qam64_table_offset_im=FOUR[x0p[1]];
qam64_table_offset_re+=TWO[x0p[2]];
@@ -568,31 +570,30 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
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)
+ uint8_t lprime,
+ uint8_t mprime,
+ uint8_t Ns,
+ int *P1_SHIFT,
+ int *P2_SHIFT)
{
+ uint8_t *x0 = NULL;
+ MIMO_mode_t mimo_mode;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
- uint8_t *x0 = dlsch0_harq->e;
- MIMO_mode_t mimo_mode = dlsch0_harq->mimo_mode;
-
- int first_layer0 = dlsch0_harq->first_layer;
- int Nlayers0 = dlsch0_harq->Nlayers;
- uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs);
+ int first_layer0; //= dlsch0_harq->first_layer;
+ int Nlayers0; // = dlsch0_harq->Nlayers;
+ uint8_t mod_order0=0; // = get_Qm(dlsch0_harq->mcs);
+ uint8_t mod_order1=0; //=2;
+ uint8_t precoder_index0,precoder_index1;
uint8_t *x1=NULL;
- uint8_t mod_order1=2;
// Fill these in later for TM8-10
// int Nlayers1;
// int first_layer1;
-
int use2ndpilots = (frame_parms->mode1_flag==1)?1:0;
uint32_t tti_offset; //,aa;
@@ -622,7 +623,6 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
int mprime2 = mprime,ind,ind_dword,ind_qpsk_symb;
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
- // if (mimo_mode == LARGE_CDD) gain_lin_QPSK>>=1;
int32_t qpsk[4];
((int16_t *)&qpsk[0])[0] = gain_lin_QPSK;
@@ -634,19 +634,46 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
((int16_t *)&qpsk[3])[0] = -gain_lin_QPSK;;
((int16_t *)&qpsk[3])[1] = -gain_lin_QPSK;
- if (dlsch1_harq) {
+ if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4
+
+ x0 = dlsch0_harq->e;
+ mimo_mode = dlsch0_harq->mimo_mode;
+ first_layer0 = dlsch0_harq->first_layer;
+ Nlayers0 = dlsch0_harq->Nlayers;
+ mod_order0 = get_Qm(dlsch0_harq->mcs);
x1 = dlsch1_harq->e;
// Fill these in later for TM8-10
// Nlayers1 = dlsch1_harq->Nlayers;
// first_layer1 = dlsch1_harq->first_layer;
mod_order1 = get_Qm(dlsch1_harq->mcs);
+ } else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc
+
+ x0 = dlsch0_harq->e;
+ mimo_mode = dlsch0_harq->mimo_mode;
+ first_layer0 = dlsch0_harq->first_layer;
+ Nlayers0 = dlsch0_harq->Nlayers;
+ mod_order0 = get_Qm(dlsch0_harq->mcs);
+
+ } else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission
+
+ x0 = dlsch1_harq->e;
+ mimo_mode = dlsch1_harq->mimo_mode;
+ first_layer0 = dlsch1_harq->first_layer;
+ Nlayers0 = dlsch1_harq->Nlayers;
+ mod_order0 = get_Qm(dlsch1_harq->mcs);
+
}
-#ifdef DEBUG_DLSCH_MODULATION
- printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj],
-x0[1+*jj]);
-#endif
+ if (dlsch0_harq != NULL){
+ #ifdef DEBUG_DLSCH_MODULATION
+ printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]);
+ #endif
+ } else{
+ #ifdef DEBUG_DLSCH_MODULATION
+ printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]);
+ #endif
+ }
first_re=0;
last_re=12;
@@ -658,17 +685,17 @@ x0[1+*jj]);
for (re=first_re; reofdm_symbol_size+1;
tti_offset = symbol_offset + re_off + re;
- // check that RE is not from Cell-specific RS
+ //check that RE is not from Cell-specific RS
if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==1) {
- // printf("re %d (jj %d)\n",re,*jj);
+ //printf("re %d (jj %d)\n",re,*jj);
if (mimo_mode == SISO) { //SISO mapping
@@ -677,16 +704,16 @@ x0[1+*jj]);
switch (mod_order0) {
case 2: //QPSK
- // printf("re %d %d(%d) : %d,%d => ",re,tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
- ((int16_t*)&txdataF[0][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
+
+ //printf("re %d %d(%d) : %d,%d => ",re,tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ ((int16_t*)&txdataF[0][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
*jj = *jj + 1;
- ((int16_t*)&txdataF[0][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
+ ((int16_t*)&txdataF[0][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
*jj = *jj + 1;
- // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
case 4: //16QAM
@@ -715,10 +742,8 @@ x0[1+*jj]);
*jj=*jj+1;
- ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam16_table_offset_re];
- ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
- // ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
- // ((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+ ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam16_table_offset_re];
+ ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
break;
@@ -758,8 +783,8 @@ x0[1+*jj]);
*jj=*jj+1;
- ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam64_table_offset_re];
- ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im];
+ ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam64_table_offset_re];
+ ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im];
break;
@@ -769,6 +794,9 @@ x0[1+*jj]);
else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
+ amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);
+
+
switch (mod_order0) {
case 2: //QPSK
@@ -786,46 +814,41 @@ x0[1+*jj]);
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
+ //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
// normalization for 2 tx antennas
- ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
- ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
- ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
- ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]));
+ ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]));
+ ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]));
+ ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]));
- break;
+ break;
case 4: //16QAM
// Antenna 0 position n
-
qam16_table_offset_re = 0;
qam16_table_offset_im = 0;
if (x0[*jj] == 1)
qam16_table_offset_re+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im+=2;
-
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_re+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im+=1;
-
*jj=*jj+1;
//((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
//((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
- ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15;
- ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15;
+ //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
+ ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]);
+ ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]);
// Antenna 1 position n Real part -> -x1*
@@ -834,30 +857,27 @@ x0[1+*jj]);
if (x0[*jj] == 1)
qam16_table_offset_re+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im+=2;
-
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_re+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im+=1;
-
*jj=*jj+1;
//((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
//((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
- ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam16_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15;
- ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15;
+ //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
+ ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam16_table_offset_re]);
+ ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]);
+ //((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re];
+ //((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
break;
@@ -869,141 +889,112 @@ x0[1+*jj]);
if (x0[*jj] == 1)
qam64_table_offset_re+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=1;
-
*jj=*jj+1;
//((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
//((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
- ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15;
- ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15;
+ //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
+ ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]);
+ ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]);
// Antenna 1 => -x1*
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
-
if (x0[*jj] == 1)
qam64_table_offset_re+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=1;
-
*jj=*jj+1;
//((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
//((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
- ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam64_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15;
- ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15;
+ //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
+ ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam64_table_offset_re]);
+ ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]);
break;
}
-
- // fill in the rest of the ALAMOUTI precoding
+ // fill in the rest of the ALAMOUTI precoding
if (is_not_pilot(pilots,re + 1,frame_parms->nushift,use2ndpilots)==1) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
- } else {
+ }
+ else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
}
- } else if (mimo_mode == LARGE_CDD) {
+ }
+ else if (mimo_mode == LARGE_CDD) {
*re_allocated = *re_allocated + 1;
if (frame_parms->nb_antenna_ports_eNB == 2) {
switch (mod_order0) {
+
default:
LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0);
xx0_re=xx0_im=0;
break;
case 2: //QPSK
- // printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj = *jj + 1;
xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj = *jj + 1;
-
-
-
- // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
case 4: //16QAM
qam16_table_offset_re0 = 0;
qam16_table_offset_im0 = 0;
-
if (x0[*jj] == 1)
qam16_table_offset_re0+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im0+=2;
-
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_re0+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im0+=1;
-
*jj=*jj+1;
xx0_re = qam_table_s0[qam16_table_offset_re0];
@@ -1019,80 +1010,61 @@ x0[1+*jj]);
if (x0[*jj] == 1)
qam64_table_offset_re0+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im0+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re0+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im0+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re0+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im0+=1;
-
*jj=*jj+1;
xx0_re = qam_table_s0[qam64_table_offset_re0];
xx0_im = qam_table_s0[qam64_table_offset_im0];
-
break;
}
switch (mod_order1) {
+
default:
LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1);
xx1_re=xx1_im=0;
break;
case 2: //QPSK
- // printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj2 = *jj2 + 1;
xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj2 = *jj2 + 1;
- // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
case 4: //16QAM
qam16_table_offset_re1 = 0;
qam16_table_offset_im1 = 0;
-
if (x1[*jj2] == 1)
qam16_table_offset_re1+=2;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam16_table_offset_im1+=2;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam16_table_offset_re1+=1;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam16_table_offset_im1+=1;
-
*jj2 = *jj2 + 1;
xx1_re = qam_table_s1[qam16_table_offset_re1];
@@ -1107,38 +1079,26 @@ x0[1+*jj]);
if (x1[*jj2] == 1)
qam64_table_offset_re1+=4;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam64_table_offset_im1+=4;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam64_table_offset_re1+=2;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam64_table_offset_im1+=2;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam64_table_offset_re1+=1;
-
*jj2 = *jj2 + 1;
-
if (x1[*jj2] == 1)
qam64_table_offset_im1+=1;
-
*jj2 = *jj2 + 1;
xx1_re = qam_table_s1[qam64_table_offset_re1];
xx1_im = qam_table_s1[qam64_table_offset_im1];
-
break;
}
@@ -1161,59 +1121,103 @@ x0[1+*jj]);
// s alternates +1/-1 for each RE
s = -s;
}
- } else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) {
- // this is for transmission modes 4-6 (1 layer)
+ }
+ else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) {
+ // this is for transmission modes 5-6 (1 layer)
*re_allocated = *re_allocated + 1;
amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);
switch (mod_order0) {
- case 2: //QPSK
+ case 2:
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj = *jj + 1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj = *jj + 1;
- // normalization for 2 tx antennas
- ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ //normalization for 2 tx antennas
+ /*((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
if (frame_parms->nb_antenna_ports_eNB == 2) {
layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
+ }*/
+
+ // We remove ONE_OVER_SQRT2_Q15 that was coming from precoder, as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function
+
+ ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
+ ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
+
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
+ ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
}
break;
- case 4: //16QAM
+ case 4:
qam16_table_offset_re = 0;
qam16_table_offset_im = 0;
if (x0[*jj] == 1)
qam16_table_offset_re+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im+=2;
-
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_re+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam16_table_offset_im+=1;
-
*jj=*jj+1;
- ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
- ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+
+ ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));
+ ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));
+
+ ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
+ ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
+
+ if (frame_parms->nb_antennas_tx == 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
+ ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
+ }
+
+ break;
+
+ case 6:
+
+ qam64_table_offset_re = 0;
+ qam64_table_offset_im = 0;
+ if (x0[*jj] == 1)
+ qam64_table_offset_re+=4;
+ *jj=*jj+1;
+ if (x0[*jj] == 1)
+ qam64_table_offset_im+=4;
+ *jj=*jj+1;
+ if (x0[*jj] == 1)
+ qam64_table_offset_re+=2;
+ *jj=*jj+1;
+ if (x0[*jj] == 1)
+ qam64_table_offset_im+=2;
+ *jj=*jj+1;
+ if (x0[*jj] == 1)
+ qam64_table_offset_re+=1;
+ *jj=*jj+1;
+ if (x0[*jj] == 1)
+ qam64_table_offset_im+=1;
+ *jj=*jj+1;
+
+ ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));
+ ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));
((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
@@ -1225,60 +1229,220 @@ x0[1+*jj]);
}
break;
+ }
+ }
+ else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) {
+ // this is for transmission mode 4 (1 layer)
+ *re_allocated = *re_allocated + 1;
- case 6: //64QAM
+ if (precoder_index==0) {
+ precoder_index0 = 0; //[1 1]
+ precoder_index1 = 1; //[1 -1]
+ }
+ else if (precoder_index==1) {
+ precoder_index0 = 2; //[1 j]
+ precoder_index1 = 3; //[1 -j]
+ }
+ else {
+ printf("problem with precoder in TM4\n");
+ return(-1);
+ }
+ switch (mod_order0) {
+ case 2:
+
+ ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+ *jj = *jj + 1;
+ ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+ *jj = *jj + 1;
+
+ //normalization for 2 tx antennas
+ // We remove ONE_OVER_2_Q15 that was coming from precoder,
+ //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function
+ //ONE_OVER_SQRT2_Q15 remains from it
+ ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
+
+ //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
+ }
+
+ break;
+
+ case 4:
+
+ qam16_table_offset_re = 0;
+ qam16_table_offset_im = 0;
+
+ if (x0[*jj] == 1)
+ qam16_table_offset_re+=2;
+ *jj=*jj+1;
+ if (x0[*jj] == 1)
+ qam16_table_offset_im+=2;
+ *jj=*jj+1;
+
+ if (x0[*jj] == 1)
+ qam16_table_offset_re+=1;
+ *jj=*jj+1;
+ if (x0[*jj] == 1)
+ qam16_table_offset_im+=1;
+ *jj=*jj+1;
+
+ ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));
+ ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));
+
+ // We remove ONE_OVER_2_Q15 that was coming from precoder,
+ //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function
+ //ONE_OVER_SQRT2_Q15 remains from it
+ ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
+
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
+ }
+
+ break;
+
+ case 6:
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
if (x0[*jj] == 1)
qam64_table_offset_re+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=4;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=2;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_re+=1;
-
*jj=*jj+1;
-
if (x0[*jj] == 1)
qam64_table_offset_im+=1;
-
*jj=*jj+1;
- ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
- ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+ ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));
+ ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));
+ ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
- ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
- ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
-
- if (frame_parms->nb_antenna_ports_eNB == 2) {
- layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
- ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
- ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
+ if (frame_parms->nb_antennas_tx == 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
}
break;
+ }
- }
+ if (dlsch1_harq) {
+ switch (mod_order1) {
+
+ case 2:
+
+ ((int16_t*)&tmp_sample1)[0] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+ *jj2 = *jj2 + 1;
+ ((int16_t*)&tmp_sample1)[1] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+ *jj2 = *jj2 + 1;
+
+ //normalization for 2 tx antennas
+ ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
+
+ if (frame_parms->nb_antenna_ports_eNB== 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
+ }
+
+ break;
+
+ case 4:
+
+ qam16_table_offset_re = 0;
+ qam16_table_offset_im = 0;
+
+ if (x1[*jj2] == 1)
+ qam16_table_offset_re+=2;
+ *jj2=*jj2+1;
+ if (x1[*jj2] == 1)
+ qam16_table_offset_im+=2;
+ *jj2=*jj2+1;
+
+
+ if (x1[*jj2] == 1)
+ qam16_table_offset_re+=1;
+ *jj2=*jj2+1;
+ if (x1[*jj2] == 1)
+ qam16_table_offset_im+=1;
+ *jj2=*jj2+1;
+
+ ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re]));
+ ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im]));
+ ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
+
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
+ }
+
+ break;
+
+ case 6:
+
+ qam64_table_offset_re = 0;
+ qam64_table_offset_im = 0;
+ if (x1[*jj2] == 1)
+ qam64_table_offset_re+=4;
+ *jj2=*jj2+1;
+ if (x1[*jj2] == 1)
+ qam64_table_offset_im+=4;
+ *jj2=*jj2+1;
+ if (x1[*jj2] == 1)
+ qam64_table_offset_re+=2;
+ *jj2=*jj2+1;
+ if (x1[*jj2] == 1)
+ qam64_table_offset_im+=2;
+ *jj2=*jj2+1;
+ if (x1[*jj2] == 1)
+ qam64_table_offset_re+=1;
+ *jj2=*jj2+1;
+ if (x1[*jj2] == 1)
+ qam64_table_offset_im+=1;
+ *jj2=*jj2+1;
+
+ ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re]));
+ ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im]));
+ ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
+
+ if (frame_parms->nb_antenna_ports_eNB == 2) {
+ layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
+ ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
+ ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
+ }
+
+ break;
+
+ }
+ }
}
+
if (mimo_mode == ALAMOUTI) {
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1;
@@ -1288,7 +1452,7 @@ x0[1+*jj]);
*re_allocated = *re_allocated + 1;
}
}
-
+
if (mimo_mode == TM7) {
*re_allocated = *re_allocated + 1;
@@ -1393,7 +1557,7 @@ x0[1+*jj]);
}
} else if (mimo_mode >= TM8) { //TM8,TM9,TM10
- //uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
+ //uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) {
switch (mod_order0) {
@@ -1444,7 +1608,6 @@ x0[1+*jj]);
case 6: //64QAM
-
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
@@ -1492,10 +1655,7 @@ x0[1+*jj]);
return(-1);
}
}
-
-
}
-
return(0);
}
@@ -1547,11 +1707,12 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
tti_offset = symbol_offset + re_off + re;
- // printf("re %d (jj %d)\n",re,*jj);
+ //printf("re %d (jj %d)\n",re,*jj);
*re_allocated = *re_allocated + 1;
switch (mod_order) {
+
case 2: //QPSK
// printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
@@ -1563,9 +1724,10 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
*jj = *jj + 1;
- // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+ //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
+
case 4: //16QAM
qam16_table_offset_re = 0;
@@ -1592,6 +1754,7 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
*jj=*jj+1;
+
((int16_t *)&txdataF[4][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
@@ -1599,7 +1762,6 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
case 6: //64QAM
-
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
@@ -1644,14 +1806,13 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
return(0);
}
-uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb)
+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;
+ */
- // printf("Getting pmi for RB %d => %d\n",rb,(pmi_alloc>>((rb>>2)<<1))&3);
switch (N_RB_DL) {
case 6: // 1 PRB per subband
if (mode <= PUSCH_PRECODING1)
@@ -1696,70 +1857,70 @@ inline int check_skip(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms
if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL
// PBCH
if ((subframe_offset==0) &&
- (rb>((frame_parms->N_RB_DL>>1)-3)) &&
- (rb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l>=(nsymb>>1)) &&
- (l<((nsymb>>1) + 4))) {
+ (rb>((frame_parms->N_RB_DL>>1)-3)) &&
+ (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l>=(nsymb>>1)) &&
+ (l<((nsymb>>1) + 4))) {
return(1);
}
if (frame_parms->frame_type == TDD) { // TDD
//SSS TDD
if (((subframe_offset==0)||(subframe_offset==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==(nsymb-1)) ) {
- return(1);
- }
+ return(1);
+ }
//PSS TDD
if (((subframe_offset==1) || (subframe_offset==6)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==2) ) {
- return(1);
+ return(1);
}
} else {
//PSS FDD
if (((subframe_offset==0)||(subframe_offset==5)) &&
- (rb>((frame_parms->N_RB_DL>>1)-3)) &&
- (rb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==((nsymb>>1)-1)) ) {
- return(1);
+ (rb>((frame_parms->N_RB_DL>>1)-3)) &&
+ (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==((nsymb>>1)-1)) ) {
+ return(1);
}
//SSS FDD
if (((subframe_offset==0)||(subframe_offset==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-2)) ) {
- return(1);
+ return(1);
}
}
}
else { // even N_RB_DL
//PBCH
if ((subframe_offset==0) &&
- (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
- (rb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l>=nsymb>>1) && (l<((nsymb>>1) + 4)))
+ (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
+ (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l>=nsymb>>1) && (l<((nsymb>>1) + 4)))
return(1);
if (frame_parms->frame_type == TDD) { // TDD
//SSS
if (((subframe_offset==0)||
- (subframe_offset==5)) &&
- (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
- (rb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==nsymb-1) ) {
- return(1);
+ (subframe_offset==5)) &&
+ (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
+ (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==nsymb-1) ) {
+ return(1);
}
-
+
//PSS
if (((subframe_offset==1)||
- (subframe_offset==6)) &&
- (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
- (rb<((frame_parms->N_RB_DL>>1)+3)) &&
- (l==2) ) {
- return(1);
+ (subframe_offset==6)) &&
+ (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
+ (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+ (l==2) ) {
+ return(1);
}
} else { // FDD
//SSS
if (((subframe_offset==0)||(subframe_offset==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-2)) ) {
- return(1);
+ return(1);
}
-
+
//PSS
if (((subframe_offset==0)||(subframe_offset==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-1)) ) {
- return(1);
+ return(1);
}
}
}
@@ -1776,9 +1937,9 @@ inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_p
// PBCH
if ((subframe_offset==0) &&
- (rb==((frame_parms->N_RB_DL>>1)-3)) &&
- (l>=(nsymb>>1)) &&
- (l<((nsymb>>1) + 4)))
+ (rb==((frame_parms->N_RB_DL>>1)-3)) &&
+ (l>=(nsymb>>1)) &&
+ (l<((nsymb>>1) + 4)))
return(1);
else if ((subframe_offset==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
return(2);
@@ -1786,26 +1947,26 @@ inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_p
if (frame_parms->frame_type == TDD) { // TDD
//SSS TDD
if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==(nsymb-1)))
- return(1);
+ return(1);
else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==(nsymb-1)))
- return(2);
+ return(2);
//PSS TDD
if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==2))
- return(1);
+ return(1);
else if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==2))
- return(2);
+ return(2);
}
else { // FDD
//PSS FDD
if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==((nsymb>>1)-1)))
- return(1);
+ return(1);
else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==(((nsymb>>1)-1))))
- return(2);
+ return(2);
//SSS FDD
if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && ((l==((nsymb>>1)-2))))
- return(1);
+ return(1);
else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && ((l==(nsymb>>1)-2)))
- return(2);
+ return(2);
}
}
else { // EVEN N_RB_DL
@@ -1837,68 +1998,126 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
uint8_t nsymb;
- uint8_t harq_pid = dlsch0->current_harq_pid;
- LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ uint8_t harq_pid; //= dlsch0->current_harq_pid;
+ LTE_DL_eNB_HARQ_t *dlsch0_harq;
LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid];
uint32_t i,i2,jj,jj2,re_allocated,symbol_offset;
uint16_t l,rb,re_offset;
uint32_t rb_alloc_ind;
- uint32_t *rb_alloc = dlsch0_harq->rb_alloc;
+ uint32_t *rb_alloc; //=dlsch0_harq->rb_alloc;
+
uint8_t pilots=0;
- uint8_t skip_dc=0,skip_half=0;
- uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs);
+ uint8_t skip_dc,skip_half;
+ 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 *qam_table_s0=NULL,*qam_table_s1=NULL;
int (*allocate_REs)(PHY_VARS_eNB*,
- int **,
- uint32_t*,
- uint32_t*,
- uint16_t,
- uint32_t,
- LTE_DL_eNB_HARQ_t *,
- LTE_DL_eNB_HARQ_t *,
- uint8_t,
- int16_t,
- uint8_t,
- int16_t *,
- int16_t *,
- uint32_t *,
- uint8_t,
- uint8_t,
- uint8_t,
- uint8_t,
- uint8_t,
- int *,
- int *);
+ int **,
+ uint32_t*,
+ uint32_t*,
+ uint16_t,
+ uint32_t,
+ LTE_DL_eNB_HARQ_t *,
+ LTE_DL_eNB_HARQ_t *,
+ uint8_t,
+ int16_t,
+ uint8_t,
+ int16_t *,
+ int16_t *,
+ uint32_t *,
+ uint8_t,
+ uint8_t,
+ uint8_t,
+ uint8_t,
+ uint8_t,
+ int *,
+ int *);
+
int P1_SHIFT[13],P2_SHIFT[13];
int offset,nushiftmod3;
- MIMO_mode_t mimo_mode = dlsch0_harq->mimo_mode;
+
+ uint8_t get_pmi_temp;
+
+ MIMO_mode_t mimo_mode;
uint8_t mprime=0,Ns;
int8_t lprime=-1;
int aa=0;
+
#ifdef DEBUG_DLSCH_MODULATION
- uint8_t Nl0 = dlsch0_harq->Nl;
+ uint8_t Nl0; //= dlsch0_harq->Nl;
uint8_t Nl1;
#endif
- if (dlsch1) {
+
+ if ((dlsch0 != NULL) && (dlsch1 != NULL)){
+
+ harq_pid = dlsch0->current_harq_pid;
+ dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ mimo_mode = dlsch0_harq->mimo_mode;
+ mod_order0 = get_Qm(dlsch0_harq->mcs);
+ rb_alloc = dlsch0_harq->rb_alloc;
+#ifdef DEBUG_DLSCH_MODULATION
+ Nl0 = dlsch0_harq->Nl;
+#endif
+
dlsch1_harq = dlsch1->harq_processes[harq_pid];
mod_order1 = get_Qm(dlsch1_harq->mcs);
#ifdef DEBUG_DLSCH_MODULATION
Nl1 = dlsch1_harq->Nl;
#endif
+
+ }else if ((dlsch0 != NULL) && (dlsch1 == NULL)){
+
+ harq_pid = dlsch0->current_harq_pid;
+ dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ mimo_mode = dlsch0_harq->mimo_mode;
+ mod_order0 = get_Qm(dlsch0_harq->mcs);
+ rb_alloc = dlsch0_harq->rb_alloc;
+#ifdef DEBUG_DLSCH_MODULATION
+ Nl0 = dlsch0_harq->Nl;
+#endif
+
+ dlsch1_harq = NULL;
+ mod_order1 = 0;
+#ifdef DEBUG_DLSCH_MODULATION
+ Nl1 = 0;
+#endif
+
+ }else if ((dlsch0 == NULL) && (dlsch1 != NULL)){
+
+ harq_pid = dlsch1->current_harq_pid;
+ dlsch1_harq = dlsch1->harq_processes[harq_pid];
+ mimo_mode = dlsch1_harq->mimo_mode;
+ mod_order0 = get_Qm(dlsch1_harq->mcs);
+ rb_alloc = dlsch1_harq->rb_alloc;
+#ifdef DEBUG_DLSCH_MODULATION
+ Nl0 = dlsch1_harq->Nl;
+#endif
+
+ dlsch0_harq = NULL;
+ mod_order1 = 0;
+#ifdef DEBUG_DLSCH_MODULATION
+ Nl1 = NULL;
+#endif
+
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN);
nsymb = (frame_parms->Ncp==0) ? 14:12;
- amp_rho_a = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_a)>>13);
+ if (dlsch0 != NULL){
+ amp_rho_a = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_a)>>13); //amp=512 in full scale; dlsch0->sqrt_rho_a=8192in Q2.13, 1 in full scale
amp_rho_b = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_b)>>13);
+ } else{
+ amp_rho_a = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_a)>>13);
+ amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13);
+ }
if (mod_order0 == 4)
for (i=0;i<4; i++) {
@@ -1928,20 +2147,22 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
jj2=0;
re_allocated=0;
-
+
// printf("num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb);
for (l=num_pdcch_symbols; lmimo_mode,
- pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),
- mod_order0,
- mod_order1,
- rb_alloc[0],
- l);
+ printf("Generating DLSCH (harq_pid %d,mimo %d, pmi_alloc0 %lx, mod0 %d, mod1 %d, rb_alloc[0] %d) in %d\n",
+ harq_pid,
+ dlsch0_harq->mimo_mode,
+ pmi2hex_2Ar2(dlsch0_harq->pmi_alloc),
+ mod_order0,
+ mod_order1,
+ rb_alloc[0],
+ len);
#endif
+ }
if (frame_parms->Ncp==0) { // normal prefix
if ((l==4)||(l==11))
@@ -1987,9 +2208,9 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
for (aa=0;aanb_antennas_tx;aa++){
memcpy(phy_vars_eNB->common_vars.beam_weights[0][5][aa],dlsch0->ue_spec_bf_weights[0][aa],frame_parms->ofdm_symbol_size*sizeof(int32_t));
}
-
+
}
-
+
Ns = 2*subframe_offset+(l>=(nsymb>>1));
offset = (pilots==2)?3:0;
@@ -1997,23 +2218,23 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
if (pilots>0) { // compute pilot arrays, could be done statically if performance suffers
if (frame_parms->mode1_flag == 1) {
- // printf("l %d, nushift %d, offset %d\n",l,frame_parms->nushift,offset);
- for (i=0,i2=0;i<12;i++) {
- if ((i!=(frame_parms->nushift+offset)) && (i!=((frame_parms->nushift+6+offset)%12)))
- P1_SHIFT[i2++]=1;
- else
- P1_SHIFT[i2++]=2;
- }
- P1_SHIFT[0]--;
+ // printf("l %d, nushift %d, offset %d\n",l,frame_parms->nushift,offset);
+ for (i=0,i2=0;i<12;i++) {
+ if ((i!=(frame_parms->nushift+offset)) && (i!=((frame_parms->nushift+6+offset)%12)))
+ P1_SHIFT[i2++]=1;
+ else
+ P1_SHIFT[i2++]=2;
+ }
+ P1_SHIFT[0]--;
}
else {
- for (i=0,i2=0;i<12;i++) {
- if ((i!=nushiftmod3) && (i!=nushiftmod3+6) && (i!=nushiftmod3+3) && (i!=nushiftmod3+9))
- P2_SHIFT[i2++]=1;
- else
- P2_SHIFT[i2++]=2;
- }
- P2_SHIFT[0]--;
+ for (i=0,i2=0;i<12;i++) {
+ if ((i!=nushiftmod3) && (i!=nushiftmod3+6) && (i!=nushiftmod3+3) && (i!=nushiftmod3+9))
+ P2_SHIFT[i2++]=1;
+ else
+ P2_SHIFT[i2++]=2;
+ }
+ P2_SHIFT[0]--;
}
}
P1_SHIFT[12]=1;P2_SHIFT[12]=1;
@@ -2022,44 +2243,44 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));
allocate_REs = allocate_REs_in_RB;
-
+
switch (mod_order0) {
case 2:
qam_table_s0 = NULL;
break;
case 4:
if (pilots) {
- qam_table_s0 = qam16_table_b0;
- allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
- allocate_REs_in_RB_pilots_16QAM_siso :
- allocate_REs_in_RB;
+ qam_table_s0 = qam16_table_b0;
+ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
+ allocate_REs_in_RB_pilots_16QAM_siso :
+ allocate_REs_in_RB;
}
else {
- qam_table_s0 = qam16_table_a0;
- allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
- allocate_REs_in_RB_no_pilots_16QAM_siso :
- allocate_REs_in_RB;
-
+ qam_table_s0 = qam16_table_a0;
+ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
+ allocate_REs_in_RB_no_pilots_16QAM_siso :
+ allocate_REs_in_RB;
+
}
break;
-
+
case 6:
if (pilots) {
- qam_table_s0 = qam64_table_b0;
- allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
- allocate_REs_in_RB_pilots_64QAM_siso :
- allocate_REs_in_RB;
+ qam_table_s0 = qam64_table_b0;
+ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
+ allocate_REs_in_RB_pilots_64QAM_siso :
+ allocate_REs_in_RB;
}
else {
- qam_table_s0 = qam64_table_a0;
- allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
- allocate_REs_in_RB_no_pilots_64QAM_siso :
- allocate_REs_in_RB;
+ qam_table_s0 = qam64_table_a0;
+ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
+ allocate_REs_in_RB_no_pilots_64QAM_siso :
+ allocate_REs_in_RB;
}
break;
-
+
}
-
+
switch (mod_order1) {
case 2:
qam_table_s1 = NULL;
@@ -2067,25 +2288,25 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
break;
case 4:
if (pilots) {
- qam_table_s1 = qam16_table_b1;
+ qam_table_s1 = qam16_table_b1;
}
else {
- qam_table_s1 = qam16_table_a1;
+ qam_table_s1 = qam16_table_a1;
}
break;
case 6:
if (pilots) {
- qam_table_s1 = qam64_table_b1;
+ qam_table_s1 = qam64_table_b1;
}
else {
- qam_table_s1 = qam64_table_a1;
+ qam_table_s1 = qam64_table_a1;
}
break;
-
+
}
//for (aa=0;aanb_antennas_tx;aa++)
- // memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2);
+ //memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2);
//printf("symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots);
for (rb=0; rbN_RB_DL; rb++) {
@@ -2101,15 +2322,18 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
rb_alloc_ind = 0;
if (check_skip(rb,subframe_offset,frame_parms,l,nsymb)==1)
- rb_alloc_ind = 0;
+ rb_alloc_ind = 0;
skip_half = check_skiphalf(rb,subframe_offset,frame_parms,l,nsymb);
skip_dc = check_skip_dc(rb,frame_parms);
-
- if (dlsch0_harq->Nlayers>1) {
- printf("Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset);
- return(-1);
+
+
+ if (dlsch0) {
+ if (dlsch0_harq->Nlayers>1) {
+ msg("Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset);
+ return(-1);
+ }
}
if (dlsch1) {
@@ -2122,40 +2346,52 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
if (rb_alloc_ind > 0) {
- // printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj);
- allocate_REs(phy_vars_eNB,
- txdataF,
- &jj,
- &jj2,
- re_offset,
- symbol_offset,
- dlsch0->harq_processes[harq_pid],
- (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid],
- pilots,
- ((pilots) ? amp_rho_b : amp_rho_a),
- get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid],rb),
- qam_table_s0,
- qam_table_s1,
- &re_allocated,
- skip_dc,
- skip_half,
- lprime,
- mprime,
- Ns,
- P1_SHIFT,
- P2_SHIFT);
+ // printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj);
+
+ if (dlsch0 != NULL) {
+ get_pmi_temp = get_pmi(frame_parms->N_RB_DL,
+ dlsch0->harq_processes[harq_pid]->mimo_mode,
+ dlsch0->harq_processes[harq_pid]->pmi_alloc,
+ rb);
+ } else
+ get_pmi_temp = get_pmi(frame_parms->N_RB_DL,
+ dlsch1->harq_processes[harq_pid]->mimo_mode,
+ dlsch1->harq_processes[harq_pid]->pmi_alloc,
+ rb);
+
+
+ allocate_REs_in_RB(phy_vars_eNB,
+ txdataF,
+ &jj,
+ &jj2,
+ re_offset,
+ symbol_offset,
+ (dlsch0 == NULL) ? NULL : dlsch0->harq_processes[harq_pid],
+ (dlsch1 == NULL) ? NULL : dlsch1->harq_processes[harq_pid],
+ pilots,
+ ((pilots) ? amp_rho_b : amp_rho_a),
+ get_pmi_temp,
+ qam_table_s0,
+ qam_table_s1,
+ &re_allocated,
+ skip_dc,
+ skip_half,
+ lprime,
+ mprime,
+ Ns,
+ P1_SHIFT,
+ P2_SHIFT);
if ((mimo_mode == TM7) && (lprime>=0))
mprime +=3+frame_parms->Ncp;
-
}
else {
- // printf("Unallocated rb %d/symbol %d, re_offset %d, jj %d\n",rb,l,re_offset,jj);
+ // printf("Unallocated rb %d/symbol %d, re_offset %d, jj %d\n",rb,l,re_offset,jj);
}
re_offset+=12; // go to next RB
-
// check if we crossed the symbol boundary and skip DCs
+
if (re_offset >= frame_parms->ofdm_symbol_size) {
if (skip_dc == 0) //even number of RBs (doesn't straddle DC)
re_offset=1;
@@ -2163,9 +2399,150 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
re_offset=7; // odd number of RBs
}
}
-
}
+#ifdef DEBUG_DLSCH_MODULATION
+ if (dlsch0 != NULL){
+ msg("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset));
+ }else{
+ msg("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch1_harq->nb_rb,dlsch1_harq->rb_alloc,mod_order1,Nl1,2,0,subframe_offset));
+ }
+#endif
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
+
+ return (re_allocated);
+}
+
+
+int dlsch_modulation_SIC(int32_t **sic_buffer,
+ uint32_t subframe_offset,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ uint8_t num_pdcch_symbols,
+ LTE_eNB_DLSCH_t *dlsch0,
+ int G)
+{
+
+ uint8_t harq_pid = dlsch0->current_harq_pid;
+ LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ uint32_t i,jj,re_allocated=0;
+ uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs);
+ uint8_t *x0 = dlsch0_harq->e;
+ uint8_t qam64_table_offset_re = 0;
+ uint8_t qam64_table_offset_im = 0;
+ uint8_t qam16_table_offset_re = 0;
+ uint8_t qam16_table_offset_im = 0;
+ int16_t gain_lin_QPSK;
+ #ifdef DEBUG_DLSCH_MODULATION
+ uint8_t Nl0 = dlsch0_harq->Nl;
+ uint8_t Nl1;
+#endif
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN);
+
+ gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15));
+
+ jj = 0;
+ i = 0;
+ while (jj <= G-1) {
+
+ re_allocated = re_allocated + 1;
+
+ switch (mod_order0) {
+ case 2: //QPSK
+
+ ((int16_t*)&sic_buffer[0][i])[0] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
+
+ jj = jj + 1;
+
+ ((int16_t*)&sic_buffer[0][i])[1] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
+
+ jj = jj + 1;
+
+ //printf("recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]);
+ i++;
+
+ break;
+
+ case 4: //16QAM
+
+ qam16_table_offset_re = 0;
+ qam16_table_offset_im = 0;
+
+ if (x0[jj] == 1)
+ qam16_table_offset_re+=2;
+
+ jj=jj+1;
+
+ if (x0[jj] == 1)
+ qam16_table_offset_im+=2;
+
+ jj=jj+1;
+
+
+ if (x0[jj] == 1)
+ qam16_table_offset_re+=1;
+
+ jj=jj+1;
+
+ if (x0[jj] == 1)
+ qam16_table_offset_im+=1;
+
+ jj=jj+1;
+
+
+ ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re];
+ ((int16_t *)&sic_buffer[0][i])[1]+=qam16_table[qam16_table_offset_im];
+
+ i++;
+
+ break;
+
+ case 6:
+
+ qam64_table_offset_re = 0;
+ qam64_table_offset_im = 0;
+
+ if (x0[jj] == 1)
+ qam64_table_offset_re+=4;
+
+ jj=jj+1;
+
+ if (x0[jj] == 1)
+ qam64_table_offset_im+=4;
+
+ jj=jj+1;
+
+ if (x0[jj] == 1)
+ qam64_table_offset_re+=2;
+
+ jj=jj+1;
+
+ if (x0[jj] == 1)
+ qam64_table_offset_im+=2;
+
+ jj=jj+1;
+
+ if (x0[jj] == 1)
+ qam64_table_offset_re+=1;
+
+ jj=jj+1;
+
+ if (x0[jj] == 1)
+ qam64_table_offset_im+=1;
+
+ jj=jj+1;
+
+
+ ((int16_t *)&sic_buffer[0][i])[0]+=(qam64_table[qam64_table_offset_re])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+ ((int16_t *)&sic_buffer[0][i])[1]+=(qam64_table[qam64_table_offset_im])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+
+ i++;
+
+ break;
+ }
+
+ }
#ifdef DEBUG_DLSCH_MODULATION
@@ -2177,6 +2554,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
return (re_allocated);
}
+
int mch_modulation(int32_t **txdataF,
int16_t amp,
uint32_t subframe_offset,
@@ -2221,14 +2599,13 @@ int mch_modulation(int32_t **txdataF,
if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL
- if (rb==(frame_parms->N_RB_DL>>1))
+ if (rb==(frame_parms->N_RB_DL>>1))
skip_dc = 1;
else
skip_dc = 0;
}
-
if (mod_order == 4)
qam_table_s = qam16_table_a;
else if (mod_order == 6)
@@ -2236,7 +2613,7 @@ int mch_modulation(int32_t **txdataF,
else
qam_table_s = NULL;
- // printf("Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
+ //printf("Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
allocate_REs_in_RB_MCH(txdataF,
&jj,
re_offset,
@@ -2252,7 +2629,6 @@ int mch_modulation(int32_t **txdataF,
re_offset+=12; // go to next RB
-
// check if we crossed the symbol boundary and skip DC
if (re_offset >= frame_parms->ofdm_symbol_size) {
if (skip_dc == 0) //even number of RBs (doesn't straddle DC)
@@ -2263,10 +2639,6 @@ int mch_modulation(int32_t **txdataF,
}
}
-
-
-
-
#ifdef DEBUG_DLSCH_MODULATION
printf("generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/));
#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 924eef11b9..b691717838 100755
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -39,6 +39,11 @@
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
+
+
+const uint8_t lin2alaw_if4p5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85};
+const uint16_t alaw2lin_if4p5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848};
+
void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type, int k) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int32_t **txdataF = (eNB->CC_id==0) ? eNB->common_vars.txdataF[0] : PHY_vars_eNB_g[0][0]->common_vars.txdataF[0];
@@ -79,19 +84,21 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
gen_IF4p5_dl_header(packet_header, frame, subframe);
for (symbol_id=0; symbol_idCC_id==1) LOG_I(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,frame,subframe,symbol_id);
for (element_id=0; element_idCC_id][blockoffsetF+element_id];
- data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
+ data_block[element_id] = ((uint16_t) lin2alaw_if4p5[*i]) | (lin2alaw_if4p5[*(i+1)]<<8);
i = (uint16_t*) &txdataF[eNB->CC_id][slotoffsetF+element_id];
- data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
+ data_block[element_id+db_halflength] = ((uint16_t) lin2alaw_if4p5[*i]) | (lin2alaw_if4p5[*(i+1)]<<8);
}
+ 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;
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
symbol_id,
&tx_buffer,
@@ -100,7 +107,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
IF4p5_PDLFFT)) < 0) {
perror("ETHERNET write for IF4p5_PDLFFT\n");
}
-
+ 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;
}
@@ -108,8 +115,8 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
(packet_type == IF4p5_PULTICK)){
db_fulllength = 12*fp->N_RB_UL;
db_halflength = (db_fulllength)>>1;
- slotoffsetF = 1;
- blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
+ slotoffsetF = 0;
+ blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
if (subframe_select(fp,subframe)==SF_S) {
nsym=fp->ul_symbols_in_S_subframe;
@@ -127,19 +134,23 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
gen_IF4p5_ul_header(packet_header, packet_type, frame, subframe);
if (packet_type == IF4p5_PULFFT) {
- for (symbol_id=fp->symbols_per_tti-nsym; symbol_idsymbols_per_tti; symbol_id++) {
+ for (symbol_id=fp->symbols_per_tti-nsym; symbol_idsymbols_per_tti; 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 );
LOG_D(PHY,"IF4p5_PULFFT: frame %d, subframe %d, symbol %d\n",frame,subframe,symbol_id);
for (element_id=0; element_idframe_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 );
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
symbol_id,
&tx_buffer,
@@ -148,7 +159,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
IF4p5_PULFFT)) < 0) {
perror("ETHERNET write for IF4p5_PULFFT\n");
}
-
+ 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;
}
@@ -186,7 +197,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
(&rxsigF[0][k]),
PRACH_BLOCK_SIZE_BYTES);
}
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
symbol_id,
&tx_buffer_prach,
@@ -194,7 +205,8 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type
1,
IF4p5_PRACH)) < 0) {
perror("ETHERNET write for IF4p5_PRACH\n");
- }
+ }
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
} else {
AssertFatal(1==0, "send_IF4p5 - Unknown packet_type %x", packet_type);
}
@@ -227,7 +239,8 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t
IF4p5_header_t *packet_header=NULL;
uint16_t *data_block=NULL, *i=NULL;
-
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
if (eNB->ifdevice.trx_read_func(&eNB->ifdevice,
(int64_t*) packet_type,
&rx_buffer,
@@ -235,7 +248,7 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t
0) < 0) {
perror("ETHERNET read");
}
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
if (eth->flags == ETH_RAW_IF4p5_MODE) {
packet_header = (IF4p5_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES);
data_block = (uint16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t);
@@ -251,45 +264,48 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t
*packet_type = packet_header->sub_type;
-
if (*packet_type == IF4p5_PDLFFT) {
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
-
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF4_SYMBOL, *symbol_number );
LOG_D(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number);
slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
-
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 );
for (element_id=0; element_id>8) ];
+ *i = alaw2lin_if4p5[ (data_block[element_id] & 0xff) ];
+ *(i+1) = alaw2lin_if4p5[ (data_block[element_id]>>8) ];
i = (uint16_t*) &txdataF[0][slotoffsetF+element_id];
- *i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ];
- *(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
+ *i = alaw2lin_if4p5[ (data_block[element_id+db_halflength] & 0xff) ];
+ *(i+1) = alaw2lin_if4p5[ (data_block[element_id+db_halflength]>>8) ];
}
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
} else if (*packet_type == IF4p5_PULFFT) {
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
-
- if (eNB->CC_id==1) LOG_I(PHY,"UL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number);
-
- slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + 1;
- blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
-
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF4_SYMBOL, *symbol_number );
+ if (eNB->CC_id==0) LOG_D(PHY,"UL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number);
+ slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size);
+ blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 );
+ if (eNB->CC_id==0) LOG_D(PHY,"UL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number);
for (element_id=0; element_id>8) ];
+ *i = alaw2lin_if4p5[ (data_block[element_id] & 0xff) ];
+ *(i+1) = alaw2lin_if4p5[ (data_block[element_id]>>8) ];
i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id];
- *i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ];
- *(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
+ *i = alaw2lin_if4p5[ (data_block[element_id+db_halflength] & 0xff) ];
+ *(i+1) = alaw2lin_if4p5[ (data_block[element_id+db_halflength]>>8) ];
+
+ //if (element_id==0) LOG_I(PHY,"recv_if4p5: symbol %d rxdata0 = (%u,%u)\n",*symbol_number,*i,*(i+1));
}
-
- } else if (*packet_type == IF4p5_PRACH) {
- if (eNB->CC_id==1) LOG_I(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
+ } else if (*packet_type == IF4p5_PRACH) {
+ LOG_D(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d\n",eNB->CC_id,*frame,*subframe);
+ if (eNB->CC_id==1) LOG_I(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d\n",eNB->CC_id,*frame,*subframe);
// FIX: hard coded prach samples length
db_fulllength = PRACH_HARD_CODED_NUM_SAMPLES;
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
index 5b1c834705..399ebc4da2 100644
--- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
@@ -31,13 +31,22 @@
*/
#include "PHY/defs.h"
+#include "PHY/TOOLS/alaw_lut.h"
-#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
+#include "time_utils.h"
+
+//#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
+#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
//#define DEBUG_DL_MOBIPASS
//#define DEBUG_UL_MOBIPASS
#define SUBFRAME_SKIP_NUM_MOBIPASS 8
+const uint8_t lin2alaw_if5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85};
+
+const uint16_t alaw2lin_if5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848};
+
+struct timespec start_comp, start_decomp, end_comp, end_decomp;
int dummy_cnt = 0;
int subframe_skip_extra = 0;
int start_flag = 1;
@@ -47,55 +56,128 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx];
int32_t *tx_buffer=NULL;
-
int8_t dummy_buffer[fp->samples_per_tti*2];
- uint16_t packet_id=0, i=0;
+ void *alaw_buffer = eNB->ifbuffer.tx[subframe&1];
+ uint16_t *data_block = NULL;
+ uint16_t *j = NULL;
+ uint16_t packet_id=0, i=0, element_id=0;
uint32_t spp_eth = (uint32_t) eNB->ifdevice.openair0_cfg->samples_per_packet;
uint32_t spsf = (uint32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10;
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
-
+ eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
if (packet_type == IF5_RRH_GW_DL) {
-
- for (i=0; i < fp->nb_antennas_tx; i++)
- txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti];
-
- for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
- eNB->ifdevice.trx_write_func(&eNB->ifdevice,
- (proc_timestamp + packet_id*spp_eth),
- (void**)txp,
- spp_eth,
- fp->nb_antennas_tx,
- 0);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
+ if (eth->compression == ALAW_COMPRESS) {
+ if (eth->flags == ETH_RAW_MODE) {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
+ } else {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES);
+ }
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_comp);
+ for (i=0; i < fp->nb_antennas_tx; i++) {
+ for (element_id=0; element_id< spp_eth; element_id++){
+ j = (uint16_t*) &eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id];
+ data_block[element_id] = ((uint16_t) lin2alaw_if5[*j]) | (lin2alaw_if5[*(j+1)]<<8);
+ }
+ }
+ clock_gettime( CLOCK_MONOTONIC, &end_comp);
+ LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_comp);
+ eNB->ifdevice.trx_write_func(&eNB->ifdevice,
+ (proc_timestamp + packet_id*spp_eth),
+ (void**)&data_block,
+ spp_eth,
+ fp->nb_antennas_tx,
+ 0);
+ clock_gettime( CLOCK_MONOTONIC, &end_comp);
+ LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
+ }
+ } else if (eth->compression == NO_COMPRESS) {
for (i=0; i < fp->nb_antennas_tx; i++)
- txp[i] += spp_eth;
+ txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti];
+
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_comp);
+ eNB->ifdevice.trx_write_func(&eNB->ifdevice,
+ (proc_timestamp + packet_id*spp_eth),
+ (void**)txp,
+ spp_eth,
+ fp->nb_antennas_tx,
+ 0);
+ clock_gettime( CLOCK_MONOTONIC, &end_comp);
+ LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
+ for (i=0; i < fp->nb_antennas_tx; i++)
+ txp[i] += spp_eth;
+ }
}
-
} else if (packet_type == IF5_RRH_GW_UL) {
-
- for (i=0; i < fp->nb_antennas_rx; i++)
- rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
-
- for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
- eNB->ifdevice.trx_write_func(&eNB->ifdevice,
- (proc_timestamp + packet_id*spp_eth),
- (void**)rxp,
- spp_eth,
- fp->nb_antennas_rx,
- 0);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
+ if (eth->compression == ALAW_COMPRESS) {
+ if (eth->flags == ETH_RAW_MODE) {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
+ } else {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES);
+ }
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_comp);
+ for (i=0; i < fp->nb_antennas_rx; i++) {
+ for (element_id=0; element_id< spp_eth; element_id++){
+ j = (uint16_t*) &eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id];
+ data_block[element_id] = ((uint16_t) lin2alaw_if5[*j]) | (lin2alaw_if5[*(j+1)]<<8);
+ if (packet_id == 0 && element_id == 0) {
+ //printf("(UL_Tx)Ori: %u(%d, %d); ALAW: %u; SF %u\n",eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id],*j,*(j+1),data_block[element_id],subframe);
+ }
+ }
+ }
+ clock_gettime( CLOCK_MONOTONIC, &end_comp);
+ LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_comp);
+ eNB->ifdevice.trx_write_func(&eNB->ifdevice,
+ (proc_timestamp + packet_id*spp_eth),
+ (void**)&data_block,
+ spp_eth,
+ fp->nb_antennas_rx,
+ 0);
+ clock_gettime( CLOCK_MONOTONIC, &end_comp);
+ LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
+ }
+ } else if (eth->compression == NO_COMPRESS) {
for (i=0; i < fp->nb_antennas_rx; i++)
- rxp[i] += spp_eth;
-
- }
+ rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_comp);
+ eNB->ifdevice.trx_write_func(&eNB->ifdevice,
+ (proc_timestamp + packet_id*spp_eth),
+ (void**)rxp,
+ spp_eth,
+ fp->nb_antennas_rx,
+ 0);
+ clock_gettime( CLOCK_MONOTONIC, &end_comp);
+ LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
+ for (i=0; i < fp->nb_antennas_rx; i++)
+ rxp[i] += spp_eth;
+
+ }
+ }
} else if (packet_type == IF5_MOBIPASS) {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
@@ -179,56 +261,129 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx];
- uint16_t packet_id=0, i=0;
+ uint16_t packet_id=0, i=0, element_id=0;
int8_t dummy_buffer_rx[fp->samples_per_tti*2];
uint8_t rxe;
int32_t spp_eth = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_packet;
int32_t spsf = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10;
-
+ void *alaw_buffer = eNB->ifbuffer.rx;
+ uint16_t *data_block = NULL;
+ uint16_t *j = NULL;
openair0_timestamp timestamp[spsf / spp_eth];
+ eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );
if (packet_type == IF5_RRH_GW_DL) {
-
- for (i=0; i < fp->nb_antennas_tx; i++)
- txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti];
-
- for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ if (eth->compression == ALAW_COMPRESS) {
+ if (eth->flags == ETH_RAW_MODE) {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
+ } else {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES);
+ }
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_decomp);
+ eNB->ifdevice.trx_read_func(&eNB->ifdevice,
+ ×tamp[packet_id],
+ (void**)&data_block,
+ spp_eth,
+ fp->nb_antennas_tx);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
- eNB->ifdevice.trx_read_func(&eNB->ifdevice,
- ×tamp[packet_id],
- (void**)txp,
- spp_eth,
- fp->nb_antennas_tx);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
+ clock_gettime( CLOCK_MONOTONIC, &end_decomp);
+ LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_decomp);
+ for (i=0; i < fp->nb_antennas_tx; i++) {
+ for (element_id=0; element_id< spp_eth; element_id++) {
+ j = (uint16_t*) &eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id];
+ *j = alaw2lin_if5[ (data_block[element_id] & 0xff) ];
+ *(j+1) = alaw2lin_if5[ (data_block[element_id]>>8) ];
+ }
+ }
+ clock_gettime( CLOCK_MONOTONIC, &end_decomp);
+ LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
+ }
+ } else if (eth->compression == NO_COMPRESS) {
for (i=0; i < fp->nb_antennas_tx; i++)
- txp[i] += spp_eth;
-
- }
+ txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti];
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_decomp);
+ eNB->ifdevice.trx_read_func(&eNB->ifdevice,
+ ×tamp[packet_id],
+ (void**)txp,
+ spp_eth,
+ fp->nb_antennas_tx);
+ clock_gettime( CLOCK_MONOTONIC, &end_decomp);
+ LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
+ for (i=0; i < fp->nb_antennas_tx; i++)
+ txp[i] += spp_eth;
+
+ }
+ }
*proc_timestamp = timestamp[0];
} else if (packet_type == IF5_RRH_GW_UL) {
-
- for (i=0; i < fp->nb_antennas_rx; i++)
- rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
-
- for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
- eNB->ifdevice.trx_read_func(&eNB->ifdevice,
- ×tamp[packet_id],
- (void**)rxp,
- spp_eth,
- fp->nb_antennas_rx);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
+ if (eth->compression == ALAW_COMPRESS) {
+ if (eth->flags == ETH_RAW_MODE) {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
+ } else {
+ data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES);
+ }
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_decomp);
+ eNB->ifdevice.trx_read_func(&eNB->ifdevice,
+ ×tamp[packet_id],
+ (void**)&data_block,
+ spp_eth,
+ fp->nb_antennas_rx);
+ clock_gettime( CLOCK_MONOTONIC, &end_decomp);
+ LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_decomp);
+ for (i=0; i < fp->nb_antennas_rx; i++) {
+ for (element_id=0; element_id< spp_eth; element_id++) {
+ j = (uint16_t*) &eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id];
+ *j = alaw2lin_if5[ (data_block[element_id] & 0xff) ];
+ *(j+1) = alaw2lin_if5[ (data_block[element_id]>>8) ];
+ }
+ }
+ clock_gettime( CLOCK_MONOTONIC, &end_decomp);
+ LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
+ }
+ } else if (eth->compression == NO_COMPRESS) {
for (i=0; i < fp->nb_antennas_rx; i++)
- rxp[i] += spp_eth;
+ rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
+
+ for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 );
+ clock_gettime( CLOCK_MONOTONIC, &start_decomp);
+ eNB->ifdevice.trx_read_func(&eNB->ifdevice,
+ ×tamp[packet_id],
+ (void**)rxp,
+ spp_eth,
+ fp->nb_antennas_rx);
+ clock_gettime( CLOCK_MONOTONIC, &end_decomp);
+ LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 );
+ for (i=0; i < fp->nb_antennas_rx; i++)
+ rxp[i] += spp_eth;
+ }
}
-
*proc_timestamp = timestamp[0];
} else if (packet_type == IF5_MOBIPASS) {
@@ -363,3 +518,30 @@ if (eNB->CC_id>0) {
return;
}
+
+void malloc_IF5_buffer(PHY_VARS_eNB *eNB) {
+ // Keep the size large enough, 3840 is the number of samples in a packet for 20MHz BW
+ int i;
+ eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv);
+ if (eth->compression == ALAW_COMPRESS) {
+ if (eth->flags == ETH_RAW_MODE) {
+ for (i=0;i<10;i++)
+ eNB->ifbuffer.tx[i] = malloc(RAW_PACKET_SIZE_BYTES_ALAW(3840));
+ eNB->ifbuffer.rx = malloc(RAW_PACKET_SIZE_BYTES_ALAW(3840));
+ } else {
+ for (i=0;i<10;i++)
+ eNB->ifbuffer.tx[i] = malloc(UDP_PACKET_SIZE_BYTES_ALAW(3840));
+ eNB->ifbuffer.rx = malloc(UDP_PACKET_SIZE_BYTES_ALAW(3840));
+ }
+ } else if (eth->compression == NO_COMPRESS) {
+ if (eth->flags == ETH_RAW_MODE) {
+ for (i=0;i<10;i++)
+ eNB->ifbuffer.tx[i] = malloc(RAW_PACKET_SIZE_BYTES(3840));
+ eNB->ifbuffer.rx = malloc(RAW_PACKET_SIZE_BYTES(3840));
+ } else {
+ for (i=0;i<10;i++)
+ eNB->ifbuffer.tx[i] = malloc(UDP_PACKET_SIZE_BYTES(3840));
+ eNB->ifbuffer.rx = malloc(UDP_PACKET_SIZE_BYTES(3840));
+ }
+ }
+}
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.h b/openair1/PHY/LTE_TRANSPORT/if5_tools.h
index b6ebe8c841..88852de58b 100644
--- a/openair1/PHY/LTE_TRANSPORT/if5_tools.h
+++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.h
@@ -59,3 +59,5 @@ typedef struct IF5_mobipass_header IF5_mobipass_header_t;
void send_IF5(PHY_VARS_eNB*, openair0_timestamp, int, uint8_t*, uint16_t);
void recv_IF5(PHY_VARS_eNB*, openair0_timestamp*, int, uint16_t);
+
+void malloc_IF5_buffer(PHY_VARS_eNB*);
diff --git a/openair1/PHY/LTE_TRANSPORT/pcfich.c b/openair1/PHY/LTE_TRANSPORT/pcfich.c
index 3b141372f0..3319cd0f78 100644
--- a/openair1/PHY/LTE_TRANSPORT/pcfich.c
+++ b/openair1/PHY/LTE_TRANSPORT/pcfich.c
@@ -69,9 +69,9 @@ void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
first_reg = pcfich_reg[3];
}
- //#ifdef DEBUG_PCFICH
+ #ifdef DEBUG_PCFICH
printf("pcfich_reg : %d,%d,%d,%d\n",pcfich_reg[0],pcfich_reg[1],pcfich_reg[2],pcfich_reg[3]);
- //#endif
+ #endif
}
void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index b46c416706..df789cd174 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -307,7 +307,7 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
Ngroup_PHICH<<=1;
}
- //#ifdef DEBUG_PHICH
+ #ifdef DEBUG_PHICH
printf("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,
@@ -317,7 +317,7 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
n0,
n1,
((frame_parms->Nid_cell))%n0);
- //#endif
+ #endif
// This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ...
@@ -371,9 +371,9 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
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
+ #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
+ #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;
@@ -1375,11 +1375,7 @@ void rx_phich(PHY_VARS_UE *ue,
HI16,
nseq_PHICH,
ngroup_PHICH);
- get_Msg3_alloc_ret(&ue->frame_parms,
- subframe,
- proc->frame_rx,
- &ue->ulsch_Msg3_frame[eNB_id],
- &ue->ulsch_Msg3_subframe[eNB_id]);
+
ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
// ulsch->harq_processes[harq_pid]->Ndi = 0;
ulsch->harq_processes[harq_pid]->round++;
@@ -1393,13 +1389,13 @@ void rx_phich(PHY_VARS_UE *ue,
}
} else {
//#ifdef DEBUG_PHICH
- LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d (Mlimit %d)\n",
+ LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n",
ue->Mod_id,harq_pid,
proc->frame_rx%1024,
subframe,
HI16,
nseq_PHICH,
- ngroup_PHICH,ulsch->harq_processes[harq_pid]->round+1,
+ ngroup_PHICH,
ulsch->Mlimit);
//#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c
index 4a9010fca0..b4199d9b60 100644
--- a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c
+++ b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c
@@ -1,31 +1,23 @@
-/*******************************************************************************
- OpenAirInterface
- Copyright(c) 1999 - 2014 Eurecom
-
- OpenAirInterface is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
-
- OpenAirInterface is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with OpenAirInterface.The full GNU General Public License is
- included in this distribution in the file called "COPYING". If not,
- see .
-
- Contact Information
- OpenAirInterface Admin: openair_admin@eurecom.fr
- OpenAirInterface Tech : openair_tech@eurecom.fr
- OpenAirInterface Dev : openair4g-devel@eurecom.fr
-
- Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
-
- *******************************************************************************/
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
/*! \file PHY/LTE_TRANSPORT/uespec_pilots.c
* \brief Top-level routines for generating DL ue-specific reference signals V12.5 2015-03
diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c
index 4de2b6b775..743c16b2f0 100644
--- a/openair1/PHY/LTE_TRANSPORT/power_control.c
+++ b/openair1/PHY/LTE_TRANSPORT/power_control.c
@@ -19,126 +19,132 @@
* contact@openairinterface.org
*/
-#include "PHY/defs.h"
-#include "PHY/impl_defs_lte.h"
-
-//#define DEBUG_PC 1
-
-/*
-double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0},
- { 5.0/4.0,1.0,3.0/4.0,1.0/2.0}};
-*/
-
-double ratioPB[2][4]= {{ 0.00000, -0.96910, -2.21849, -3.97940},
- { 0.96910, 0.00000, -1.24939, -3.01030}
-};
-
-double pa_values[8]= {-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0};
-
-double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated)
-{
- return(pa_values[pdsch_config_dedicated->p_a]);
-}
-
-double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- LTE_eNB_DLSCH_t *dlsch_eNB,int dl_power_off)
-{
- double rho_a_dB;
- double sqrt_rho_a_lin;
-
- rho_a_dB = pa_values[ pdsch_config_dedicated->p_a];
-
- if(!dl_power_off)
- rho_a_dB-=10*log10(2);
-
- sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
-
- dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
-
-#ifdef DEBUG_PC
- printf("sqrt_rho_a(eNB):%d\n",dlsch_eNB->sqrt_rho_a);
-#endif
-
- return(rho_a_dB);
-}
-
-double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- PDSCH_CONFIG_COMMON *pdsch_config_common,
- uint8_t n_antenna_port,
- LTE_eNB_DLSCH_t *dlsch_eNB,
- int dl_power_off)
-{
-
- double rho_a_dB, rho_b_dB;
- double sqrt_rho_b_lin;
-
- rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off);
-
- if(n_antenna_port>1)
- rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
- else
- rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
-
- sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
-
- dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
-
-#ifdef DEBUG_PC
- printf("sqrt_rho_b(eNB):%d\n",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)
-{
-
- double rho_a_dB;
- double sqrt_rho_a_lin;
-
- rho_a_dB = pa_values[ pdsch_config_dedicated->p_a];
-
- if(!dl_power_off)
- rho_a_dB-=10*log10(2);
-
- sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
-
- dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
-
-#ifdef DEBUG_PC
- printf("sqrt_rho_a(ue):%d\n",dlsch_ue->sqrt_rho_a);
-#endif
-
- return(rho_a_dB);
-}
-
-double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- PDSCH_CONFIG_COMMON *pdsch_config_common,
- uint8_t n_antenna_port,
- LTE_UE_DLSCH_t *dlsch_ue,
- unsigned char dl_power_off)
-{
-
- double rho_a_dB, rho_b_dB;
- double sqrt_rho_b_lin;
-
- rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off);
-
- if(n_antenna_port>1)
- rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
- else
- rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
-
- sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
-
- dlsch_ue->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
-
-#ifdef DEBUG_PC
- printf("sqrt_rho_b(ue):%d\n",dlsch_ue->sqrt_rho_b);
-#endif
- return(rho_b_dB);
-}
-
-
+#include "PHY/defs.h"
+#include "PHY/impl_defs_lte.h"
+
+//#define DEBUG_PC 0
+/*
+double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0},
+ { 5.0/4.0,1.0,3.0/4.0,1.0/2.0}};
+*/
+
+double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db
+ { 0.96910, 0.00000, -1.24939, -3.01030}};
+
+double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by higher layers
+
+double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated)
+{
+ if (pdsch_config_dedicated)
+ return(pa_values[ pdsch_config_dedicated->p_a]);
+ else
+ return(0.0);
+}
+
+double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port){
+ double rho_a_dB;
+ double sqrt_rho_a_lin;
+
+ rho_a_dB = get_pa_dB(pdsch_config_dedicated);
+
+ if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5
+ rho_a_dB-=10*log10(2);
+
+ if(n_antenna_port==4) // see TS 36.213 Section 5.2
+ rho_a_dB=+10*log10(2);
+
+ sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
+
+ dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
+
+#if DEBUG_PC
+ printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a);
+#endif
+
+ return(rho_a_dB);
+}
+
+double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ PDSCH_CONFIG_COMMON *pdsch_config_common,
+ uint8_t n_antenna_port,
+ LTE_eNB_DLSCH_t *dlsch_eNB,
+ int dl_power_off)
+{
+
+ double rho_a_dB, rho_b_dB;
+ double sqrt_rho_b_lin;
+
+ rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off, n_antenna_port);
+
+ if(n_antenna_port>1)
+ rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
+ else
+ rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
+
+ sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
+
+ dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
+
+#ifdef DEBUG_PC
+ printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pdsch_config_common->p_b,ratioPB[1][pdsch_config_common->p_b],dlsch_eNB->sqrt_rho_b);
+#endif
+ return(rho_b_dB);
+}
+
+
+double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ LTE_UE_DLSCH_t *dlsch_ue,
+ unsigned char dl_power_off,
+ uint8_t n_antenna_port
+ ){
+
+ double rho_a_dB;
+ double sqrt_rho_a_lin;
+
+ rho_a_dB = get_pa_dB(pdsch_config_dedicated);
+
+ if(!dl_power_off)
+ rho_a_dB-=10*log10(2);
+ //if dl_power_offset is 0, this is for MU-interference, TM5. But in practice UE may assume 16 or 64QAM TM4 as multiuser
+
+ if(n_antenna_port==4) // see TS 36.213 Section 5.2
+ rho_a_dB=+10*log10(2);
+
+ sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
+
+ dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
+
+#ifdef DEBUG_PC
+ printf("UE: p_a=%d, value=%f, dl_power_off=%d, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dl_power_off,dlsch_ue->sqrt_rho_a);
+#endif
+
+ return(rho_a_dB);
+}
+
+double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ PDSCH_CONFIG_COMMON *pdsch_config_common,
+ uint8_t n_antenna_port,
+ LTE_UE_DLSCH_t *dlsch_ue,
+ unsigned char dl_power_off)
+{
+
+ double rho_a_dB, rho_b_dB;
+ double sqrt_rho_b_lin;
+
+ rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off, n_antenna_port);
+
+ if(n_antenna_port>1)
+ rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
+ else
+ rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
+
+ sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
+
+ dlsch_ue->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
+
+#ifdef DEBUG_PC
+ printf("UE: p_b=%d, n_ant=%d -> ratio=%f -> sqrt_rho_b=%d\n",pdsch_config_common->p_b, n_antenna_port,ratioPB[1][pdsch_config_common->p_b],dlsch_ue->sqrt_rho_b);
+#endif
+ return(rho_b_dB);
+}
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index 489fdb0f71..bffcd4b23a 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -645,6 +645,12 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
#else //normal case (simulation)
prach_start = subframe*ue->frame_parms.samples_per_tti-ue->N_TA_offset;
+ LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
+ prach_start,
+ ue->rx_offset,
+ ue->hw_timing_advance,
+ ue->N_TA_offset);
+
#endif
@@ -1074,6 +1080,8 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
#ifdef PRACH_DEBUG
write_output("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1);
write_output("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1);
+ write_output("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][0]),2*ue->frame_parms.samples_per_tti,1,1);
+ exit(-1);
#endif
return signal_energy( (int*)prach, 256 );
@@ -1125,7 +1133,6 @@ void rx_prach(PHY_VARS_eNB *eNB,
int fft_size,log2_ifft_size;
uint8_t nb_ant_rx = 1; //eNB->frame_parms.nb_antennas_rx;
- // int en;
for (aa=0; aacommon_vars.rxdata[0][aa][subframe*eNB->frame_parms.samples_per_tti-eNB->N_TA_offset];
@@ -1327,9 +1334,26 @@ void rx_prach(PHY_VARS_eNB *eNB,
/// **** send_IF4 of rxsigF to RCC **** ///
send_IF4p5(eNB, eNB->proc.frame_prach, eNB->proc.subframe_prach, IF4p5_PRACH, k);
- // en = dB_fixed(signal_energy(&rxsigF[0][k],840));
- // if (en>60)
- // printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
+#if 0
+ /* TODO: resolv this conflict (there should be no printf anyway, so no big deal) */
+<<<<<<< HEAD
+ /*
+ en = dB_fixed(signal_energy(&rxsigF[0][k],840));
+ printf("Sending PRACH, k %d,n_ra_prb %d, N_RB_UL %d, en %d\n",k,n_ra_prb,eNB->frame_parms.N_RB_UL,en);
+ if (en>60) {
+ printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
+ write_output("prach_rx0.m","prach_rx0",(int16_t*)&rxsigF[0][k],839,1,1);
+ exit(-1);
+ }
+ */
+
+=======
+ en = dB_fixed(signal_energy(&rxsigF[0][k],840));
+ if (en>60)
+ printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
+>>>>>>> origin/fix-if4p5
+#endif
+
return;
} else if (eNB->node_function == NGFI_RCC_IF4p5) {
k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
@@ -1347,9 +1371,25 @@ void rx_prach(PHY_VARS_eNB *eNB,
(&rxsigF[0][0]),
839*2*sizeof(int16_t));
- //en = dB_fixed(signal_energy(&rxsigF[0][k],840));
- // if (en>60)
- //printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
+#if 0
+ /* TODO: resolv this conflict (there should be no printf anyway, so no big deal) */
+<<<<<<< HEAD
+ /*
+ en = dB_fixed(signal_energy(&rxsigF[0][k],840));
+ printf("Receiving PRACH, k %d,n_ra_prb %d, N_RB_UL %d, en %d\n",k,n_ra_prb,eNB->frame_parms.N_RB_UL,en);
+ if (en>60) {
+ printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
+ write_output("prach_rx0.m","prach_rx0",(int16_t*)&rxsigF[0][k],839,1,1);
+ exit(-1);
+ }
+ */
+=======
+ en = dB_fixed(signal_energy(&rxsigF[0][k],840));
+ /*if (en>60)
+ printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);*/
+
+>>>>>>> origin/fix-if4p5
+#endif
}
@@ -1523,7 +1563,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
#ifdef PRACH_DEBUG
- // if (en>40) {
+ if (en>40) {
k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
if (k<0)
@@ -1537,7 +1577,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
write_output("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
write_output("prach_ifft0.m","prach_t0",prach_ifft[0],1024,1,1);
exit(-1);
- // }
+ }
#endif
} // new dft
@@ -1551,7 +1591,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
for (aa=0; aapreamble_energy_list[preamble_index] ) {
@@ -1559,12 +1599,12 @@ void rx_prach(PHY_VARS_eNB *eNB,
preamble_delay_list[preamble_index] = (i*fft_size)>>log2_ifft_size;
}
}
-
#ifdef PRACH_DEBUG
LOG_D(PHY,"[RAPROC] Preamble %d => %d dB, %d (shift %d (%d), NCS2 %d(%d), Ncp %d)\n",preamble_index,preamble_energy_list[preamble_index],preamble_delay_list[preamble_index],preamble_shift2,
preamble_shift, NCS2,NCS,Ncp);
-#endif
// exit(-1);
+#endif
+
}// preamble_index
stop_meas(&eNB->rx_prach);
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 52c258762b..5fc8dea986 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -121,6 +121,18 @@ int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
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,
@@ -180,7 +192,7 @@ void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
\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 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
@@ -192,7 +204,7 @@ void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
\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 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
@@ -281,6 +293,13 @@ int32_t dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
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
@@ -789,6 +808,18 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
@param beamforming_mode beamforming mode
*/
+int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int32_t **sic_buffer,
+ int **rho_i,
+ short *dlsch_llr,
+ uint8_t num_pdcch_symbols,
+ uint16_t nb_rb,
+ uint8_t subframe,
+ uint32_t rb_alloc,
+ uint16_t mod_order_0,
+ LTE_UE_DLSCH_t *dlsch0);
+
void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *dlsch_llr,
@@ -799,7 +830,6 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t pbch_pss_sss_adjust,
int16_t **llr128p,
uint8_t beamforming_mode);
-
/**
\brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
@param frame_parms Frame descriptor structure
@@ -813,6 +843,34 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
@param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs)
@param beamforming_mode beamforming mode
*/
+void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **sic_buffer, //Q15
+ int32_t **rho_i,
+ int16_t *dlsch_llr,
+ uint8_t num_pdcch_symbols,
+ int32_t **dl_ch_mag,
+ uint16_t nb_rb,
+ uint8_t subframe,
+ uint32_t rb_alloc,
+ uint16_t mod_order_0,
+ LTE_UE_DLSCH_t *dlsch0);
+
+void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **sic_buffer, //Q15
+ int32_t **rho_i,
+ int16_t *dlsch_llr,
+ uint8_t num_pdcch_symbols,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint16_t nb_rb,
+ uint8_t subframe,
+ uint32_t rb_alloc,
+ uint16_t mod_order_0,
+ LTE_UE_DLSCH_t *dlsch0);
+
+
void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *dlsch_llr,
@@ -825,6 +883,7 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
int16_t **llr_save,
uint8_t beamforming_mode);
+
/** \fn dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
@@ -922,6 +981,14 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t nb_rb,
uint8_t dual_stream_UE);
+void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms,
+ LTE_UE_PDSCH *lte_ue_pdsch_vars,
+ int harq_pid,
+ int round,
+ unsigned char symbol,
+ unsigned short nb_rb,
+ unsigned char dual_stream_UE);
+
/** \fn dlsch_extract_rbs_single(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
@@ -992,7 +1059,8 @@ uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
- LTE_DL_FRAME_PARMS *frame_parms);
+ LTE_DL_FRAME_PARMS *frame_parms,
+ MIMO_mode_t mimo_mode);
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
@@ -1062,6 +1130,15 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
int **dl_ch_rho_ext,
unsigned char output_shift);
+void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms,
+ unsigned char symbol,
+ unsigned short nb_rb,
+ int **dl_ch_estimates_ext,
+ int **dl_ch_estimates_ext_i,
+ int **dl_ch_rho_ext,
+ unsigned char output_shift0,
+ unsigned char output_shift1);
+
void dlsch_channel_compensation_TM56(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
@@ -1077,16 +1154,20 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext,
unsigned char output_shift,
unsigned char dl_power_off);
-void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms,
+
+void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *lte_ue_pdsch_vars,
PHY_MEASUREMENTS *phy_measurements,
int eNB_id,
unsigned char symbol,
unsigned char mod_order0,
unsigned char mod_order1,
+ int harq_pid,
int round,
+ MIMO_mode_t mimo_mode,
unsigned short nb_rb,
- unsigned char output_shift);
+ unsigned char output_shift0,
+ unsigned char output_shift1);
/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
@@ -1102,11 +1183,16 @@ void dlsch_channel_level(int32_t **dl_ch_estimates_ext,
uint8_t pilots_flag,
uint16_t nb_rb);
-void dlsch_channel_level_TM3(int **dl_ch_estimates_ext,
- LTE_DL_FRAME_PARMS *frame_parms,
- int *avg,
- uint8_t symbol,
- unsigned short nb_rb);
+
+void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
+ LTE_DL_FRAME_PARMS *frame_parms,
+ unsigned char *pmi_ext,
+ int *avg_0,
+ int *avg_1,
+ uint8_t symbol,
+ unsigned short nb_rb,
+ MIMO_mode_t mimo_mode);
+
void dlsch_channel_level_TM56(int32_t **dl_ch_estimates_ext,
LTE_DL_FRAME_PARMS *frame_parms,
@@ -1167,6 +1253,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
- RE extraction (pilot, PBCH, synch. signals)
- antenna combining (MRC, Alamouti, cycling)
- LLR computation
+ This function supports TM1, 2, 3, 5, and 6.
@param phy_vars_ue Pointer to PHY variables
@param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH)
@param eNB_id eNb index (Nid1) 0,1,2
@@ -1174,7 +1261,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
@param subframe Subframe number
@param symbol Symbol on which to act (within sub-frame)
@param first_symbol_flag set to 1 on first DLSCH symbol
- @param dual_stream_UE Flag to indicate dual-stream interference cancellation
+ @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
@param i_mod Modulation order of the interfering stream
*/
int32_t rx_pdsch(PHY_VARS_UE *phy_vars_ue,
@@ -1185,7 +1272,7 @@ int32_t rx_pdsch(PHY_VARS_UE *phy_vars_ue,
uint8_t subframe,
uint8_t symbol,
uint8_t first_symbol_flag,
- uint8_t dual_stream_UE,
+ RX_type_t rx_type,
uint8_t i_mod,
uint8_t harq_pid);
@@ -1397,7 +1484,7 @@ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb);
*/
uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap);
-/* \brief Return prb for a given vrb index
+/* \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
*/
@@ -1521,7 +1608,7 @@ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t
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,
+ uint8_t subframe,
void *dci_pdu,
rnti_t rnti,
DCI_format_t dci_format,
@@ -1591,10 +1678,6 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,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);
@@ -1771,10 +1854,20 @@ 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);
+/** \brief This routine computes the subband PMI bitmap based on measurements (0,1,2,3 for rank 0 and 0,1 for rank 1) in the format needed for UCI
+ @param meas pointer to measurements
+ @param eNB_id eNB_id
+ @param nb_subbands number of subbands
+ @returns subband PMI bitmap
+*/
uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands);
-uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands);
+
+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);
@@ -1784,14 +1877,29 @@ uint64_t cqi2hex(uint32_t cqi);
uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
-uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi);
+/** \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
+ @param mimo_mode
+ @param pmi_alloc subband PMI bitmap
+ @param rb resource block for which to extract PMI
+ @returns subband PMI
+*/
+uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
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);
+ 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);
@@ -1849,7 +1957,7 @@ void generate_pucch2x(int32_t **txdataF,
PUCCH_FMT_t fmt,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint16_t n2_pucch,
- uint16_t *payload,
+ uint8_t *payload,
int A,
int B2,
int16_t amp,
@@ -1867,15 +1975,15 @@ void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue,
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);
+ 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,
@@ -1885,7 +1993,6 @@ int32_t rx_pucch_emul(PHY_VARS_eNB *phy_vars_eNB,
uint8_t *payload);
-
/*!
\brief Check for PRACH TXop in subframe
@param frame_parms Pointer to LTE_DL_FRAME_PARMS
@@ -1979,16 +2086,19 @@ 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);
+ int dl_power_off,
+ uint8_t n_antenna_port);
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);
+ 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,
- uint8_t dl_power_off);
+ uint8_t dl_power_off,
+ uint8_t n_antenna_port);
double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
PDSCH_CONFIG_COMMON *pdsch_config_common,
@@ -2002,7 +2112,7 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
LTE_UE_DLSCH_t *dlsch_ue);
*/
-uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf);
+uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf);
uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n);
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index db671f048c..563f83bb7f 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -473,7 +473,7 @@ void generate_pucch2x(int32_t **txdataF,
PUCCH_FMT_t fmt,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint16_t n2_pucch,
- uint16_t *payload,
+ uint8_t *payload,
int A,
int B2,
int16_t amp,
@@ -573,7 +573,8 @@ void generate_pucch2x(int32_t **txdataF,
n_cs = (ncs_cell[ns][l]+nprime)%12;
alpha_ind = 0;
- for (n=0; n<12; n++) {
+ for (n=0; n<12; n++)
+ {
// this is r_uv^alpha(n)
ref_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
ref_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);
@@ -584,11 +585,25 @@ void generate_pucch2x(int32_t **txdataF,
//LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n);
}
else {
- ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15);
- ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15);
- //LOG_I(PHY,"slot %d ofdm# %d ==> dmrs[%d] \n",ns,l,n);
- }
- alpha_ind = (alpha_ind + n_cs)%12;
+ if ((l==1) || ( (l==5) && (fmt==pucch_format2) ))
+ {
+ ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15);
+ ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15);
+ }
+ // l == 5 && pucch format 2a
+ else if (fmt==pucch_format2a)
+ {
+ ((int16_t *)&zptr[n])[0] = ((int32_t)d[20]*ref_re>>15);
+ ((int16_t *)&zptr[n])[1] = ((int32_t)d[21]*ref_im>>15);
+ }
+ // l == 5 && pucch format 2b
+ else if (fmt==pucch_format2b)
+ {
+ ((int16_t *)&zptr[n])[0] = ((int32_t)d[20]*ref_re>>15);
+ ((int16_t *)&zptr[n])[1] = ((int32_t)d[21]*ref_im>>15);
+ }
+ } // l==1 || l==5
+ alpha_ind = (alpha_ind + n_cs)%12;
} // n
zptr+=12;
diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
index 467b1bbc9a..fba5b0c0e3 100644
--- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
@@ -168,6 +168,7 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_
//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) {
@@ -275,6 +276,11 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_
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)*2)<<2*i;
break;
case HLC_subband_cqi_nopmi:
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 8edb1eaf94..ca67ccdb3c 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -418,6 +418,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
extern int oai_exit;
void *td_thread(void *param) {
+ pthread_setname_np( pthread_self(), "td processing");
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
eNB_proc_t *proc = &eNB->proc;
@@ -2067,7 +2068,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
get_ack(&eNB->frame_parms,
PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0]->harq_ack,
subframe,
- eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK);
+ eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0);
} else { // get remote UEs' ack
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0];
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[1];
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
index ee9bfc53cd..a4bcd802f5 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
@@ -415,7 +415,7 @@ void ulsch_modulation(int32_t **txdataF,
return;
}
- if (first_rb >25 ) {
+ if (first_rb > frame_parms->N_RB_UL) {
printf("ulsch_modulation.c: Frame %d, Subframe %d Illegal first_rb %d\n",frame,subframe,first_rb);
return;
}
diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c
index 88ac12b0a7..d2336f6187 100644
--- a/openair1/PHY/MODULATION/beamforming.c
+++ b/openair1/PHY/MODULATION/beamforming.c
@@ -1,31 +1,23 @@
-/*******************************************************************************
- OpenAirInterface
- Copyright(c) 1999 - 2014 Eurecom
-
- OpenAirInterface is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
-
- OpenAirInterface is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with OpenAirInterface.The full GNU General Public License is
- included in this distribution in the file called "COPYING". If not,
- see .
-
- Contact Information
- OpenAirInterface Admin: openair_admin@eurecom.fr
- OpenAirInterface Tech : openair_tech@eurecom.fr
- OpenAirInterface Dev : openair4g-devel@eurecom.fr
-
-Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
-
- *******************************************************************************/
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
/*! \file PHY/MODULATION/beamforming.c
* \brief
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index 01e04f0959..04645eb8c1 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -136,7 +136,7 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
#ifdef DEBUG_OFDM_MOD
printf("[PHY] symbol %d/%d offset %d (%p,%p -> %p)\n",i,nb_symbols,i*fftsize+(i*nb_prefix_samples),input,&input[i*fftsize],&output[(i*fftsize) + ((i)*nb_prefix_samples)]);
#endif
- /*
+
#ifndef __AVX2__
// handle 128-bit alignment for 128-bit SIMD (SSE4,NEON,AltiVEC)
idft((int16_t *)&input[i*fftsize],
@@ -149,11 +149,7 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
1);
#endif
- */
- idft((int16_t *)&input[i*fftsize],
- (int16_t *)temp,
- 1);
// Copy to frame buffer with Cyclic Extension
// Note: will have to adjust for synchronization offset!
@@ -164,13 +160,11 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
// msg("Doing cyclic prefix method\n");
- /*
+
#ifndef __AVX2__
if (fftsize==128)
-
#else
- if (fftsize<=512)
- #endif*/
+#endif
{
for (j=0; j>3); i++) {
+ z_128[0] = _mm_subs_epi16(x_128[0],y_128[0]);
+
+ x_128++;
+ y_128++;
+ z_128++;
+
+ }
+
+ _mm_empty();
+ _m_empty();
+ return(0);
+}
+
+
+
int add_real_vector64(short *x,
short* y,
short *z,
diff --git a/openair1/PHY/TOOLS/cdot_prod.c b/openair1/PHY/TOOLS/cdot_prod.c
index d7c7dd3fea..7e73e58e5e 100644
--- a/openair1/PHY/TOOLS/cdot_prod.c
+++ b/openair1/PHY/TOOLS/cdot_prod.c
@@ -107,10 +107,10 @@ int32_t dot_product(int16_t *x,
// print_shorts("mmtmp7",&mmtmp7);
// convert back to integer
result = _mm_cvtsi64_si32(mmtmp7);
-
+
_mm_empty();
_m_empty();
-
+
return(result);
#elif defined(__arm__)
diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c
index aebab9b38f..bc631bd6cc 100644
--- a/openair1/PHY/TOOLS/cmult_sv.c
+++ b/openair1/PHY/TOOLS/cmult_sv.c
@@ -59,18 +59,23 @@ void multadd_complex_vector_real_scalar(int16_t *x,
if (zero_flag == 1)
for (n=0; n>2; n++) {
+ // print_shorts("x_128[n]=", &x_128[n]);
+ // print_shorts("alpha_128", &alpha_128);
y_128[n] = mulhi_int16(x_128[n],alpha_128);
+ // print_shorts("y_128[n]=", &y_128[n]);
}
else
for (n=0; n>2; n++) {
y_128[n] = adds_int16(y_128[n],mulhi_int16(x_128[n],alpha_128));
}
-
+
_mm_empty();
_m_empty();
}
+
+
void multadd_real_vector_complex_scalar(int16_t *x,
int16_t *alpha,
int16_t *y,
@@ -380,6 +385,7 @@ int rotate_cpx_vector(int16_t *x,
m3 = _mm_sra_epi32(m3,shift); // shift right by shift in order to compensate for the input amplitude
y_128[0] = _mm_packs_epi32(m2,m3); // pack in 16bit integers with saturation [re im re im re im re im]
+ //print_ints("y_128[0]=", &y_128[0]);
#elif defined(__arm__)
ab_re0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bconj)[0]);
diff --git a/openair1/PHY/TOOLS/cmult_vv.c b/openair1/PHY/TOOLS/cmult_vv.c
index 9d5079f52b..f8caa0c6da 100644
--- a/openair1/PHY/TOOLS/cmult_vv.c
+++ b/openair1/PHY/TOOLS/cmult_vv.c
@@ -28,8 +28,11 @@
#if defined(__x86_64__) || defined(__i386__)
int16_t conjug[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ;
int16_t conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+
#define simd_q15_t __m128i
#define simdshort_q15_t __m64
+#define set1_int16(a) _mm_set1_epi16(a)
+#define setr_int16(a0, a1, a2, a3, a4, a5, a6, a7) _mm_setr_epi16(a0, a1, a2, a3, a4, a5, a6, a7 )
#elif defined(__arm__)
int16_t conjug[4]__attribute__((aligned(16))) = {-1,1,-1,1} ;
#define simd_q15_t int16x8_t
@@ -45,7 +48,7 @@ int mult_cpx_conj_vector(int16_t *x1,
int output_shift,
int madd)
{
- // Multiply elementwise the complex conjugate of x1 with x2.
+ // Multiply elementwise the complex conjugate of x1 with x2.
// x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
// We assume x1 with a dinamic of 15 bit maximum
//
@@ -68,11 +71,12 @@ int mult_cpx_conj_vector(int16_t *x1,
#if defined(__x86_64__) || defined(__i386__)
simd_q15_t tmp_re,tmp_im;
simd_q15_t tmpy0,tmpy1;
+
#elif defined(__arm__)
int32x4_t tmp_re,tmp_im;
int32x4_t tmp_re1,tmp_im1;
- int16x4x2_t tmpy;
- int32x4_t shift = vdupq_n_s32(-output_shift);
+ int16x4x2_t tmpy;
+ int32x4_t shift = vdupq_n_s32(-output_shift);
#endif
x1_128 = (simd_q15_t *)&x1[0];
@@ -92,7 +96,7 @@ int mult_cpx_conj_vector(int16_t *x1,
tmp_im = _mm_srai_epi32(tmp_im,output_shift);
tmpy0 = _mm_unpacklo_epi32(tmp_re,tmp_im);
tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im);
- if (madd==0)
+ if (madd==0)
*y_128 = _mm_packs_epi32(tmpy0,tmpy1);
else
*y_128 += _mm_packs_epi32(tmpy0,tmpy1);
@@ -100,12 +104,12 @@ int mult_cpx_conj_vector(int16_t *x1,
#elif defined(__arm__)
tmp_re = vmull_s16(((simdshort_q15_t *)x1_128)[0], ((simdshort_q15_t*)x2_128)[0]);
- //tmp_re = [Re(x1[0])Re(x2[0]) Im(x1[0])Im(x2[0]) Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1])]
+ //tmp_re = [Re(x1[0])Re(x2[0]) Im(x1[0])Im(x2[0]) Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1])]
tmp_re1 = vmull_s16(((simdshort_q15_t *)x1_128)[1], ((simdshort_q15_t*)x2_128)[1]);
- //tmp_re1 = [Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1]) Re(x1[1])Re(x2[2]) Im(x1[1])Im(x2[2])]
+ //tmp_re1 = [Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1]) Re(x1[1])Re(x2[2]) Im(x1[1])Im(x2[2])]
tmp_re = vcombine_s32(vpadd_s32(vget_low_s32(tmp_re),vget_high_s32(tmp_re)),
vpadd_s32(vget_low_s32(tmp_re1),vget_high_s32(tmp_re1)));
- //tmp_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])]
+ //tmp_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])]
tmp_im = vmull_s16(vrev32_s16(vmul_s16(((simdshort_q15_t*)x2_128)[0],*(simdshort_q15_t*)conjug)), ((simdshort_q15_t*)x1_128)[0]);
//tmp_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])]
@@ -135,6 +139,68 @@ int mult_cpx_conj_vector(int16_t *x1,
return(0);
}
+int mult_cpx_vector(int16_t *x1, //Q15
+ int16_t *x2,//Q13
+ int16_t *y,
+ uint32_t N,
+ int output_shift)
+{
+ // Multiply elementwise x1 with x2.
+ // x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
+ // We assume x1 with a dinamic of 15 bit maximum
+ //
+ // x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
+ // We assume x2 with a dinamic of 14 bit maximum
+ ///
+ // y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
+ //
+ // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4;
+ //
+ // output_shift - shift to be applied to generate output
+ uint32_t i; // loop counter
+ simd_q15_t *x1_128;
+ simd_q15_t *x2_128;
+ simd_q15_t *y_128;
+ simd_q15_t tmp_re,tmp_im;
+ simd_q15_t tmpy0,tmpy1;
+ x1_128 = (simd_q15_t *)&x1[0];
+ x2_128 = (simd_q15_t *)&x2[0];
+ y_128 = (simd_q15_t *)&y[0];
+ //print_shorts("x1_128:",&x1_128[0]);
+ // print_shorts("x2_128:",&x2_128[0]);
+
+ //right shift by 13 while p_a * x0 and 15 while
+ // we compute 4 cpx multiply for each loop
+ for(i=0; i<(N>>2); i++) {
+ tmp_re = _mm_sign_epi16(*x1_128,*(__m128i*)&conjug2[0]);// Q15
+ //print_shorts("tmp_re1:",&tmp_re[i]);
+ tmp_re = _mm_madd_epi16(tmp_re,*x2_128); //Q28
+ //print_ints("tmp_re2:",&tmp_re[i]);
+ tmp_im = _mm_shufflelo_epi16(*x1_128,_MM_SHUFFLE(2,3,0,1)); //Q15
+ //print_shorts("tmp_im1:",&tmp_im[i]);
+ tmp_im = _mm_shufflehi_epi16(tmp_im,_MM_SHUFFLE(2,3,0,1)); //Q15
+ //print_shorts("tmp_im2:",&tmp_im[i]);
+ tmp_im = _mm_madd_epi16(tmp_im, *x2_128); //Q28
+ //print_ints("tmp_im3:",&tmp_im[i]);
+ tmp_re = _mm_srai_epi32(tmp_re,output_shift);//Q(28-shift)
+ //print_ints("tmp_re shifted:",&tmp_re[i]);
+ tmp_im = _mm_srai_epi32(tmp_im,output_shift); //Q(28-shift)
+ //print_ints("tmp_im shifted:",&tmp_im[i]);
+ tmpy0 = _mm_unpacklo_epi32(tmp_re,tmp_im); //Q(28-shift)
+ //print_ints("unpack lo :",&tmpy0[i]);
+ tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im); //Q(28-shift)
+ //print_ints("mrc rho0:",&tmpy1[i]);
+ *y_128 = _mm_packs_epi32(tmpy0,tmpy1); //must be Q15
+ //print_shorts("*y_128:",&y_128[i]);
+ x1_128++;
+ x2_128++;
+ y_128++;
+ }
+ _mm_empty();
+ _m_empty();
+ return(0);
+}
+
int multadd_cpx_vector(int16_t *x1,
int16_t *x2,
int16_t *y,
@@ -156,9 +222,7 @@ int multadd_cpx_vector(int16_t *x1,
// N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4;
//
// output_shift - shift to be applied to generate output
-
uint32_t i; // loop counter
-
simd_q15_t *x1_128;
simd_q15_t *x2_128;
simd_q15_t *y_128;
@@ -171,12 +235,9 @@ int multadd_cpx_vector(int16_t *x1,
int16x4x2_t tmpy;
int32x4_t shift = vdupq_n_s32(-output_shift);
#endif
-
x1_128 = (simd_q15_t *)&x1[0];
x2_128 = (simd_q15_t *)&x2[0];
y_128 = (simd_q15_t *)&y[0];
-
-
// we compute 4 cpx multiply for each loop
for(i=0; i<(N>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
@@ -191,25 +252,19 @@ int multadd_cpx_vector(int16_t *x1,
//print_ints("unpack lo:",&tmpy0[i]);
tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im);
//print_ints("unpack hi:",&tmpy1[i]);
-
if (zero_flag == 1)
*y_128 = _mm_packs_epi32(tmpy0,tmpy1);
else
*y_128 = _mm_adds_epi16(*y_128,_mm_packs_epi32(tmpy0,tmpy1));
//print_shorts("*y_128:",&y_128[i]);
-
#elif defined(__arm__)
-
msg("mult_cpx_vector not implemented for __arm__");
#endif
x1_128++;
x2_128++;
y_128++;
}
-
-
_mm_empty();
_m_empty();
-
return(0);
-}
+}
\ No newline at end of file
diff --git a/openair1/PHY/TOOLS/defs.h b/openair1/PHY/TOOLS/defs.h
index 8f0ae402bf..542b8edba5 100644
--- a/openair1/PHY/TOOLS/defs.h
+++ b/openair1/PHY/TOOLS/defs.h
@@ -145,6 +145,12 @@ int multadd_cpx_vector(int16_t *x1,
uint32_t N,
int output_shift);
+int mult_cpx_vector(int16_t *x1,
+ int16_t *x2,
+ int16_t *y,
+ uint32_t N,
+ int output_shift);
+
// lte_dfts.c
void init_fft(uint16_t size,
uint8_t logsize,
@@ -228,6 +234,11 @@ int32_t add_cpx_vector(int16_t *x,
int16_t *y,
uint32_t N);
+int32_t sub_cpx_vector16(int16_t *x,
+ int16_t *y,
+ int16_t *z,
+ uint32_t N);
+
int32_t add_cpx_vector32(int16_t *x,
int16_t *y,
int16_t *z,
diff --git a/openair1/PHY/TOOLS/file_output.c b/openair1/PHY/TOOLS/file_output.c
index 1eb9f25b5a..16b8b108d0 100644
--- a/openair1/PHY/TOOLS/file_output.c
+++ b/openair1/PHY/TOOLS/file_output.c
@@ -36,9 +36,9 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d
printf("Writing %d elements of type %d to %s\n",length,format,fname);
- if (format == 10 || format ==11 || format == 12 ) {
+ if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) {
fp = fopen(fname,"a+");
- } else if (format != 10 && format !=11 && format != 12 ) {
+ } else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) {
fp = fopen(fname,"w+");
}
@@ -49,7 +49,7 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d
return(-1);
}
- if (format != 10 && format !=11 && format != 12 )
+ if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14)
fprintf(fp,"%s = [",vname);
@@ -63,7 +63,9 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d
break;
case 1: // complex 16-bit
-
+ case 13:
+ case 14:
+ case 15:
for (i=0; iofdm_symbol_size); i++) {
- i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
- time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
+ i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
+ time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1]));
if (chest_t_abs[0][i] > ymax)
@@ -247,7 +247,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
if (chest_t[arx] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
-
+
if (chest_t_abs[arx][i] > ymax)
ymax = chest_t_abs[arx][i];
}
@@ -340,7 +340,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1];
A_pucch[ind] = 10*log10(pucch1_comp[ind]);
B_pucch[ind] = ind;
- C_pucch[ind] = (float)pucch1_thres[ind];
+ C_pucch[ind] = (float)pucch1_thres[ind];
}
fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
@@ -768,4 +768,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
}
free(chest_t_abs);
-}
+}
\ No newline at end of file
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.h b/openair1/PHY/TOOLS/lte_phy_scope.h
index a5bcfa1ce6..2e8ca96c3a 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.h
+++ b/openair1/PHY/TOOLS/lte_phy_scope.h
@@ -46,18 +46,21 @@ typedef struct {
} FD_lte_phy_scope_enb;
typedef struct {
- FL_FORM * lte_phy_scope_ue;
- FL_OBJECT * rxsig_t;
- FL_OBJECT * chest_f;
- FL_OBJECT * chest_t;
- FL_OBJECT * pbch_comp;
- FL_OBJECT * pbch_llr;
- FL_OBJECT * pdcch_comp;
- FL_OBJECT * pdcch_llr;
- FL_OBJECT * pdsch_comp;
- FL_OBJECT * pdsch_llr;
- FL_OBJECT * pdsch_tput;
- FL_OBJECT * button_0;
+ FL_FORM * lte_phy_scope_ue;
+ FL_OBJECT * rxsig_t;
+ FL_OBJECT * chest_f;
+ FL_OBJECT * chest_t;
+ FL_OBJECT * pbch_comp;
+ FL_OBJECT * pbch_llr;
+ FL_OBJECT * pdcch_comp;
+ FL_OBJECT * pdcch_llr;
+ FL_OBJECT * pdsch_comp;
+ FL_OBJECT * pdsch_llr;
+ FL_OBJECT * pdsch_comp1;
+ FL_OBJECT * pdsch_llr1;
+ FL_OBJECT * pdsch_tput;
+ FL_OBJECT * button_0;
+
} FD_lte_phy_scope_ue;
FD_lte_phy_scope_enb * create_lte_phy_scope_enb( void );
@@ -76,7 +79,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
-
-
-
#endif /* FD_lte_scope_h_ */
diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
new file mode 100755
index 0000000000..60c5ace2c5
--- /dev/null
+++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
@@ -0,0 +1,800 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/* Form definition file generated by fdesign */
+#include
+#include "lte_phy_scope.h"
+#define TPUT_WINDOW_LENGTH 100
+int otg_enabled;
+FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
+float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
+float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
+float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
+float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
+float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
+static void ia_receiver_on_off( FL_OBJECT *button, long arg)
+{
+ if (fl_get_button(button)) {
+ fl_set_object_label(button, "IA Receiver ON");
+ // PHY_vars_UE_g[0][0]->use_ia_receiver = 1;
+ fl_set_object_color(button, FL_GREEN, FL_GREEN);
+ } else {
+ fl_set_object_label(button, "IA Receiver OFF");
+ // PHY_vars_UE_g[0][0]->use_ia_receiver = 0;
+ fl_set_object_color(button, FL_RED, FL_RED);
+ }
+}
+static void dl_traffic_on_off( FL_OBJECT *button, long arg)
+{
+ if (fl_get_button(button)) {
+ fl_set_object_label(button, "DL Traffic ON");
+ otg_enabled = 1;
+ fl_set_object_color(button, FL_GREEN, FL_GREEN);
+ } else {
+ fl_set_object_label(button, "DL Traffic OFF");
+ otg_enabled = 0;
+ fl_set_object_color(button, FL_RED, FL_RED);
+ }
+}
+FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
+{
+ FL_OBJECT *obj;
+ FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui );
+ // Define form
+ fdui->lte_phy_scope_enb = fl_bgn_form( FL_NO_BOX, 800, 800 );
+ // This the whole UI box
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
+ fl_set_object_color( obj, FL_BLACK, FL_BLACK );
+ // Received signal
+ fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
+ fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
+ fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
+ // Time-domain channel response
+ fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
+ fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
+ // Frequency-domain channel response
+ fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
+ fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
+ fl_set_xyplot_ybounds( fdui->chest_f,30,70);
+ // LLR of PUSCH
+ fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pusch_llr,2);
+ // I/Q PUSCH comp
+ fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pusch_comp, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pusch_comp,2);
+ fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
+ // I/Q PUCCH comp (format 1)
+ fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" );
+ fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pucch_comp1, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pucch_comp1,2);
+ // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
+ // I/Q PUCCH comp (fromat 1a/b)
+ fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pucch_comp, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pucch_comp,2);
+ // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
+ // Throughput on PUSCH
+ fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" );
+ fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE );
+ fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color
+ // Generic eNB Button
+ fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
+ fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
+ fl_set_button(fdui->button_0,0);
+ otg_enabled = 0;
+ fl_set_object_label(fdui->button_0, "DL Traffic OFF");
+ fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
+ fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
+ fl_end_form( );
+ fdui->lte_phy_scope_enb->fdui = fdui;
+ return fdui;
+}
+void phy_scope_eNB(FD_lte_phy_scope_enb *form,
+ PHY_VARS_eNB *phy_vars_enb,
+ int UE_id)
+{
+ int eNB_id = 0;
+ int i,i2,arx,atx,ind,k;
+ LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_enb->frame_parms;
+ int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE
+ int16_t **rxsig_t;
+ int16_t **chest_t;
+ int16_t **chest_f;
+ int16_t *pusch_llr;
+ int16_t *pusch_comp;
+ int32_t *pucch1_comp;
+ int32_t *pucch1_thres;
+ int32_t *pucch1ab_comp;
+ float Re,Im,ymax;
+ float *llr, *bit;
+ float I[nsymb_ce*2], Q[nsymb_ce*2];
+ float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240];
+ float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES];
+ float chest_t_abs[nb_antennas_rx][frame_parms->ofdm_symbol_size];
+ float *chest_f_abs;
+ float time[FRAME_LENGTH_COMPLEX_SAMPLES];
+ float time2[2048];
+ float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
+ int frame = phy_vars_enb->proc.proc_rxtx[0].frame_tx;
+ uint32_t total_dlsch_bitrate = phy_vars_enb->total_dlsch_bitrate;
+ int coded_bits_per_codeword = 0;
+ uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
+ int mcs = 0;
+ // choose max MCS to compute coded_bits_per_codeword
+ if (phy_vars_enb->ulsch[UE_id]!=NULL) {
+ for (harq_pid=0; harq_pid<3; harq_pid++) {
+ mcs = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->mcs,mcs);
+ }
+ }
+ coded_bits_per_codeword = frame_parms->N_RB_UL*12*get_Qm(mcs)*frame_parms->symbols_per_tti;
+ chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
+ llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
+ bit = malloc(coded_bits_per_codeword*sizeof(float));
+ rxsig_t = (int16_t**) phy_vars_enb->common_vars.rxdata[eNB_id];
+ chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[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];
+ 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];
+ // Received signal in time domain of receive antenna 0
+ if (rxsig_t != NULL) {
+ if (rxsig_t[0] != NULL) {
+ for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
+ }
+ for (arx=1; arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
+ }
+ }
+ }
+ // Channel Impulse Response
+ if (chest_t != NULL) {
+ ymax = 0;
+ if (chest_t[0] !=NULL) {
+ for (i=0; i<(frame_parms->ofdm_symbol_size); i++) {
+ i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
+ time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
+ chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1]));
+ if (chest_t_abs[0][i] > ymax)
+ ymax = chest_t_abs[0][i];
+ }
+ fl_set_xyplot_data(form->chest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","","");
+ }
+ for (arx=1; arxofdm_symbol_size>>3); i++) {
+ chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
+ if (chest_t_abs[arx][i] > ymax)
+ ymax = chest_t_abs[arx][i];
+ }
+ fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
+ fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
+ }
+ }
+ // Avoid flickering effect
+ // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
+ fl_set_xyplot_ybounds(form->chest_t,0,ymax);
+ }
+ // Channel Frequency Response
+ if (chest_f != NULL) {
+ ind = 0;
+ for (atx=0; atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3);
+ fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+ for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
+ // other tx antennas
+ if (nb_antennas_tx > 1) {
+ if (nb_antennas_rx > 1) {
+ for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
+ }
+ } else { // 1 rx antenna
+ atx=1;
+ arx=0;
+ fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
+ }
+ }
+ // PUSCH LLRs
+ if (pusch_llr != NULL) {
+ for (i=0; ipusch_llr,bit,llr,coded_bits_per_codeword,"","","");
+ }
+ // PUSCH I/Q of MF Output
+ if (pusch_comp!=NULL) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_UL; i++) {
+ I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
+ Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1];
+ ind++;
+ }
+ }
+ fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
+ }
+ // PUSCH I/Q of MF Output
+ if (pucch1ab_comp!=NULL) {
+ for (ind=0; ind<10240; ind++) {
+ I_pucch[ind] = (float)pucch1ab_comp[2*(ind)];
+ Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1];
+ A_pucch[ind] = 10*log10(pucch1_comp[ind]);
+ B_pucch[ind] = ind;
+ C_pucch[ind] = (float)pucch1_thres[ind];
+ }
+ fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
+ fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
+ fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED);
+ fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000);
+ fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000);
+ fl_set_xyplot_ybounds(form->pucch_comp1,0,80);
+ }
+ // PUSCH Throughput
+ memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
+ memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
+ tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame;
+ tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
+ fl_set_xyplot_data(form->pusch_tput,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","","");
+ // fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax);
+ // fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
+ fl_check_forms();
+ free(llr);
+ free(bit);
+ free(chest_f_abs);
+}
+FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) {
+ FL_OBJECT *obj;
+ FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui );
+ // Define form
+ fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 );
+ // This the whole UI box
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" );
+ fl_set_object_color( obj, FL_BLACK, FL_BLACK );
+ // Received signal
+ fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
+ fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
+ fl_set_xyplot_ybounds(fdui->rxsig_t,30,70);
+ // Time-domain channel response
+ fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
+ fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
+ // Frequency-domain channel response
+ fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
+ fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
+ fl_set_xyplot_ybounds( fdui->chest_f,30,70);
+ /*
+ // LLR of PBCH
+ fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
+ fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
+ fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
+ fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
+ // I/Q PBCH comp
+ fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
+ fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
+ fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
+ fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
+ // LLR of PDCCH
+ fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
+ fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
+ // I/Q PDCCH comp
+ fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
+ fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
+ fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
+ */
+ int offset=240;
+ // LLR of PDSCH
+ fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
+ fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
+ // I/Q PDSCH comp
+ fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
+ // LLR of PDSCH
+ fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2);
+ fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR);
+ // I/Q PDSCH comp
+ fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2);
+ /*
+ // Throughput on PDSCH
+ fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
+ fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
+ fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
+ // Generic UE Button
+ fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
+ fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
+ //openair_daq_vars.use_ia_receiver = 0;
+ fl_set_button(fdui->button_0,0);
+ fl_set_object_label(fdui->button_0, "IA Receiver OFF");
+ fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
+ fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
+ fl_hide_object(fdui->button_0);
+ */
+ fl_end_form( );
+ fdui->lte_phy_scope_ue->fdui = fdui;
+ return fdui;
+}
+void phy_scope_UE(FD_lte_phy_scope_ue *form,
+ PHY_VARS_UE *phy_vars_ue,
+ int eNB_id,
+ int UE_id,
+ uint8_t subframe){
+ int i,arx,atx,ind,k;
+ LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB;
+ int16_t **rxsig_t;
+ int16_t **chest_t;
+ int16_t **chest_f;
+ int16_t *pdsch_llr,*pdsch_llr1;
+ int16_t *pdsch_comp,*pdsch_comp1;
+ int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1;
+ int8_t *pdcch_llr;
+ int16_t *pdcch_comp;
+ int8_t *pbch_llr;
+ int16_t *pbch_comp;
+ float Re,Im,ymax=1;
+ int num_pdcch_symbols=3;
+ float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch;
+ float *I, *Q;
+ float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES];
+ float **chest_t_abs;
+ float time[FRAME_LENGTH_COMPLEX_SAMPLES];
+ float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
+ int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
+ uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id];
+ int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1;
+ int mod0,mod1;
+ int mcs0 = 0;
+ int mcs1=0;
+ unsigned char harq_pid = 0;
+ int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
+ if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) {
+ harq_pid = phy_vars_ue->dlsch[eNB_id][0]->current_harq_pid;
+ if (harq_pid>=8)
+ return;
+ mcs0 = phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->mcs;
+ // Button 0
+ /*
+ if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
+ // we are in TM5
+ fl_show_object(form->button_0);
+ }
+ */
+ }
+ if (phy_vars_ue->dlsch[eNB_id][1]!=NULL) {
+ harq_pid = phy_vars_ue->dlsch[eNB_id][1]->current_harq_pid;
+ if (harq_pid>=8)
+ return;
+ mcs1 = phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->mcs;
+ }
+ if (phy_vars_ue->pdcch_vars[eNB_id]!=NULL) {
+ num_pdcch_symbols = phy_vars_ue->pdcch_vars[eNB_id]->num_pdcch_symbols;
+ }
+ // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+ if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) {
+ mod0 = get_Qm(mcs0);
+ coded_bits_per_codeword0 = get_G(frame_parms,
+ phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+ phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+ get_Qm(mcs0),
+ phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl,
+ num_pdcch_symbols,
+ frame,
+ subframe,
+ beamforming_mode);
+ } else {
+ coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+ mod0=0;
+ }
+ if (phy_vars_ue->dlsch[eNB_id][1]!=NULL) {
+ mod1 = get_Qm(mcs1);
+ coded_bits_per_codeword1 = get_G(frame_parms,
+ phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->nb_rb,
+ phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
+ get_Qm(mcs1),
+ phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->Nl,
+ num_pdcch_symbols,
+ frame,
+ subframe,
+ beamforming_mode);
+ } else {
+ coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+ mod1=0;
+ }
+ I = (float*) calloc(nsymb_ce*2,sizeof(float));
+ Q = (float*) calloc(nsymb_ce*2,sizeof(float));
+ chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
+ for (arx=0;arxofdm_symbol_size,sizeof(float));
+ }
+ chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
+ llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // init to zero
+ bit0 = malloc(coded_bits_per_codeword0*sizeof(float));
+ llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // init to zero
+ bit1 = malloc(coded_bits_per_codeword1*sizeof(float));
+ llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
+ bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
+ rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
+ chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_id];
+ chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id];
+ pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
+ pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
+ pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[eNB_id]->llr;
+ pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[eNB_id]->rxdataF_comp[0];
+ pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 0
+ pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[1]; // stream 1
+ pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0];
+ //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[0];
+ //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[1];
+ pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0])[0];
+ //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0];
+ pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag0[0];
+ pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[0][0])[0];
+ pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb0[0];
+ pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[0][0])[0];
+ fl_freeze_form(form->lte_phy_scope_ue);
+ // Received signal in time domain of receive antenna 0
+ if (rxsig_t != NULL) {
+ if (rxsig_t[0] != NULL) {
+ for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
+ }
+ for (arx=1;arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
+ }
+ }
+ }
+ // Channel Impulse Response (still repeated format)
+ if (chest_t != NULL) {
+ ymax = 0;
+ if (chest_t[0] !=NULL) {
+ for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
+ chest_t_abs[0][i] = (float) (chest_t[0][4*i]*chest_t[0][4*i]+chest_t[0][4*i+1]*chest_t[0][4*i+1]);
+ if (chest_t_abs[0][i] > ymax)
+ ymax = chest_t_abs[0][i];
+ }
+ fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
+ }
+ for (arx=1; arxofdm_symbol_size>>3); i++) {
+ chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]);
+ if (chest_t_abs[arx][i] > ymax)
+ ymax = chest_t_abs[arx][i];
+ }
+ fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
+ fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
+ }
+ }
+ // Avoid flickering effect
+ // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
+ fl_set_xyplot_ybounds(form->chest_t,0,ymax);
+ }
+ // Channel Frequency Response (includes 5 complex sample for filter)
+ if (chest_f != NULL) {
+ ind = 0;
+ for (atx=0;atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
+ // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
+ fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+ for (arx=1;arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
+ // other tx antennas
+ if (nb_antennas_tx > 1) {
+ if (nb_antennas_rx > 1) {
+ for (atx=1;atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
+ }
+ } else { // 1 rx antenna
+ atx=1; arx=0;
+ fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
+ }
+ }
+ /*
+ // PBCH LLRs
+ if (pbch_llr != NULL) {
+ for (i=0; i<1920;i++) {
+ llr_pbch[i] = (float) pbch_llr[i];
+ bit_pbch[i] = (float) i;
+ }
+ fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","","");
+ }
+ // PBCH I/Q of MF Output
+ if (pbch_comp!=NULL) {
+ for (i=0; i<72*2; i++) {
+ I[i] = pbch_comp[2*i];
+ Q[i] = pbch_comp[2*i+1];
+ }
+ fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","","");
+ }
+ // PDCCH LLRs
+ if (pdcch_llr != NULL) {
+ for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) {
+ llr_pdcch[i] = (float) pdcch_llr[i];
+ bit_pdcch[i] = (float) i;
+ }
+ fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3);
+ fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","","");
+ }
+ // PDCCH I/Q of MF Output
+ if (pdcch_comp!=NULL) {
+ for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) {
+ I[i] = pdcch_comp[2*i];
+ Q[i] = pdcch_comp[2*i+1];
+ }
+ fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
+ }
+ */
+ // PDSCH LLRs CW0
+ if (pdsch_llr != NULL) {
+ for (i=0; ipdsch_llr,0,coded_bits_per_codeword0);
+ fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","","");
+ }
+ // PDSCH I/Q of MF Output
+ if (pdsch_comp!=NULL) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i];
+ Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
+ ind++;
+ }
+ }
+ fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","","");
+ }
+ if (pdsch_mag0 != NULL) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ Q[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ ind++;
+ }
+ }
+ fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN);
+ }
+ if (pdsch_magb0 != NULL) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ Q[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ ind++;
+ }
+ }
+ fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED);
+ }
+ if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] =
+ (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+
+ pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])*
+ cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ Q[ind] =
+ (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
+ pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
+ sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ ind++;
+ }
+ }
+ fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE);
+ }
+ // PDSCH LLRs CW1
+ if (pdsch_llr1 != NULL) {
+ for (i=0; ipdsch_llr1,0,coded_bits_per_codeword1);
+ fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","","");
+ }
+ // PDSCH I/Q of MF Output
+ if (pdsch_comp1!=NULL) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i];
+ Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
+ ind++;
+ }
+ }
+ fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","","");
+ }
+ if (pdsch_mag1 != NULL) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ Q[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ ind++;
+ }
+ }
+ fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN);
+ }
+ if (pdsch_magb1 != NULL) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ Q[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ ind++;
+ }
+ }
+ fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED);
+ }
+ if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) {
+ ind=0;
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] =
+ (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+
+ pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])*
+ cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ Q[ind] =
+ (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
+ pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
+ sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ ind++;
+ }
+ }
+ fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE);
+ }
+ /*
+ // PDSCH Throughput
+ memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
+ memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
+ tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame;
+ tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
+ if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) {
+ tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
+ }
+ fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
+ fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
+ */
+ fl_unfreeze_form(form->lte_phy_scope_ue);
+ fl_check_forms();
+ free(I);
+ free(Q);
+ free(chest_f_abs);
+ free(llr0);
+ free(bit0);
+ free(llr1);
+ free(bit1);
+ free(bit_pdcch);
+ free(llr_pdcch);
+ for (arx=0;arxmeas_flag==0) {
ts->trials++;
ts->in = rdtsc_oai();
+ ts->meas_flag=1;
+ }
+ else {
+ ts->in = rdtsc_oai();
+ }
}
}
@@ -120,7 +126,8 @@ static inline void stop_meas(time_stats_t *ts)
if ((out-ts->in) > ts->max)
ts->max = out-ts->in;
-
+
+ ts->meas_flag=0;
}
}
@@ -132,6 +139,7 @@ static inline void reset_meas(time_stats_t *ts) {
ts->p_time=0;
ts->diff_square=0;
ts->max=0;
+ ts->meas_flag=0;
}
diff --git a/openair1/PHY/TOOLS/twiddle18432.h b/openair1/PHY/TOOLS/twiddle18432.h
index f21987c4cb..8c6c9822dc 100644
--- a/openair1/PHY/TOOLS/twiddle18432.h
+++ b/openair1/PHY/TOOLS/twiddle18432.h
@@ -1,31 +1,23 @@
-/*******************************************************************************
- OpenAirInterface
- Copyright(c) 1999 - 2014 Eurecom
-
- OpenAirInterface is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
-
- OpenAirInterface is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with OpenAirInterface.The full GNU General Public License is
- included in this distribution in the file called "COPYING". If not,
- see .
-
- Contact Information
- OpenAirInterface Admin: openair_admin@eurecom.fr
- OpenAirInterface Tech : openair_tech@eurecom.fr
- OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
-
- Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
-
- *******************************************************************************/
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
/* Twiddles generated with
twa = floor(32767*exp(-sqrt(-1)*2*pi*(0:6143)/18432));
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index d21312fe34..d70bfb3f72 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -32,6 +32,7 @@
#ifndef __PHY_DEFS__H__
#define __PHY_DEFS__H__
+#define _GNU_SOURCE
#include
#include
#include
@@ -153,10 +154,10 @@ enum transmission_access_mode {
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_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)
+ NGFI_RRU_IF4p5 // NGFI_RRU (NGFI remote radio-unit,IF4p5)
} eNB_func_t;
typedef enum {
@@ -391,6 +392,9 @@ typedef struct {
pthread_mutex_t mutex_rxtx;
/// scheduling parameters for RXn-TXnp4 thread
struct sched_param sched_param_rxtx;
+ int sub_frame_start;
+ int sub_frame_step;
+ unsigned long long gotIQs;
} UE_rxtx_proc_t;
/// Context data structure for eNB subframe processing
@@ -430,6 +434,7 @@ typedef struct PHY_VARS_eNB_s {
eNB_proc_t proc;
eNB_func_t node_function;
eNB_timing_t node_timing;
+ eth_params_t *eth_params;
int single_thread_flag;
openair0_rf_map rf_map;
int abstraction_flag;
@@ -591,7 +596,7 @@ typedef struct PHY_VARS_eNB_s {
uint32_t total_transmitted_bits;
uint32_t total_system_throughput;
- int hw_timing_advance;
+ int hw_timing_advance;
time_stats_t phy_proc;
time_stats_t phy_proc_tx;
@@ -628,7 +633,7 @@ typedef struct PHY_VARS_eNB_s {
#ifdef LOCALIZATION
/// time state for localization
time_stats_t localization_stats;
-#endif
+#endif
int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX][10];
int32_t pucch1_stats[NUMBER_OF_UE_MAX][10*1024];
@@ -640,9 +645,9 @@ typedef struct PHY_VARS_eNB_s {
int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240];
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240];
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
-
+
/// RF and Interface devices per CC
- openair0_device rfdevice;
+ openair0_device rfdevice;
openair0_device ifdevice;
/// Pointer for ifdevice buffer struct
if_buffer_t ifbuffer;
@@ -905,7 +910,18 @@ typedef struct {
time_stats_t tx_prach;
/// RF and Interface devices per CC
- openair0_device rfdevice;
+ 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;
@@ -918,7 +934,7 @@ static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,
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
@@ -940,7 +956,7 @@ static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *
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
@@ -962,9 +978,9 @@ static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *
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");
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
old mode 100644
new mode 100755
index f6daccfbe0..e9604a36f6
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -666,8 +666,8 @@ typedef struct {
/// - third index: tx antenna [0..nb_antennas_tx[
/// - fourth index: sample [0..]
int32_t **beam_weights[3][15];
- /// \brief Holds the tdd reciprocity calibration coefficients
- /// - first index: eNB id [0..2] (hard coded)
+ /// \brief Holds the tdd reciprocity calibration coefficients
+ /// - first index: eNB id [0..2] (hard coded)
/// - second index: tx antenna [0..nb_antennas_tx[
/// - third index: frequency [0..]
int32_t **tdd_calib_coeffs[3];
@@ -845,15 +845,22 @@ typedef struct {
/// - 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.
- /// - first index: ? [0..7] (hard coded) accessed via \c round
- /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
- /// - third index: ? [0..168*N_RB_DL[
- int32_t **rxdataF_comp1[8];
+ /// \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)[
@@ -865,10 +872,6 @@ typedef struct {
/// \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_rho_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[
@@ -880,7 +883,7 @@ typedef struct {
/// \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;
+ 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[
@@ -888,7 +891,7 @@ typedef struct {
/// \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;
+ 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..]
@@ -901,6 +904,10 @@ typedef struct {
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;
diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index dd09749fbf..be63ea00cc 100644
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -202,7 +202,7 @@
#define ONE_OVER_SQRT2_Q15 23170
-
+#define ONE_OVER_2_Q15 16384
// QAM amplitude definitions
@@ -284,21 +284,7 @@ typedef enum {
#define NUMBER_OF_HARQ_PID_MAX 8
#define MAX_FRAME_NUMBER 0x400
-#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP)
-#define NUMBER_OF_eNB_MAX 1
-#define NUMBER_OF_UE_MAX 16
-#define NUMBER_OF_CONNECTED_eNB_MAX 3
-#else
-#ifdef LARGE_SCALE
-#define NUMBER_OF_eNB_MAX 2
-#define NUMBER_OF_UE_MAX 120
-#define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory
-#else
-#define NUMBER_OF_eNB_MAX 7
-#define NUMBER_OF_UE_MAX 16
-#define NUMBER_OF_CONNECTED_eNB_MAX 3
-#endif
-#endif
+#include "openairinterface5g_limits.h"
#define NUMBER_OF_RN_MAX 3
typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t;
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 5fd5009f1f..ac2d7957f2 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -197,7 +197,7 @@ void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB,relaying_type_t r_type);
*/
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
+/*! \brief Scheduling for eNB PRACH RX procedures
@param phy_vars_eNB Pointer to eNB variables on which to act
@param proc Pointer to RXn-TXnp4 proc information
*/
@@ -305,7 +305,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n);
@param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH
@returns status indicator for PUCCH/PUSCH transmission
*/
-uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK);
+uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK, uint8_t cw_idx);
/*! \brief Reset ACK/NACK information
@param frame_parms Pointer to DL frame parameter descriptor
@@ -317,7 +317,8 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t
uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
harq_status_t *harq_ack,
unsigned char subframe,
- unsigned char *o_ACK);
+ unsigned char *o_ACK,
+ uint8_t cw_idx);
/*! \brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH. Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6)
@param frame_parms Pointer to DL frame parameter descriptor
@@ -509,7 +510,9 @@ int get_ue_active_harq_pid(uint8_t Mod_id,uint8_t CC_id,uint16_t rnti,int frame,
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, uint16_t coded_bits_per_codeword,int round);
+
+void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid);
+
/*@}*/
diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c
index cb22461656..9a41ae09c5 100644
--- a/openair1/SCHED/phy_mac_stub.c
+++ b/openair1/SCHED/phy_mac_stub.c
@@ -455,6 +455,151 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
break;
}
+
+
+
+
+ DCI_pdu->dci_alloc[1].L = 2;
+ DCI_pdu->dci_alloc[1].rnti = 0x1235;
+ DCI_pdu->dci_alloc[1].format = format0;
+ DCI_pdu->dci_alloc[1].ra_flag = 0;
+
+ if (eNB->frame_parms.frame_type == FDD) {
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(6,1,4);
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ /* case 15:
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
+ ((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;*/
+ case 25:
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,1,20);
+ printf("rballoc %d\n",((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc);
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ case 50:
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(50,1,48);
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ /* case 75:
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;*/
+ case 100:
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(100,1,96);
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ }
+ }
+ else {
+ switch (eNB->frame_parms.N_RB_DL==6) {
+ case 6:
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(6,1,5);
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
+ ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ /* case 15:
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
+ ((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;*/
+ case 25:
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,20);
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
+ ((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ case 50:
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(50,1,48);
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
+ ((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ /* case 75:
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
+ ((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;*/
+ case 100:
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(100,1,96);
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
+ ((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
+ break;
+ }
+ }
} else if (transmission_mode==4) {
DCI_pdu->Num_ue_spec_dci = 1;
// user 1
@@ -543,32 +688,8 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&RA_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
break;
*/
- /*
- case 9:
- DCI_pdu->Num_ue_spec_dci = 1;
+
- //user 1
- if (eNB->frame_parms.frame_type == FDD)
- DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_FDD_t ;
- else
- DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
-
- DCI_pdu->dci_alloc[0].L = 2;
- DCI_pdu->dci_alloc[0].rnti = 0x1235;
- DCI_pdu->dci_alloc[0].format = format0;
- DCI_pdu->dci_alloc[0].ra_flag = 0;
-
- UL_alloc_pdu.type = 0;
- UL_alloc_pdu.hopping = 0;
- UL_alloc_pdu.rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
- UL_alloc_pdu.mcs = eNB->target_ue_ul_mcs;
- UL_alloc_pdu.ndi = proc->frame_tx&1;
- UL_alloc_pdu.TPC = 0;
- UL_alloc_pdu.cshift = 0;
- UL_alloc_pdu.dai = 0;
- UL_alloc_pdu.cqi_req = 1;
- memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
- */
// user 2
/*
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
@@ -593,11 +714,8 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
UL_alloc_pdu.dai = 0;
UL_alloc_pdu.cqi_req = 1;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
- break;
+
*/
-
- /*default:
- break;*/
}
/*
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 93d3c94b11..ae61f7be0d 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -325,6 +325,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
harq_status_t *harq_ack,
unsigned char subframe,
unsigned char *o_ACK,
+ uint8_t cw_idx,
uint8_t do_reset) // 1 to reset ACK/NACK status : 0 otherwise
{
uint8_t status=0;
@@ -337,7 +338,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
else
subframe_dl0 = subframe - 4;
- o_ACK[0] = harq_ack[subframe_dl0].ack;
+ o_ACK[cw_idx] = harq_ack[subframe_dl0].ack;
status = harq_ack[subframe_dl0].send_harq_status;
if(do_reset)
@@ -484,17 +485,19 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,
harq_status_t *harq_ack,
unsigned char subframe,
- unsigned char *o_ACK)
+ unsigned char *o_ACK,
+ uint8_t cw_idx)
{
- return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 0);
+ return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 0);
}
uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
harq_status_t *harq_ack,
unsigned char subframe,
- unsigned char *o_ACK)
+ unsigned char *o_ACK,
+ uint8_t cw_idx)
{
- return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 1);
+ return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 1);
}
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index cad508c7c2..e9f1125a34 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -78,7 +78,8 @@
void exit_fun(const char* s);
extern int exit_openair;
-
+struct timespec start_fh, start_fh_prev;
+int start_fh_sf, start_fh_prev_sf;
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
@@ -92,6 +93,9 @@ extern uint16_t hundred_times_log10_NPRB[100];
unsigned int max_peak_val;
int max_sync_pos;
+int harq_pid_updated[NUMBER_OF_UE_MAX][8] = {{0}};
+int harq_pid_round[NUMBER_OF_UE_MAX][8] = {{0}};
+
//DCI_ALLOC_t dci_alloc[8];
#ifdef EMOS
@@ -686,7 +690,7 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
dci_alloc->format,
&eNB->dlsch_SI,
fp,
- eNB->pdsch_config_dedicated,
+ NULL,
SI_RNTI,
0,
P_RNTI,
@@ -720,7 +724,7 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
dci_alloc->format,
&eNB->dlsch_ra,
fp,
- eNB->pdsch_config_dedicated,
+ NULL,
SI_RNTI,
dci_alloc->rnti,
P_RNTI,
@@ -770,7 +774,7 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
dci_alloc->format,
eNB->dlsch[(uint8_t)UE_id],
fp,
- eNB->pdsch_config_dedicated,
+ &eNB->pdsch_config_dedicated[UE_id],
SI_RNTI,
0,
P_RNTI,
@@ -1444,15 +1448,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
eNB->dlsch_ra->active = 0;
}
-#if defined(FLEXRAN_AGENT_SB_IF)
-#ifndef DISABLE_SF_TRIGGER
- //Send subframe trigger to the controller
- if (mac_agent_registered[eNB->Mod_id]) {
- agent_mac_xface[eNB->Mod_id]->flexran_agent_send_sf_trigger(eNB->Mod_id);
- }
-#endif
-#endif
-
// Now scan UE specific DLSCH
for (UE_id=0; UE_id=10 && subframe>=9) {
+ write_output("/tmp/txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1);
+ write_output("/tmp/txsigF1.m","txsF1", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1);
+ abort();
+ }
+ */
#ifdef EMOS
phy_procedures_emos_eNB_TX(subframe, eNB);
@@ -1553,7 +1554,6 @@ void process_HARQ_feedback(uint8_t UE_id,
int subframe = proc->subframe_rx;
int harq_pid = subframe2harq_pid( fp,frame,subframe);
-
if (fp->frame_type == FDD) { //FDD
subframe_m4 = (subframe<4) ? subframe+6 : subframe-4;
@@ -1681,6 +1681,7 @@ void process_HARQ_feedback(uint8_t UE_id,
mp = m;
dl_harq_pid[m] = dlsch->harq_ids[dl_subframe];
+ harq_pid_updated[UE_id][dl_harq_pid[m]] = 1;
if ((pucch_sel != 2)&&(pusch_flag == 0)) { // multiplexing
if ((SR_payload == 1)&&(all_ACKed == 1))
@@ -1768,7 +1769,7 @@ void process_HARQ_feedback(uint8_t UE_id,
eNB->dlsch[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
*/
}
-
+
// Do fine-grain rate-adaptation for DLSCH
if (ue_stats->dlsch_NAK_round0 > dlsch->error_threshold) {
if (ue_stats->dlsch_mcs_offset == 1)
@@ -1781,7 +1782,7 @@ void process_HARQ_feedback(uint8_t UE_id,
LOG_D(PHY,"[process_HARQ_feedback] Frame %d Setting round to %d for pid %d (subframe %d)\n",frame,
dlsch_harq_proc->round,dl_harq_pid[m],subframe);
#endif
-
+ harq_pid_round[UE_id][dl_harq_pid[m]] = dlsch_harq_proc->round;
// Clear NAK stats and adjust mcs offset
// after measurement window timer expires
if (ue_stats->dlsch_sliding_cnt == dlsch->ra_window_size) {
@@ -1800,8 +1801,6 @@ void process_HARQ_feedback(uint8_t UE_id,
ue_stats->dlsch_NAK_round0 = 0;
ue_stats->dlsch_sliding_cnt = 0;
}
-
-
}
}
}
@@ -2605,6 +2604,7 @@ extern int oai_exit;
static void *fep_thread(void *param) {
+ pthread_setname_np( pthread_self(), "UEfep");
PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param;
eNB_proc_t *proc = &eNB->proc;
while (!oai_exit) {
@@ -2750,7 +2750,12 @@ void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) {
if (eNB->node_function == NGFI_RRU_IF4p5) {
/// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
+ LOG_D(PHY,"send_IF4p5 (PULFFT): frame %d, subframe %d\n",proc_rxtx->frame_rx,proc_rxtx->subframe_rx);
send_IF4p5(eNB, proc_rxtx->frame_rx, proc_rxtx->subframe_rx, IF4p5_PULFFT, 0);
+ start_fh_prev = start_fh;
+ start_fh_prev_sf = start_fh_sf;
+ clock_gettime( CLOCK_MONOTONIC, &start_fh);
+ start_fh_sf = proc_rxtx->subframe_rx;
}
}
@@ -2762,6 +2767,10 @@ void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) {
/// **** send_IF5 of rxdata to BBU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
send_IF5(eNB, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL);
+ start_fh_prev = start_fh;
+ start_fh_prev_sf = start_fh_sf;
+ clock_gettime( CLOCK_MONOTONIC, &start_fh);
+ start_fh_sf = proc->subframe_rx;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
}
@@ -3070,12 +3079,15 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,eNB->ulsch[i]->harq_processes[harq_pid]->round);
if (eNB->ulsch[i]->Msg3_flag == 1) {
+
LOG_D(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d/%d\n",
eNB->Mod_id,
eNB->CC_id,
frame,subframe, i,
eNB->ulsch[i]->harq_processes[harq_pid]->round-1,
fp->maxHARQ_Msg3Tx-1);
+ /*dump_ulsch(eNB,proc,i);
+ exit(-1);*/
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
eNB->Mod_id,harq_pid,
@@ -3158,6 +3170,10 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
eNB->UE_stats[i].ulsch_errors[harq_pid]++;
eNB->UE_stats[i].ulsch_consecutive_errors++;
+ /*if (eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb > 20) {
+ dump_ulsch(eNB,proc,i);
+ exit(-1);
+ }*/
// indicate error to MAC
if (eNB->mac_enabled == 1)
mac_xface->rx_sdu(eNB->Mod_id,
@@ -3422,14 +3438,21 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
}
#endif
-
-
//}
#ifdef EMOS
phy_procedures_emos_eNB_RX(subframe,eNB);
#endif
+#if defined(FLEXRAN_AGENT_SB_IF)
+#ifndef DISABLE_SF_TRIGGER
+ //Send subframe trigger to the controller
+ if (mac_agent_registered[eNB->Mod_id]) {
+ agent_mac_xface[eNB->Mod_id]->flexran_agent_send_sf_trigger(eNB->Mod_id);
+ }
+#endif
+#endif
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC+offset, 0 );
stop_meas(&eNB->phy_proc_rx);
@@ -3466,3 +3489,4 @@ int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, r
return do_proc;
}
#endif
+
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index ac90094ea4..cd8fbdbc8e 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -364,7 +364,7 @@ void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!!
- LOG_I(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
+ LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
}
@@ -639,7 +639,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
uint8_t pucch_ack_payload[2];
if (get_ack(&ue->frame_parms,
ue->dlsch[eNB_id][0]->harq_ack,
- subframe_tx,pucch_ack_payload) > 0)
+ subframe_tx,pucch_ack_payload,0) > 0)
{
is_sr_an_subframe = 1;
}
@@ -737,6 +737,60 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id)
}
}
+PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
+ lte_prefix_type_t cyclic_prefix_type,
+ uint8_t SR_payload,
+ uint8_t nb_cw,
+ uint8_t cqi_status,
+ uint8_t ri_status)
+{
+ if((cqi_status == 0) && (ri_status==0))
+ {
+ // PUCCH Format 1 1a 1b
+ // 1- SR only ==> PUCCH format 1
+ // 2- 1bit Ack/Nack with/without SR ==> PUCCH format 1a
+ // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b
+ if(nb_cw == 1)
+ {
+ return pucch_format1a;
+ }
+ if(nb_cw == 2)
+ {
+ return pucch_format1b;
+ }
+ if(SR_payload == 1)
+ {
+ return pucch_format1;
+ }
+ }
+ else
+ {
+ // PUCCH Format 2 2a 2b
+ // 1- CQI only or RI only ==> PUCCH format 2
+ // 2- CQI or RI + 1bit Ack/Nack for normal CP ==> PUCCH format 2a
+ // 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b
+ // 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2
+ if(nb_cw == 0)
+ {
+ return pucch_format2;
+ }
+ if(cyclic_prefix_type == NORMAL)
+ {
+ if(nb_cw == 1)
+ {
+ return pucch_format2a;
+ }
+ if(nb_cw == 2)
+ {
+ return pucch_format2b;
+ }
+ }
+ else
+ {
+ return pucch_format2;
+ }
+ }
+}
uint16_t get_n1_pucch(PHY_VARS_UE *ue,
UE_rxtx_proc_t *proc,
harq_status_t *harq_ack,
@@ -986,10 +1040,10 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
int subframe_tx = proc->subframe_tx;
int frame_tx = proc->frame_tx;
int ulsch_start;
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
int overflow=0;
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
int k,l;
- int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
+ int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16)));
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);
@@ -1015,17 +1069,22 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
#endif //else EXMIMO
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
if (empty_subframe)
{
//#if 1
overflow = ulsch_start - 9*frame_parms->samples_per_tti;
for (aa=0; aanb_antennas_tx; aa++) {
- memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti));
-
- if (overflow> 0)
- memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
+ if (overflow > 0)
+ {
+ memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow));
+ memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
+ }
+ else
+ {
+ memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti);
+ }
}
/*#else
overflow = ulsch_start - 9*frame_parms->samples_per_tti;
@@ -1043,7 +1102,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
#endif*/
return;
}
-#endif
+//#endif
if ((frame_tx%100) == 0)
LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
@@ -1381,7 +1440,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
ack_status = reset_ack(&ue->frame_parms,
ue->dlsch[eNB_id][0]->harq_ack,
subframe_tx,
- ue->ulsch[eNB_id]->o_ACK);
+ ue->ulsch[eNB_id]->o_ACK,0);
Nbundled = ack_status;
first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
@@ -1394,7 +1453,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
// check if we received a PDSCH at subframe_tx - 4
// ==> send ACK/NACK on PUSCH
- ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status;
+ ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1;
#if T_TRACER
if(ue->ulsch[eNB_id]->o_ACK[0])
@@ -1411,17 +1470,17 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
}
#endif
- LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n",
+ LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
Mod_id,
ue->ulsch[eNB_id]->rnti,
- frame_tx,subframe_tx,
+ frame_tx%1024,subframe_tx,
ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,
- "[UE %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n",
+ "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n",
Mod_id,harq_pid,frame_tx,subframe_tx,
first_rb,nb_rb,
ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
@@ -1577,8 +1636,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb));
#endif
- LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
- Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
+ 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);
start_meas(&ue->ulsch_modulation_stats);
ulsch_modulation(ue->common_vars.txdataF,
tx_amp,
@@ -1684,17 +1743,79 @@ int16_t get_pucch2_ri(PHY_VARS_UE *ue,int eNB_id) {
return(1);
}
+
+void get_pucch_param(PHY_VARS_UE *ue,
+ UE_rxtx_proc_t *proc,
+ uint8_t *ack_payload,
+ PUCCH_FMT_t format,
+ uint8_t eNB_id,
+ uint8_t SR,
+ uint8_t cqi_report,
+ uint16_t *pucch_resource,
+ uint8_t *pucch_payload,
+ uint16_t *plength)
+{
+
+ switch (format) {
+ case pucch_format1:
+ {
+ pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex;
+ pucch_payload[0] = 0; // payload is ignored in case of format1
+ pucch_payload[1] = 0; // payload is ignored in case of format1
+ }
+ break;
+
+ case pucch_format1a:
+ case pucch_format1b:
+ {
+ pucch_resource[0] = get_n1_pucch(ue,
+ proc,
+ ue->dlsch[eNB_id][0]->harq_ack,
+ eNB_id,
+ ack_payload,
+ SR);
+ pucch_payload[0] = ack_payload[0];
+ //pucch_payload[1] = ack_payload[1];
+ pucch_payload[1] = 1;
+ }
+ break;
+
+ case pucch_format2:
+ {
+ pucch_resource[0] = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
+ if(cqi_report)
+ {
+ pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,plength);
+ }
+ else
+ {
+ *plength = 1;
+ pucch_payload[0] = get_pucch2_ri(ue,eNB_id);
+ }
+ }
+ break;
+
+ case pucch_format2a:
+ case pucch_format2b:
+ LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n");
+ break;
+ }
+}
+
void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
- uint8_t pucch_ack_payload[2];
- uint8_t n1_pucch,n2_pucch;
+ uint8_t pucch_ack_payload[2];
+ uint8_t n1_pucch,n2_pucch;
+ uint16_t pucch_resource;
ANFBmode_t bundling_flag;
PUCCH_FMT_t format;
- uint8_t SR_payload;
+ uint8_t SR_payload;
uint16_t CQI_payload;
uint16_t RI_payload;
+ uint8_t pucch_payload[2];
+ uint16_t len;
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int frame_tx=proc->frame_tx;
@@ -1704,6 +1825,11 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
int tx_amp;
int16_t Po_PUCCH;
uint8_t ack_status=0;
+ uint8_t ack_status_cw0=0;
+ uint8_t ack_status_cw1=0;
+ uint8_t nb_cw=0;
+ uint8_t cqi_status=0;
+ uint8_t ri_status=0;
uint8_t ack_sr_generated = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
@@ -1741,312 +1867,256 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
LOG_D(PHY,"[UE] PUCCH 1b\n");
}
- // Check for SR and do ACK/NACK accordingly
- if (is_SR_TXOp(ue,proc,eNB_id)==1) {
- LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d: got SR_TXOp, Checking for SR for PUSCH from MAC\n",
- Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx);
-
- if (ue->mac_enabled==1) {
- SR_payload = mac_xface->ue_get_SR(Mod_id,
- CC_id,
- frame_tx,
- eNB_id,
- ue->pdcch_vars[eNB_id]->crnti,
- subframe_tx); // subframe used for meas gap
- }
- else {
- SR_payload = 1;
- }
-
- if (SR_payload>0) {
- ue->generate_ul_signal[eNB_id] = 1;
- LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d got the SR for PUSCH is %d\n",
- Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx,SR_payload);
- } else {
- ue->sr[subframe_tx]=0;
- }
- } else {
- SR_payload=0;
+ // Part - I
+ // Collect feedback that should be transmitted at this subframe
+ // - SR
+ // - ACK/NACK
+ // - CQI
+ // - RI
+
+ SR_payload = 0;
+ if (is_SR_TXOp(ue,proc,eNB_id)==1)
+ {
+ if (ue->mac_enabled==1) {
+ SR_payload = mac_xface->ue_get_SR(Mod_id,
+ CC_id,
+ frame_tx,
+ eNB_id,
+ ue->pdcch_vars[eNB_id]->crnti,
+ subframe_tx); // subframe used for meas gap
+ }
+ else {
+ SR_payload = 1;
+ }
}
-
- ack_status = get_ack(&ue->frame_parms,
- ue->dlsch[eNB_id][0]->harq_ack,
- subframe_tx,pucch_ack_payload);
- if (ack_status > 0) {
- // we need to transmit ACK/NAK in this subframe
-
- ue->generate_ul_signal[eNB_id] = 1;
- ack_sr_generated = 1;
- if ((frame_parms->frame_type == TDD) && (SR_payload>0)) {
- format = pucch_format1b;
- }
+ ack_status_cw0 = reset_ack(&ue->frame_parms,
+ ue->dlsch[eNB_id][0]->harq_ack,
+ subframe_tx,
+ pucch_ack_payload,
+ 0);
+
+ ack_status_cw1 = reset_ack(&ue->frame_parms,
+ ue->dlsch[eNB_id][1]->harq_ack,
+ subframe_tx,
+ pucch_ack_payload,
+ 1);
+
+ nb_cw = ack_status_cw0 + ack_status_cw1;
+
+ cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
+ (is_cqi_TXOp(ue,proc,eNB_id)==1));
+
+ ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
+ (is_ri_TXOp(ue,proc,eNB_id)==1));
+
+ // Part - II
+ // if nothing to report ==> exit function
+ if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0))
+ {
+ LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n",
+ frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status);
+ return;
+ }
+
+ // Part - III
+ // Decide which PUCCH format should be used if needed
+ format = get_pucch_format(frame_parms->frame_type,
+ frame_parms->Ncp,
+ SR_payload,
+ nb_cw,
+ cqi_status,
+ ri_status);
+ // Determine PUCCH resources and payload: mandatory for pucch encoding
+ get_pucch_param(ue,
+ proc,
+ pucch_ack_payload,
+ format,
+ eNB_id,
+ SR_payload,
+ cqi_status,
+ &pucch_resource,
+ &pucch_payload,
+ &len);
+
+ LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
+ frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
+
+
+ // Part - IV
+ // Generate PUCCH signal
+ ue->generate_ul_signal[eNB_id] = 1;
+
+ switch (format) {
+ case pucch_format1:
+ case pucch_format1a:
+ case pucch_format1b:
+ {
+ if (ue->mac_enabled == 1) {
+ Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
+ }
+ else {
+ Po_PUCCH = ue->tx_power_max_dBm;
+ }
+ ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
+ ue->tx_total_RE[subframe_tx] = 12;
- n1_pucch = get_n1_pucch(ue,
- proc,
- ue->dlsch[eNB_id][0]->harq_ack,
- eNB_id,
- pucch_ack_payload,
- SR_payload);
-
- if (ue->mac_enabled == 1) {
- Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
- }
- else {
- Po_PUCCH = ue->tx_power_max_dBm;
- }
- ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
- ue->tx_total_RE[subframe_tx] = 12;
-
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
- tx_amp = get_tx_amp(Po_PUCCH,
- ue->tx_power_max_dBm,
- ue->frame_parms.N_RB_UL,
- 1);
+ tx_amp = get_tx_amp(Po_PUCCH,
+ ue->tx_power_max_dBm,
+ ue->frame_parms.N_RB_UL,
+ 1);
#else
- tx_amp = AMP;
+ tx_amp = AMP;
#endif
#if T_TRACER
T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
- T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+ T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
#endif
- if (SR_payload>0) {
- LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
- Mod_id,
- ue->dlsch[eNB_id][0]->rnti,
- frame_tx % 1024, subframe_tx,
- (format == pucch_format1a? "1a": (
- format == pucch_format1b? "1b" : "??")),
- pucch_ack_payload[0],pucch_ack_payload[1],
- frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
- isShortenPucch,
- ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
- Po_PUCCH,
- tx_amp);
- } else {
- LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
- Mod_id,
- ue->dlsch[eNB_id][0]->rnti,
- frame_tx, subframe_tx,ue->rx_offset_diff,
- (format == pucch_format1a? "1a": (
- format == pucch_format1b? "1b" : "??")),
- frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
- isShortenPucch,
- n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload,
- Po_PUCCH,
- tx_amp);
- }
+ if(format == pucch_format1)
+ {
+ LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
+ Mod_id,
+ ue->dlsch[eNB_id][0]->rnti,
+ frame_tx, subframe_tx,
+ frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+ isShortenPucch,
+ ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
+ Po_PUCCH);
+ }
+ else
+ {
+ if (SR_payload>0) {
+ LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
+ Mod_id,
+ ue->dlsch[eNB_id][0]->rnti,
+ frame_tx % 1024, subframe_tx,
+ (format == pucch_format1a? "1a": (
+ format == pucch_format1b? "1b" : "??")),
+ pucch_ack_payload[0],pucch_ack_payload[1],
+ frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+ isShortenPucch,
+ pucch_resource,
+ Po_PUCCH,
+ tx_amp);
+ } else {
+ LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
+ Mod_id,
+ ue->dlsch[eNB_id][0]->rnti,
+ frame_tx%1024, subframe_tx,ue->rx_offset_diff,
+ (format == pucch_format1a? "1a": (
+ format == pucch_format1b? "1b" : "??")),
+ frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+ isShortenPucch,
+ pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload,
+ Po_PUCCH,
+ tx_amp);
+ }
+ }
#if T_TRACER
- if(pucch_ack_payload[0])
- {
- LOG_I(PHY,"PUCCH ACK\n");
- T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
- T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
- }
- else
- {
- LOG_I(PHY,"PUCCH NACK\n");
- T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
- T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
- }
+ if(pucch_payload[0])
+ {
+ T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
+ T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
+ }
+ else
+ {
+ T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
+ T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
+ }
#endif
-
- if (abstraction_flag == 0) {
-
- generate_pucch1x(ue->common_vars.txdataF,
- &ue->frame_parms,
- ue->ncs_cell,
- format,
- &ue->pucch_config_dedicated[eNB_id],
- n1_pucch,
- isShortenPucch, // shortened format
- pucch_ack_payload,
- tx_amp,
- subframe_tx);
-
- } else {
+
+ if (abstraction_flag == 0) {
+
+ generate_pucch1x(ue->common_vars.txdataF,
+ &ue->frame_parms,
+ ue->ncs_cell,
+ format,
+ &ue->pucch_config_dedicated[eNB_id],
+ pucch_resource,
+ isShortenPucch, // shortened format
+ pucch_payload,
+ tx_amp,
+ subframe_tx);
+
+ } else {
#ifdef PHY_ABSTRACTION
- LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
- generate_pucch_emul(ue,
- proc,
- format,
- ue->frame_parms.pucch_config_common.nCS_AN,
- pucch_ack_payload,
- SR_payload);
+ LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
+ generate_pucch_emul(ue,
+ proc,
+ format,
+ ue->frame_parms.pucch_config_common.nCS_AN,
+ pucch_payload,
+ SR_payload);
#endif
- }
- } else if (SR_payload==1) { // no ACK/NAK but SR is triggered by MAC
+ }
+ }
+ break;
- ack_sr_generated = 1;
- if (ue->mac_enabled == 1) {
- Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,pucch_format1);
- }
- else {
- Po_PUCCH = ue->tx_power_max_dBm;
- }
- ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
- ue->tx_total_RE[subframe_tx] = 12;
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
- tx_amp = get_tx_amp(Po_PUCCH,
- ue->tx_power_max_dBm,
- ue->frame_parms.N_RB_UL,
- 1);
-#else
- tx_amp = AMP;
-#endif
-#if T_TRACER
- T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
- T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
-#endif
- LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
- Mod_id,
- ue->dlsch[eNB_id][0]->rnti,
- frame_tx, subframe_tx,
- frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
- isShortenPucch,
- ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
- Po_PUCCH);
-
- if (abstraction_flag == 0) {
-
- generate_pucch1x(ue->common_vars.txdataF,
- &ue->frame_parms,
- ue->ncs_cell,
- pucch_format1,
- &ue->pucch_config_dedicated[eNB_id],
- ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
- isShortenPucch, // shortened format
- pucch_ack_payload, // this is ignored anyway, we just need a pointer
- tx_amp,
- subframe_tx);
- } else {
- LOG_D(PHY,"Calling generate_pucch_emul ...\n");
- generate_pucch_emul(ue,
- proc,
- pucch_format1,
- ue->frame_parms.pucch_config_common.nCS_AN,
- pucch_ack_payload,
- SR_payload);
-
- }
- } // SR_Payload==1
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
-
- // PUCCH 2x
-
- if (ack_sr_generated == 0) { // we have not generated ACK/NAK/SR in this subframe
-
- n2_pucch = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
- // only use format2 for now, i.e. now ACK/NAK - CQI multiplexing
- format = pucch_format2;
-
- // Periodic CQI report
- if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
- (is_cqi_TXOp(ue,proc,eNB_id)==1)){
+ case pucch_format2:
+ {
if (ue->mac_enabled == 1) {
- Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
+ Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
}
else {
- Po_PUCCH = ue->tx_power_max_dBm;
+ Po_PUCCH = ue->tx_power_max_dBm;
}
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
ue->tx_total_RE[subframe_tx] = 12;
-
+
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
tx_amp = get_tx_amp(Po_PUCCH,
- ue->tx_power_max_dBm,
- ue->frame_parms.N_RB_UL,
- 1);
+ ue->tx_power_max_dBm,
+ ue->frame_parms.N_RB_UL,
+ 1);
#else
tx_amp = AMP;
#endif
#if T_TRACER
T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
- T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+ T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
#endif
-
- int len;
- // get the payload : < 12 bits, returned in len
- CQI_payload = get_pucch2_cqi(ue,eNB_id,&len);
- generate_pucch2x(ue->common_vars.txdataF,
- &ue->frame_parms,
- ue->ncs_cell,
- format,
- &ue->pucch_config_dedicated[eNB_id],
- n2_pucch,
- &CQI_payload,
- len, // A
- 0, // B2 not needed
- tx_amp,
- subframe_tx,
- ue->pdcch_vars[eNB_id]->crnti);
- ue->generate_ul_signal[eNB_id] = 1;
-
- LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (CQI %d), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
- Mod_id,
- ue->dlsch[eNB_id][0]->rnti,
- frame_tx, subframe_tx,CQI_payload,
- n2_pucch,
- Po_PUCCH,
- isShortenPucch,
- tx_amp);
-
- }
- // Periodic RI report
- else if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
- (is_ri_TXOp(ue,proc,eNB_id)==1)){
-
- if (ue->mac_enabled == 1) {
- Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
- }
- else {
- Po_PUCCH = ue->tx_power_max_dBm;
- }
- ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
- ue->tx_total_RE[subframe_tx] = 12;
-#if T_TRACER
- T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
- T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
-#endif
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
- tx_amp = get_tx_amp(Po_PUCCH,
- ue->tx_power_max_dBm,
- ue->frame_parms.N_RB_UL,
- 1);
-#else
- tx_amp = AMP;
-#endif
- LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
- Mod_id,
- ue->dlsch[eNB_id][0]->rnti,
- frame_tx, subframe_tx,
- n2_pucch,
- Po_PUCCH,
- isShortenPucch,
- tx_amp);
-
- RI_payload = get_pucch2_ri(ue,eNB_id);
+ LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
+ Mod_id,
+ ue->dlsch[eNB_id][0]->rnti,
+ frame_tx%1024, subframe_tx,
+ n2_pucch,
+ Po_PUCCH,
+ isShortenPucch,
+ tx_amp);
generate_pucch2x(ue->common_vars.txdataF,
- &ue->frame_parms,
- ue->ncs_cell,
- format,
- &ue->pucch_config_dedicated[eNB_id],
- n2_pucch,
- &RI_payload,
- 1, // A
- 0, // B2 not needed
- tx_amp,
- subframe_tx,
- ue->pdcch_vars[eNB_id]->crnti);
-
- ue->generate_ul_signal[eNB_id] = 1;
- }
+ &ue->frame_parms,
+ ue->ncs_cell,
+ format,
+ &ue->pucch_config_dedicated[eNB_id],
+ pucch_resource,
+ pucch_payload,
+ len, // A
+ 0, // B2 not needed
+ tx_amp,
+ subframe_tx,
+ ue->pdcch_vars[eNB_id]->crnti);
+ }
+ break;
+
+ case pucch_format2a:
+ LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
+ Mod_id,
+ ue->dlsch[eNB_id][0]->rnti,
+ frame_tx%1024, subframe_tx);
+ break;
+ case pucch_format2b:
+ LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
+ Mod_id,
+ ue->dlsch[eNB_id][0]->rnti,
+ frame_tx%1024, subframe_tx);
+ break;
+ default:
+ break;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
@@ -2186,12 +2256,12 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
reset_ack(&ue->frame_parms,
ue->dlsch[eNB_id][0]->harq_ack,
subframe_tx,
- ue->ulsch[eNB_id]->o_ACK);
+ ue->ulsch[eNB_id]->o_ACK,0);
reset_ack(&ue->frame_parms,
ue->dlsch_SI[eNB_id]->harq_ack,
subframe_tx,
- ue->ulsch[eNB_id]->o_ACK);
+ ue->ulsch[eNB_id]->o_ACK,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
@@ -2770,9 +2840,9 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
(dci_alloc_rx[i].format != format0)) {
- LOG_D(PHY,"[UE %d][DCI][PDSCH %x] frame %d, subframe %d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
+ LOG_D(PHY,"[UE %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
ue->Mod_id,dci_alloc_rx[i].rnti,
- frame_rx,subframe_rx,
+ frame_rx%1024,subframe_rx,
dci_alloc_rx[i].format,
ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
ue->pdcch_vars[eNB_id]->nCCE[subframe_rx],
@@ -2801,8 +2871,10 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
// update TPC for PUCCH
if((dci_alloc_rx[i].format == format1) ||
(dci_alloc_rx[i].format == format1A) ||
+ (dci_alloc_rx[i].format == format1B) ||
(dci_alloc_rx[i].format == format2) ||
- (dci_alloc_rx[i].format == format2A))
+ (dci_alloc_rx[i].format == format2A) ||
+ (dci_alloc_rx[i].format == format2B))
{
ue->dlsch[eNB_id][0]->g_pucch += ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->delta_PUCCH;
}
diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c
index e19d3ad8c4..5bc03bb58d 100644
--- a/openair1/SCHED/pucch_pc.c
+++ b/openair1/SCHED/pucch_pc.c
@@ -88,17 +88,17 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u
}
if (pucch_fmt!=pucch_format1) {
- LOG_D(PHY,"[UE %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
+ LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
ue->Mod_id,
- ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
+ ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
Po_PUCCH,
ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
get_PL(ue->Mod_id,ue->CC_id,eNB_id),
ue->dlsch[eNB_id][0]->g_pucch);
} else {
- LOG_D(PHY,"[UE %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
+ LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
ue->Mod_id,
- ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
+ ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
Po_PUCCH,
ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
get_PL(ue->Mod_id,ue->CC_id,eNB_id),
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 62b4063d29..af39d92a6b 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -118,10 +118,10 @@ 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(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],
double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) {
int i,u;
@@ -145,17 +145,17 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou
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]);
}
-
+
}
}
}
}
-
+
// Multipath channel
if (awgn_flag == 0) {
multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
2*UE->frame_parms.samples_per_tti,hold_channel);
-
+
// printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
if(abstx==1 && num_rounds>1)
if(round==0 && hold_channel==0) {
@@ -163,7 +163,7 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou
random_channel(eNB2UE[2],0);
random_channel(eNB2UE[3],0);
}
-
+
if (UE->perfect_ce==1) {
// fill in perfect channel estimates
freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
@@ -173,15 +173,15 @@ 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);
// snr=pow(10.0,.1*SNR);
fprintf(csv_fd,"%f,",SNR);
-
+
for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
for (aarx=0; aarxnb_rx; aarx++) {
for (aatx=0; aatxnb_tx; aatx++) {
@@ -190,11 +190,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou
fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
}
}
- }
-
+ }
+
if(num_rounds>1) {
freq_channel(eNB2UE[1], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1);
-
+
for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
for (aarx=0; aarxnb_rx; aarx++) {
for (aatx=0; aatxnb_tx; aatx++) {
@@ -204,9 +204,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);
-
+
for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
for (aarx=0; aarxnb_rx; aarx++) {
for (aatx=0; aatxnb_tx; aatx++) {
@@ -216,9 +216,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);
-
+
for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
for (aarx=0; aarxnb_rx; aarx++) {
for (aatx=0; aatxnb_tx; aatx++) {
@@ -231,10 +231,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou
}
}
}
-
+
//AWGN
- // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A
- 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 - get_pa_dB(eNB->pdsch_config_dedicated);
+ // 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 = pow(10,sigma2_dB/10);
for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
@@ -251,7 +252,7 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou
void fill_DCI(PHY_VARS_eNB *eNB,
DCI_ALLOC_t *dci_alloc,
- int subframe,
+ int subframe,
int n_rnti,
int n_users,
int transmission_mode,
@@ -278,9 +279,9 @@ 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;
@@ -294,7 +295,7 @@ void fill_DCI(PHY_VARS_eNB *eNB,
((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);
@@ -307,7 +308,7 @@ void fill_DCI(PHY_VARS_eNB *eNB,
((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);
@@ -1223,17 +1224,17 @@ DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t
if (subframeP == subframe) {
DCI_pdu.Num_ue_spec_dci = num_ue_spec_dci;
DCI_pdu.Num_common_dci = num_common_dci;
- DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
+ DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
return(&DCI_pdu);
} else {
DCI_pdu.Num_ue_spec_dci = 0;
DCI_pdu.Num_common_dci = 0;
- DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
+ DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
}
}
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) {
-
+
return;
}
@@ -1459,7 +1460,7 @@ int main(int argc, char **argv)
common_flag = 1;
TPC = atoi(optarg);
break;
-
+
case 'E':
threequarter_fs=1;
break;
@@ -1779,7 +1780,7 @@ int main(int argc, char **argv)
form_ue = create_lte_phy_scope_ue();
sprintf (title, "LTE PHY SCOPE eNB");
fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
-
+
if (!dual_stream_UE==0) {
UE->use_ia_receiver = 1;
fl_set_button(form_ue->button_0,1);
@@ -1807,9 +1808,9 @@ int main(int argc, char **argv)
perfect_ce);
if ((transmission_mode==1) || (transmission_mode==7)) {
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++)
- for (re=0; reframe_parms.ofdm_symbol_size; re++)
- eNB->common_vars.beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx;
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++)
+ for (re=0; reframe_parms.ofdm_symbol_size; re++)
+ eNB->common_vars.beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx;
}
if (transmission_mode<7)
@@ -1827,11 +1828,11 @@ int main(int argc, char **argv)
init_te_thread(eNB,NULL);
}
- // callback functions required for phy_procedures_tx
+ // 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;
printf("Setting mcs1 = %d\n",mcs1);
@@ -2107,6 +2108,10 @@ int main(int argc, char **argv)
UE->dlsch[0][i]->rnti = n_rnti;
}
+ UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+ UE->dlsch_ra[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+ UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
+
// structure for SIC at UE
UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
@@ -2335,7 +2340,7 @@ 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);
}
else {
@@ -2343,14 +2348,14 @@ int main(int argc, char **argv)
(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; isubframe_tx = subframe;
eNB->abstraction_flag=0;
-
+
phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1);
-
-
+
+
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,
@@ -2425,19 +2430,19 @@ int main(int argc, char **argv)
stop_meas(&eNB->ofdm_mod_stats);
-
+
// generate next subframe for channel estimation
-
+
proc_eNB->subframe_tx = subframe+1;
-
+
phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0);
-
+
do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
eNB->common_vars.txdata[eNB_id],
(subframe*2)+2,
&eNB->frame_parms);
-
+
proc_eNB->frame_tx++;
tx_lev = 0;
@@ -2450,7 +2455,7 @@ 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);
@@ -2466,7 +2471,7 @@ int main(int argc, char **argv)
}
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);
-
+
UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[subframe&1];
proc->subframe_rx = subframe;
@@ -2479,7 +2484,7 @@ int main(int argc, char **argv)
UE->rx_offset,
0,
0);
-
+
if (n_frames==1) printf("Running phy_procedures_UE_RX\n");
phy_procedures_UE_RX(UE,proc,0,0,normal_txrx,no_relay,NULL);
@@ -2488,7 +2493,7 @@ int main(int argc, char **argv)
/*
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("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],
@@ -2503,53 +2508,55 @@ int main(int argc, char **argv)
if ((test_perf ==0 ) && (n_frames==1)) {
write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8);
-
+
if (eNB->frame_parms.nb_antennas_tx>1)
write_output("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);
-
+
//common vars
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.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
-
+
if (UE->frame_parms.nb_antennas_rx>1) {
write_output("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
write_output("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
}
-
+
write_output("dlsch00_r0.m","dl00_r0",
&(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
-
+
if (UE->frame_parms.nb_antennas_rx>1)
write_output("dlsch01_r0.m","dl01_r0",
&(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
-
+
if (eNB->frame_parms.nb_antennas_tx>1)
write_output("dlsch10_r0.m","dl10_r0",
&(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
-
+
if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
write_output("dlsch11_r0.m","dl11_r0",
&(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
-
+
//pdsch_vars
- dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round);
- //dump_dlsch2(UE,eNB_id_i,coded_bits_per_codeword);
+
+ dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid);
+
write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
-
+
//pdcch_vars
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],300*3,1,1);
-
+
write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1);
write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4);
-
+
}
-
-
+
+
if (UE->dlsch_errors[0] == 0) {
@@ -2563,7 +2570,7 @@ int main(int argc, char **argv)
UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->TBS;
TB0_active = 0;
-
+
} // DLSCH received ok
else {
errs[round]++;
@@ -2594,8 +2601,9 @@ int main(int argc, char **argv)
write_output(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
sprintf(fname,"rxsigF0_r%d.m",round);
sprintf(vname,"rxs0F_r%d",round);
+
write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
-
+
if (UE->frame_parms.nb_antennas_rx>1) {
sprintf(fname,"rxsig1_r%d.m",round);
sprintf(vname,"rxs1_r%d.m",round);
@@ -2636,8 +2644,9 @@ int main(int argc, char **argv)
}
//pdsch_vars
- dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round);
-
+ dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid);
+
+
//write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
//write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
//write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
@@ -2645,10 +2654,10 @@ int main(int argc, char **argv)
//pdcch_vars
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],300*3,1,1);
-
+
write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1);
- write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4);
-
+ write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4);
+
if (round == 3) exit(-1);
}
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
new file mode 100644
index 0000000000..c3f975006d
--- /dev/null
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
@@ -0,0 +1,5354 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file dlsim.c
+ \brief Top-level DL simulator
+ \author R. Knopp
+ \date 2011 - 2014
+ \version 0.1
+ \company Eurecom
+ \email: knopp@eurecom.fr
+ \note
+ \warning
+*/
+
+//#define DEBUG_HARQ
+//#define PRINT_THROUGHPUT
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include "SIMULATION/TOOLS/defs.h"
+#include "PHY/types.h"
+#include "PHY/defs.h"
+#include "PHY/vars.h"
+
+#include "SCHED/defs.h"
+#include "SCHED/vars.h"
+#include "LAYER2/MAC/vars.h"
+#include "OCG_vars.h"
+#include "UTIL/LOG/log.h"
+#include "UTIL/LISTS/list.h"
+
+#include "unitary_defs.h"
+
+extern unsigned int dlsch_tbs25[27][25],TBStable[27][110];
+extern unsigned char offset_mumimo_llr_drange_fix;
+
+extern uint8_t interf_unaw_shift0;
+extern uint8_t interf_unaw_shift1;
+extern uint8_t interf_unaw_shift;
+
+#include "PHY/TOOLS/lte_phy_scope.h"
+
+#define PRINT_BYTES
+
+PHY_VARS_eNB *eNB;
+PHY_VARS_UE *UE;
+
+
+int otg_enabled=0;
+/*the following parameters are used to control the processing times calculations*/
+double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */
+double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */
+double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */
+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 */
+
+void handler(int sig)
+{
+ void *array[10];
+ size_t size;
+
+ // 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);
+}
+
+
+
+//DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_2A[2];
+
+DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_1E[2];
+uint64_t DLSCH_alloc_pdu_1[2];
+
+#define UL_RB_ALLOC 0x1ff;
+#define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2)
+
+//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13
+//#define DLSCH_RB_ALLOC 0x0001
+void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
+{
+
+ int aa, slot_offset, slot_offset_F;
+
+ slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7);
+ slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
+
+ for (aa=0; aanb_antennas_tx; aa++) {
+ // printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
+
+ if (frame_parms->Ncp == 1)
+ PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
+ &txdata[aa][slot_offset], // output
+ frame_parms->ofdm_symbol_size,
+ 6, // number of symbols
+ frame_parms->nb_prefix_samples, // number of prefix samples
+ CYCLIC_PREFIX);
+ else {
+ normal_prefix_mod(&txdataF[aa][slot_offset_F],
+ &txdata[aa][slot_offset],
+ 7,
+ frame_parms);
+ }
+
+
+ }
+
+}
+
+int main(int argc, char **argv)
+{
+
+ int c;
+ int k,i,aa,aarx,aatx;
+
+ int s,Kr,Kr_bytes;
+
+ double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1,rate[2];
+ double snr_step=1,input_snr_step=1, snr_int=30;
+
+ LTE_DL_FRAME_PARMS *frame_parms;
+ double **s_re,**s_im,**r_re,**r_im;
+ 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,transmission_mode=1,n_tx_port=1, n_tx_phy=1, n_rx=1;
+ uint16_t Nid_cell=0;
+
+ int8_t eNB_id = 0, eNB_id_i = 1;
+ unsigned char mcs1=0,mcs2=0,mcs_i=0,awgn_flag=0,dci_flag=0;
+ unsigned char i_mod = 2;
+ unsigned short NB_RB;
+ unsigned char Ns,l,m;
+ uint16_t tdd_config=3;
+ uint16_t n_rnti=0x1234;
+ int n_users = 1;
+
+ int TB=0;
+ RX_type_t rx_type=rx_standard;
+ unsigned char cur_harq_pid;
+ int hold_rank1_precoder=0;
+ int tpmi_retr=0;
+ bool is_first_time;
+ int updated_csi = 0;
+
+ SCM_t channel_model=Rayleigh1;
+ // unsigned char *input_data,*decoded_output;
+
+ unsigned char *input_buffer0[2],*input_buffer1[2];
+ unsigned short input_buffer_length0,input_buffer_length1;
+
+ /* A variable "ret" is a nuumber of turbo iterations, that are performed in the turbo-decoder for each CW.
+ The decoder checks CRC, and if CRC test fails, it increments "ret". Ret is between 1 and 4, where 4 is for
+ the max number of turbo iterations. If the CRC is passed, ret is equal to a current iteration.
+ This is done separately for each CW inside decoding process.
+ Again: this is not a HARQ retransmission!*/
+ unsigned int ret[2];
+ unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2];
+
+ unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, decoded_in_sic[4]={0,0,0,0}, sic_attempt[4]={0,0,0,0}, round_sic=0;
+ unsigned int dci_errors=0, dlsch_active=0;
+ unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}, TB0_deact[4]={0,0,0,0}, TB1_deact[4]={0,0,0,0};
+
+ int re_allocated;
+ char fname[32],vname[32];
+ FILE *bler_fd;
+ char bler_fname[256];
+ FILE *time_meas_fd;
+ char time_meas_fname[256];
+
+ FILE *input_trch_fd=NULL;
+ 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];
+ double channelx,channely;
+
+ // unsigned char pbch_pdu[6];
+
+ DCI_ALLOC_t dci_alloc[8],dci_alloc_rx[8];
+ int num_common_dci=0,num_ue_spec_dci=0,num_dci=0;
+
+ // FILE *rx_frame_file;
+
+ int n_frames;
+ int n_ch_rlz = 1;
+
+ channel_desc_t *eNB2UE[8];
+
+ uint8_t num_pdcch_symbols=1,num_pdcch_symbols_2=0;
+ uint8_t pilot1,pilot2,pilot3;
+ uint8_t rx_sample_offset = 0;
+ //char stats_buffer[4096];
+ //int len;
+
+ uint8_t num_rounds = 4;
+ uint8_t subframe=7;
+ int u;
+ int n=0;
+ int abstx=0;
+ int iii;
+ FILE *csv_fd=NULL;
+ char csv_fname[512];
+ int ch_realization;
+ int pmi_feedback=0;
+ int hold_channel=0;
+
+ // temporarily for retransmissions:
+ unsigned char resend_cw1=0; //if 0 resend only cw0
+ unsigned char resend_cw0_cw1=1; //if 0 resend both cw in a normal way
+
+ // void *data;
+ // int ii;
+ int bler;
+ double blerr[2][4],uncoded_ber,avg_ber;
+ short *uncoded_ber_bit=NULL;
+ uint8_t N_RB_DL=25,osf=1;
+ uint8_t fdd_flag = 0;
+ frame_t frame_type = FDD;
+ int xforms=0;
+ FD_lte_phy_scope_ue *form_ue = NULL;
+ char title[255];
+ uint32_t DLSCH_RB_ALLOC = 0x1fff;
+ int numCCE=0;
+ int dci_length_bytes=0,dci_length=0;
+ int common_flag=0,TPC=0;
+
+ double cpu_freq_GHz;
+ //time_stats_t ts;//,sts,usts;
+ int avg_iter[2],iter_trials[2];
+ int rballocset=0;
+ int print_perf=0;
+ int test_perf=0;
+ int dump_table=0;
+ int llr8_flag=0;
+
+ double effective_rate=0.0;
+
+ double thr_cw0_tm4 = 0.0;
+ double thr_cw0_tm4_nonconst = 0.0;
+ double thr_cw0[4]={0,0,0,0}, thr_cw1[4]={0,0,0,0}, thr_cw0_tot = 0.0, thr_cw1_tot = 0.0;
+ unsigned int tbs0_init=0, tbs1_init=0;
+ double rate0_init=0.0, rate1_init=0.0;
+ int mcs0_init=0, mcs1_init=0, mod_order0_init = 0, mod_order1_init=0;
+ char channel_model_input[17]="I";
+
+ int TB0_active = 1;
+ int TB1_active = 1;
+
+ uint32_t perfect_ce = 0;
+
+ LTE_DL_UE_HARQ_t *dlsch0_ue_harq;
+ LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq;
+ uint8_t Kmimo;
+
+ int32_t **sic_buffer;
+ int8_t cw_to_decode_interf;
+ int8_t cw_to_decode_interf_free;
+ int8_t cw_non_sic;
+ int8_t cw_sic;
+ FILE *proc_fd = NULL;
+ char buf[64];
+ uint8_t ue_category=4;
+ uint32_t Nsoft;
+
+ int CCE_table[800];
+
+ int threequarter_fs=0;
+
+
+
+ opp_enabled=1; // to enable the time meas
+
+#if defined(__arm__)
+ FILE *proc_fd = NULL;
+ char buf[64];
+
+ proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
+ if(!proc_fd)
+ printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
+ else {
+ while(fgets(buf, 63, proc_fd))
+ printf("%s", buf);
+ }
+ fclose(proc_fd);
+ cpu_freq_GHz = ((double)atof(buf))/1e6;
+#else
+ cpu_freq_GHz = get_cpu_freq_GHz();
+#endif
+ printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
+
+ //signal(SIGSEGV, handler);
+ //signal(SIGABRT, handler);
+
+ logInit();
+ set_glog(LOG_INFO, LOG_MED);
+
+ // default parameters
+ n_frames = 1000;
+ snr0 = 0;
+ // num_layers = 1;
+ perfect_ce = 0;
+
+
+ while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XYv:W:J:K:U")) != -1) {
+
+ switch (c) {
+ case 'a':
+ awgn_flag = 1;
+ channel_model = AWGN;
+ break;
+
+ case 'A':
+ abstx = 1;
+ break;
+
+ case 'b':
+ tdd_config=atoi(optarg);
+ break;
+
+ case 'B':
+ N_RB_DL=atoi(optarg);
+ break;
+
+ case 'c':
+ num_pdcch_symbols=atoi(optarg);
+ break;
+
+ case 'C':
+ Nid_cell = atoi(optarg);
+ break;
+
+ case 'd':
+ dci_flag = 1;
+ break;
+
+ case 'D':
+ frame_type=TDD;
+ break;
+
+ case 'e':
+ num_rounds=1;
+ common_flag = 1;
+ TPC = atoi(optarg);
+ break;
+
+ case 'E':
+ threequarter_fs=1;
+ break;
+
+ case 'f':
+ input_snr_step= atof(optarg);
+ break;
+
+ case 'F':
+ forgetting_factor = atof(optarg);
+ break;
+
+ case 'i':
+ input_fd = fopen(optarg,"r");
+ input_file=1;
+ dci_flag = 1;
+ break;
+
+ case 'I':
+ input_trch_fd = fopen(optarg,"r");
+ input_trch_file=1;
+ break;
+
+ case 'L':
+ llr8_flag=1;
+ break;
+
+ case 'l':
+ offset_mumimo_llr_drange_fix=atoi(optarg);
+ break;
+
+ case 'm':
+ mcs1 = atoi(optarg);
+ break;
+
+ case 'M':
+ mcs2 = atoi(optarg);
+ //i_mod = get_Qm(mcs2); /// think here again!!!
+ break;
+
+ case 'O':
+ test_perf=atoi(optarg);
+ //print_perf =1;
+ break;
+
+ case 't':
+ mcs_i = atoi(optarg);
+ i_mod = get_Qm(mcs_i);
+ break;
+
+ case 'n':
+ n_frames = atoi(optarg);
+ break;
+
+ case 'o':
+ rx_sample_offset = atoi(optarg);
+ break;
+
+ case 'r':
+ DLSCH_RB_ALLOC = atoi(optarg);
+ rballocset = 1;
+ break;
+
+ case 's':
+ snr0 = atof(optarg);
+ break;
+
+ case 'w':
+ snr_int = atof(optarg);
+ break;
+
+ case 'N':
+ n_ch_rlz= atof(optarg);
+ break;
+
+ case 'p':
+ extended_prefix_flag=1;
+ break;
+
+ case 'g':
+ memcpy(channel_model_input,optarg,17);
+
+ switch((char)*optarg) {
+ case 'A':
+ channel_model=SCM_A;
+ break;
+ case 'B':
+ channel_model=SCM_B;
+ break;
+ case 'C':
+ channel_model=SCM_C;
+ break;
+ case 'D':
+ channel_model=SCM_D;
+ break;
+ case 'E':
+ channel_model=EPA;
+ break;
+ case 'F':
+ channel_model=EVA;
+ break;
+ case 'G':
+ channel_model=ETU;
+ break;
+ case 'H':
+ channel_model=Rayleigh8;
+ break;
+ case 'I':
+ channel_model=Rayleigh1;
+ break;
+ case 'J':
+ channel_model=Rayleigh1_corr;
+ break;
+ case 'K':
+ channel_model=Rayleigh1_anticorr;
+ break;
+ case 'L':
+ channel_model=Rice8;
+ break;
+ case 'M':
+ channel_model=Rice1;
+ break;
+ case 'N':
+ channel_model=AWGN;
+ break;
+ case 'P':
+ channel_model=Rayleigh1_orthogonal;
+ break;
+ case 'Q':
+ channel_model=Rayleigh1_orth_eff_ch_TM4_prec_real; // for DUALSTREAM_UNIFORM_PRECODING1 when interf is precancelled
+ break;
+ case 'R':
+ channel_model=Rayleigh1_orth_eff_ch_TM4_prec_imag; // for DUALSTREAM_UNIFORM_PRECODINGj when interf is precancelled
+ break;
+ case 'S':
+ channel_model=Rayleigh8_orth_eff_ch_TM4_prec_real;//when interf is precancelled
+ break;
+ case 'T':
+ channel_model=Rayleigh8_orth_eff_ch_TM4_prec_imag;//when interf is precancelled
+ break;
+ case 'U':
+ channel_model = TS_SHIFT;
+ break;
+ case 'V':
+ channel_model=EPA_low;
+ break;
+ case 'W':
+ channel_model=EPA_medium;
+ break;
+ case 'X':
+ channel_model=EPA_high;
+ break;
+ default:
+ msg("Unsupported channel model!\n");
+ exit(-1);
+ }
+ break;
+ case 'z':
+ n_rx=atoi(optarg);
+ if ((n_rx==0) || (n_rx>2)) {
+ msg("Unsupported number of rx antennas %d\n",n_rx);
+ exit(-1);
+ }
+ break;
+
+ case 'R':
+ num_rounds=atoi(optarg);
+ break;
+ case 'S':
+ subframe=atoi(optarg);
+ break;
+ case 'T':
+ n_rnti=atoi(optarg);
+ break;
+ case 'u':
+ rx_type = (RX_type_t) atoi(optarg);
+ if (rx_typerx_SIC_dual_stream) {
+ printf("Unsupported rx type %d\n",rx_type);
+ exit(-1);
+ }
+ break;
+ case 'v':
+ 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);
+ exit(-1);
+ }
+ break;
+ case 'P':
+ print_perf=1;
+ break;
+ case 'q':
+ 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);
+ exit(-1);
+ }
+ break;
+ case 'x':
+ transmission_mode=atoi(optarg);
+ if ((transmission_mode!=1) &&
+ (transmission_mode!=2) &&
+ (transmission_mode!=3) &&
+ (transmission_mode!=4) &&
+ (transmission_mode!=5) &&
+ (transmission_mode!=6)) {
+ msg("Unsupported transmission mode %d\n",transmission_mode);
+ exit(-1);
+ }
+ if (transmission_mode>1 && transmission_mode<7) {
+ n_tx_port = 2;
+ }
+ break;
+ case 'y':
+ n_tx_phy=atoi(optarg);
+
+ if (n_tx_phy < n_tx_port) {
+ msg("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);
+ 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");
+ exit(-1);
+ }
+
+ break;
+ case 'X':
+ xforms = 1;
+ break;
+ case 'Z':
+ dump_table=1;
+ break;
+ case 'Y':
+ perfect_ce=1;
+ break;
+ case 'V':
+ interf_unaw_shift0=atoi(optarg);
+ break;
+ case 'W':
+ interf_unaw_shift1=atoi(optarg);
+ break;
+ case 'J':
+ interf_unaw_shift=atoi(optarg);
+ break;
+ case 'K':
+ tpmi_retr = atoi(optarg);
+ break;
+ case 'U':
+ updated_csi=1;
+ break;
+ case 'h':
+ default:
+ printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]);
+ printf("-h This message\n");
+ printf("-a Use AWGN channel and not multipath\n");
+ printf("-c Number of PDCCH symbols\n");
+ printf("-m MCS1 for TB 1\n");
+ printf("-M MCS2 for TB 2\n");
+ printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n");
+ printf("-p Use extended prefix mode\n");
+ printf("-n Number of frames to simulate\n");
+ printf("-o Sample offset for receiver\n");
+ printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step);
+ printf("-f step size of SNR, default value is 1.\n");
+ printf("-r resource block allocation (see section 7.1.6.3 in 36.213\n");
+ printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T'), EPA_low ('V'), EPA_medium ('W'), EPA_high ('X') \n");
+ printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n");
+ printf("-x Transmission mode (1,2,6 for the moment)\n");
+ printf("-y Number of TX antennas used in eNB\n");
+ printf("-z Number of RX antennas used in UE\n");
+ printf("-t MCS of interfering UE\n");
+ printf("-R Number of HARQ rounds (fixed)\n");
+ printf("-A Turns on calibration mode for abstraction.\n");
+ printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n");
+ printf("-O Set the percentage of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n");
+ printf("-I Input filename for TrCH data (binary)\n");
+ printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n");
+ exit(1);
+ break;
+
+ }
+ }
+
+ if (common_flag == 0) {
+ switch (N_RB_DL) {
+ case 6:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
+ num_pdcch_symbols = 3;
+ break;
+
+ case 25:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
+ break;
+
+ case 50:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;
+ break;
+
+ case 100:
+ if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;
+ break;
+ }
+
+ NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
+ } else
+ NB_RB = 4;
+
+ NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
+
+
+ if (((transmission_mode==1) || (transmission_mode==2)) && (rx_type != rx_standard)) {
+ printf("only standard rx available for TM1 and TM2\n");
+ exit(-1);
+ }
+ if (((transmission_mode==5) || (transmission_mode==6)) && (rx_type > rx_IC_single_stream)) {
+ printf("only standard rx or single stream IC available for TM5 and TM6\n");
+ exit(-1);
+ }
+
+
+ if (xforms==1) {
+ fl_initialize (&argc, argv, NULL, 0, 0);
+ form_ue = create_lte_phy_scope_ue();
+ sprintf (title, "LTE PHY SCOPE eNB");
+ fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
+
+ /*
+ if (rx_type==rx_IC_single_stream) {
+ openair_daq_vars.use_ia_receiver = 1;
+ fl_set_button(form_ue->button_0,1);
+ fl_set_object_label(form_ue->button_0, "IA Receiver ON");
+ fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
+ }
+
+ */
+ }
+
+ if (transmission_mode==5) {
+ n_users = 2;
+ eNB_id_i = UE->n_connected_eNB;
+ //eNB_id_i=1;
+ }
+ else
+ eNB_id_i = eNB_id;
+
+ lte_param_init(n_tx_port,
+ n_tx_phy,
+ n_rx,
+ transmission_mode,
+ extended_prefix_flag,
+ frame_type,
+ Nid_cell,
+ tdd_config,
+ N_RB_DL,
+ threequarter_fs,
+ osf,
+ perfect_ce);
+
+
+ printf("Setting mcs1 = %d\n",mcs1);
+ printf("Setting mcs2 = %d\n",mcs2);
+ printf("NPRB = %d\n",NB_RB);
+ printf("n_frames = %d\n",n_frames);
+ printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
+ printf("Using receiver type %d\n", rx_type);
+ printf("TM1 shift %d\n", interf_unaw_shift);
+ //printf("Using I_UA rec shift layer 1 %d\n", interf_unaw_shift0);
+ //printf("Using I_UA rec shift layer 2 %d\n", interf_unaw_shift1);
+ snr1 = snr0+snr_int;
+ printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
+
+ /*
+ txdataF = (int **)malloc16(2*sizeof(int*));
+ txdataF[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
+ txdataF[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
+
+ txdata = (int **)malloc16(2*sizeof(int*));
+ txdata[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
+ txdata[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
+ */
+
+ frame_parms = &eNB->frame_parms;
+
+
+ s_re = malloc(2*sizeof(double*)); //transmitted signal (Sent)
+ s_im = malloc(2*sizeof(double*));
+ r_re = malloc(2*sizeof(double*)); //received signal
+ r_im = malloc(2*sizeof(double*));
+ // r_re0 = malloc(2*sizeof(double*));
+ // r_im0 = malloc(2*sizeof(double*));
+
+ nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
+
+
+ printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model);
+ printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d, Rayleigh1_orthogonal=%d, Rayleigh1_orth_eff_ch_TM4_prec_real22=%d, Rayleigh1_orth_eff_ch_TM4_prec_imag=%d, Rayleigh8_orth_eff_ch_TM4_prec_real=%d, Rayleigh8_orth_eff_ch_TM4_prec_imag=%d , TS_SHIFT=%d\n",
+ SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT);
+ if(transmission_mode==5)
+ sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod);
+ else if (abstx == 1){
+ if (perfect_ce==1)
+ sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr);
+ else
+ sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr);
+ }
+ else {//abstx=0
+ if (perfect_ce==1){
+ if (updated_csi==1){
+ sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+ }
+ else{
+ sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+ }
+ }
+ else{
+ if (updated_csi==1){
+ sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+ }
+ else{
+ sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+ }
+ }
+ }
+
+ bler_fd = fopen(bler_fname,"w");
+ if (bler_fd==NULL) {
+ fprintf(stderr,"Cannot create file %s!\n",bler_fname);
+ exit(-1);
+ }
+
+ if ((transmission_mode != 3) && (transmission_mode != 4))
+ fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n");
+ else if (rx_type == rx_SIC_dual_stream)
+ fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+ else
+ fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+
+ if (test_perf != 0) {
+
+ char hostname[1024];
+
+ hostname[1023] = '\0';
+ gethostname(hostname, 1023);
+ printf("Hostname: %s\n", hostname);
+ //char dirname[FILENAME_MAX];
+ //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname );
+ sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv",
+ N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
+ //mkdir(dirname,0777);
+ time_meas_fd = fopen(time_meas_fname,"w");
+ if (time_meas_fd==NULL) {
+ fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
+ exit(-1);
+ }
+ }
+
+ if(abstx){
+ // CSV file // add here second stream mcs
+
+ if (transmission_mode == 5)
+ sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d_abstr.m",transmission_mode,rx_type,mcs1,channel_model,n_frames,num_rounds);
+
+ else
+ if (perfect_ce==1)
+ sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz);
+ else
+ sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz);
+
+ csv_fd = fopen(csv_fname,"w");
+ fprintf(csv_fd,"data_all%d=[",mcs1);
+ if (csv_fd==NULL) {
+ fprintf(stderr,"Cannot create file %s!\n",csv_fname);
+ exit(-1);
+ }
+ }
+
+ for (i=0; i<2; i++) {
+ s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ // r_re0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ // bzero(r_re0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ // r_im0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ // bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+ }
+
+ UE->pdcch_vars[0]->crnti = n_rnti;
+ UE->transmission_mode[eNB_id]=transmission_mode;
+ if (UE->transmission_mode[eNB_id] !=4)
+ UE->measurements.rank[eNB_id]=0;
+ else
+ UE->measurements.rank[eNB_id]=1;
+
+ // 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);
+
+ eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+ UE->frame_parms.nb_antennas_rx,
+ channel_model,
+ N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+ N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+ forgetting_factor,
+ rx_sample_offset,
+ 0);
+
+ if(num_rounds>1) {
+ for(n=1; n<8; n++)
+ eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+ UE->frame_parms.nb_antennas_rx,
+ channel_model,
+ N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+ N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+ forgetting_factor,
+ rx_sample_offset,
+ 0);
+ }
+
+ if (eNB2UE[0]==NULL) {
+ msg("Problem generating channel model. Exiting.\n");
+ exit(-1);
+ }
+
+ if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8))
+ Kmimo=2;
+ else
+ Kmimo=1;
+
+ switch (ue_category) {
+ case 1:
+ Nsoft = 250368;
+ break;
+ case 2:
+ case 3:
+ Nsoft = 1237248;
+ break;
+ case 4:
+ Nsoft = 1827072;
+ break;
+ default:
+ printf("Unsupported UE category %d\n",ue_category);
+ exit(-1);
+ break;
+ }
+
+ for (k=0; kdlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0, &eNB->frame_parms);
+
+ if (!eNB->dlsch[k][i]) {
+
+ printf("Can't get eNB dlsch structures\n");
+ exit(-1);
+ }
+
+ eNB->dlsch[k][i]->rnti = n_rnti+k;
+ }
+ }
+
+ for (i=0; i<2; i++) {
+ UE->dlsch[0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+
+ if (!UE->dlsch[0][i]) {
+
+ printf("Can't get ue dlsch structures\n");
+ exit(-1);
+ }
+
+ UE->dlsch[0][i]->rnti = n_rnti;
+ }
+
+ // structure for SIC at UE
+ UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0, &eNB->frame_parms);
+
+ if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
+
+ eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);
+
+ if (n_users>1)
+ eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI
+ } else {
+ eNB->UE_stats[0].DL_pmi_single = 0;
+
+ if (n_users>1)
+ eNB->UE_stats[1].DL_pmi_single = 0;
+ }
+
+
+ sic_buffer = (int32_t **) malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t *) );
+ for (i=0; inb_antennas_tx; i++) {
+ sic_buffer[i] = malloc16_clear(FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
+ }
+
+ if (input_fd==NULL) {
+
+ // UE specific DCI
+ for(k=0; kframe_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 = 1;
+ ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0;
+ 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 = 1;
+ ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0;
+ 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 = 1;
+ ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0;
+ 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 = 1;
+ ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0;
+ dci_length = sizeof_DCI1_20MHz_TDD_t;
+ dci_length_bytes = sizeof(DCI1_20MHz_TDD_t);
+ break;
+ }
+ }
+ else { //fdd
+
+ 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 = 1;
+ ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0;
+ 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 = 1;
+ ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0;
+ 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 = 1;
+ ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0;
+ 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 = 1;
+ ((DCI1_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 = n_rnti+k;
+ dci_alloc[num_dci].format = format1;
+
+ 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_ue_spec_dci++;
+ }
+ else { //common flag =1
+ 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 = 1;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 { // fdd
+ 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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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;
+ 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_dci++;
+
+ }
+ break;
+ case 3: //LARGE CDD
+ 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 = 1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((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 = 1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ 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 = 1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ 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 = 1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ 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 = 1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ dci_length = sizeof_DCI2A_20MHz_2A_TDD_t;
+ dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t);
+ break;
+ }
+ }
+
+ else { // fdd
+ 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 = 1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((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 = 1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ 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 = 1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ 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 = 1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ 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 = 1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ break;
+ }
+ }
+ }
+ else if (eNB->frame_parms.nb_antennas_tx == 4) { //4 antenna, needs diff precoding codebook index depeneding on layers
+
+
+ }
+
+ 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;
+ 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_ue_spec_dci++;
+ }
+ else { //commonn flag 1
+ if (eNB->frame_parms.frame_type == TDD) { //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 = 1;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 { //fdd
+ 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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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;
+ 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_dci++;
+
+ }
+ printf("Generated DCI format 2A (Transmission Mode 3)\n");
+ break;
+
+ case 4: // !!! this dci format contains precoder information
+ 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 = 1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((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 = 1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+ 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 = 1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+
+ 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 = 1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+
+ 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 = 1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+ 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 = 1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((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 = 1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+ 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 = 1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+ 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 = 1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+ 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 = 1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2;
+ break;
+ }
+ }
+ }
+ else if (eNB->frame_parms.nb_antennas_tx == 4) {
+
+
+ }
+
+ printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi);
+ if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) {
+
+ eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);
+
+
+ }
+
+ 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;
+ 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_ue_spec_dci++;
+ }
+ else { //common_flag==1
+ 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 = 1;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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 = 0;
+ ((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 = 1;
+ ((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;
+ 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_dci++;
+
+ }
+ break;
+
+ 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;
+ 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_dci++;
+
+ break;
+
+ default:
+ printf("Unsupported Transmission Mode!!!");
+ exit(-1);
+ break;
+ }
+
+
+
+
+ /*
+ memcpy(&dci_alloc[1].dci_pdu[0],&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD0_t));
+ dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_0_t;
+ dci_alloc[1].L = 2;
+ dci_alloc[1].rnti = n_rnti;
+ */
+ }
+
+ if (n_frames==1)
+ printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE);
+
+ numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
+
+
+ if (n_frames==1)
+ printf("%d\n",numCCE);
+
+ // apply RNTI-based nCCE allocation
+ memset(CCE_table,0,800*sizeof(int));
+
+ for (i=num_common_dci; idlsch[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>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);
+ }
+ }
+ }
+
+ snr_step = input_snr_step;
+ UE->high_speed_flag = 1;
+ UE->ch_est_alpha=0;
+
+ for (ch_realization=0; ch_realizationproc.proc_rxtx[0].frame_rx=0;
+ for (i=0; i<4; i++) {
+ errs[0][i]=0; //CW_0
+ errs[1][i]=0; //CW_1
+ decoded_in_sic[i]=0;
+ sic_attempt[i]=0;
+ resend_one[i]=0;
+ resend_both[i]=0;
+
+ round_trials[0][i] = 0; // CW_0
+ round_trials[1][i] = 0; // CW_1
+ TB0_deact[i]=0;
+ TB1_deact[i]=0;
+ }
+ dci_errors=0;
+
+ round = 0;
+
+ avg_iter[0] = 0;
+ avg_iter[1] = 0;
+ iter_trials[0]=0;
+ iter_trials[1]=0;
+
+ reset_meas(&eNB->phy_proc_tx); // total eNB tx
+ reset_meas(&eNB->dlsch_scrambling_stats);
+ reset_meas(&UE->dlsch_unscrambling_stats);
+ reset_meas(&eNB->ofdm_mod_stats);
+ reset_meas(&eNB->dlsch_modulation_stats);
+ reset_meas(&eNB->dlsch_encoding_stats);
+ reset_meas(&eNB->dlsch_interleaving_stats);
+ reset_meas(&eNB->dlsch_rate_matching_stats);
+ reset_meas(&eNB->dlsch_turbo_encoding_stats);
+
+ reset_meas(&UE->phy_proc_rx); // total UE rx
+ reset_meas(&UE->ofdm_demod_stats);
+ reset_meas(&UE->dlsch_channel_estimation_stats);
+ reset_meas(&UE->dlsch_freq_offset_estimation_stats);
+ reset_meas(&UE->rx_dft_stats);
+ reset_meas(&UE->dlsch_llr_stats);
+ reset_meas(&UE->dlsch_decoding_stats);
+ reset_meas(&UE->dlsch_turbo_decoding_stats);
+ reset_meas(&UE->dlsch_deinterleaving_stats);
+ reset_meas(&UE->dlsch_rate_unmatching_stats);
+ reset_meas(&UE->dlsch_tc_init_stats);
+ reset_meas(&UE->dlsch_tc_alpha_stats);
+ reset_meas(&UE->dlsch_tc_beta_stats);
+ reset_meas(&UE->dlsch_tc_gamma_stats);
+ reset_meas(&UE->dlsch_tc_ext_stats);
+ reset_meas(&UE->dlsch_tc_intl1_stats);
+ reset_meas(&UE->dlsch_tc_intl2_stats);
+
+ // initialization
+ struct list time_vector_tx;
+ initialize(&time_vector_tx);
+ struct list time_vector_tx_ifft;
+ initialize(&time_vector_tx_ifft);
+ struct list time_vector_tx_mod;
+ initialize(&time_vector_tx_mod);
+ struct list time_vector_tx_enc;
+ initialize(&time_vector_tx_enc);
+
+ struct list time_vector_rx;
+ initialize(&time_vector_rx);
+ struct list time_vector_rx_fft;
+ initialize(&time_vector_rx_fft);
+ struct list time_vector_rx_demod;
+ initialize(&time_vector_rx_demod);
+ struct list time_vector_rx_dec;
+ initialize(&time_vector_rx_dec);
+
+ for (trials = 0;trialsnb_antennas_tx; i++) {
+ memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
+ }
+
+ eNB2UE[0]->first_run = 1;
+
+ ret[0] = UE->dlsch[0][0]->max_turbo_iterations+1;
+ ret[1] = UE->dlsch[0][0]->max_turbo_iterations+1;
+
+ resend_cw0_cw1=1;
+ resend_cw1=0;
+ TB0_active=1;
+ TB1_active=1;
+
+ while (((transmission_mode == 3 || transmission_mode == 4) &&
+ ((round < num_rounds) && ((ret[0] > UE->dlsch[0][0]->max_turbo_iterations) ||
+ (ret[1] > UE->dlsch[0][0]->max_turbo_iterations)))) ||
+ ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) &&
+ (ret[0] > UE->dlsch[0][0]->max_turbo_iterations)))) {
+#ifdef DEBUG_HARQ
+ printf("\n [DLSIM] On top round is %d\n", round);
+#endif
+
+
+ round_trials[0][round]++;
+ round_trials[1][round]++;
+
+ //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]);
+
+ /*if (ret[0] > UE->dlsch[0][0]->max_turbo_iterations) {
+ round_trials[0][round]++;
+ round_trials[1][round]++;
+ } else if ((ret[1] > UE->dlsch[0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[0][0]->max_turbo_iterations))
+ round_trials[1][round]++;*/
+
+
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] Just after while loop TB0 status %d TB1 status %d round %d\n", TB0_active, TB1_active, round);
+#endif
+
+ // printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials TB0 = %d, round_trials TB1 = %d \n",trials,round, ret[0], ret[1], round_trials[0][round], round_trials[1][round]);
+
+
+ /*printf("Trial %d, round cw0 = %d , round cw1 = %d, ret[0] = %d, ret[1] = %d, round_trials cw0 [%d]= %d, round_trials cw1 [%d]= %d\n",trials, round, round, \
+ ret[0], ret[1], round, round_trials[0][round], round, round_trials[1][round]);*/
+
+ //printf("round_trials %d round %d\n", round_trials[round], round);
+
+ if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6)
+ pmi_feedback=1;
+ else
+ pmi_feedback=0;
+
+ if (abstx) {
+ if (trials==0 && round==0 && SNR==snr0) //generate a new channel
+ hold_channel = 0;
+ else
+ hold_channel = 1;
+ }
+ else
+ hold_channel = 0;//(round==0) ? 0 : 1;
+
+ PMI_FEEDBACK:
+
+ //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
+ for (aa=0; aaframe_parms.nb_antennas_tx;aa++) {
+ memset(&eNB->common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
+ }
+
+ if (input_fd==NULL) {
+
+ start_meas(&eNB->phy_proc_tx);
+
+ // Simulate HARQ procedures!!!
+ if (common_flag == 0) {
+
+ eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
+ if (transmission_mode == 3 || transmission_mode == 4)
+ eNB->dlsch[0][1]->harq_processes[0]->rvidx = round&3;
+
+ if (round == 0) { // First round
+ TB0_active = 1;
+ TB1_active = 1;
+
+ if (eNB->frame_parms.frame_type == TDD) {
+
+ switch (transmission_mode) {
+ case 1:
+ case 2:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t));
+ break;
+ case 25:
+ ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t));
+ break;
+ case 50:
+ ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t));
+ break;
+ case 100:
+ ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t));
+ break;
+ }
+ break;
+ case 3:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t));
+ break;
+ case 25:
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t));
+ break;
+ case 50:
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t));
+ break;
+ case 100:
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t));
+ break;
+ }
+ break;
+ case 4:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+ break;
+ case 25:
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+ break;
+ case 50:
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+ break;
+ case 100:
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+ break;
+ }
+ break;
+ case 5:
+ case 6:
+ DLSCH_alloc_pdu2_1E[0].ndi = trials&1;
+ DLSCH_alloc_pdu2_1E[0].rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+ break;
+ }
+ }
+ else { // FDD
+ switch (transmission_mode) {
+ case 1:
+ case 2:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t));
+ break;
+ case 25:
+ ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t));
+ break;
+ case 50:
+ ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t));
+ break;
+ case 100:
+ ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t));
+ break;
+ }
+ break;
+ case 3:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t));
+ break;
+ case 25:
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t));
+ break;
+ case 50:
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t));
+ break;
+ case 100:
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t));
+ break;
+ }
+ break;
+ case 4:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
+ break;
+ case 25:
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+ break;
+ case 50:
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+ break;
+ case 100:
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+ break;
+ }
+ break;
+ case 5:
+ case 6:
+ DLSCH_alloc_pdu2_1E[0].ndi = trials&1;
+ DLSCH_alloc_pdu2_1E[0].rv = 0;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+ break;
+ }
+ }
+ }
+ else {
+
+ if (eNB->frame_parms.frame_type == TDD) {
+ switch (transmission_mode) {
+ case 1:
+ case 2:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t));
+ break;
+ case 25:
+ ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t));
+ break;
+ case 50:
+ ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t));
+ break;
+ case 100:
+ ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t));
+ break;
+ }
+ break;
+ case 3:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0) { // deactivate TB0
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t));
+ break;
+ case 25:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0) { // deactivate TB0
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t));
+ break;
+ case 50:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t));
+ break;
+ case 100:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t));
+ break;
+ }
+ break;
+ case 4:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+ break;
+ case 25:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+#ifdef DEBUG_HARQ
+ printf("\n[DLSIM] Requesting only TB1 from temp DCI\n");
+#endif
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+#ifdef DEBUG_HARQ
+ printf("\n[DLSIM] TDD Requesting only TB0 from temp DCI\n");
+#endif
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+ 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,
+ UE->dlsch[0][1]->pmi_alloc,
+ transmission_mode>=7?transmission_mode:0
+ );
+ break;
+ case 50:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+ break;
+ case 100:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+ break;
+ }
+ break;
+
+ case 5:
+ case 6:
+ DLSCH_alloc_pdu2_1E[0].ndi = trials&1;
+ DLSCH_alloc_pdu2_1E[0].rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+ break;
+ }
+ }
+ else {
+ switch (transmission_mode) {
+ case 1:
+ case 2:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t));
+ break;
+ case 25:
+ ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t));
+ break;
+ case 50:
+ ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t));
+ break;
+ case 100:
+ ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1;
+ ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t));
+ break;
+ }
+ break;
+ case 3:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ if (TB0_active==1) {
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB0
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t));
+ break;
+ case 25:
+ if (TB0_active==1) {
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB0
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t));
+ break;
+ case 50:
+ if (TB0_active==1) {
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB0
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t));
+ break;
+ case 100:
+ if (TB0_active==1) {
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB0
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t));
+ break;
+ }
+ break;
+ case 4:
+ switch (eNB->frame_parms.N_RB_DL) {
+ case 6:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
+ break;
+ case 25:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+#ifdef DEBUG_HARQ
+ printf("\n [DLSIM] Requesting only TB1 from temp DCI\n");
+#endif
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+#ifdef DEBUG_HARQ
+ printf("\n[DLSIM] FDD Requesting only TB0 from temp DCI\n");
+#endif
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+ 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,
+ UE->dlsch[0][1]->pmi_alloc,
+ transmission_mode>=7?transmission_mode:0
+ );
+ break;
+ case 50:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0) { // deactivate TB0
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+ break;
+ case 100:
+ if (TB0_active == 1 && TB1_active == 1) {
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else if (TB0_active == 0){ // deactivate TB0
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3;
+ }
+ else { // deactivate TB1
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3;
+ ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0;
+ ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1;
+ }
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+ break;
+ }
+ break;
+
+
+ case 5:
+ case 6:
+ DLSCH_alloc_pdu2_1E[0].ndi = trials&1;
+ DLSCH_alloc_pdu2_1E[0].rv = round&3;
+ memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+ break;
+ }
+ }
+ }
+ }
+ num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci,
+ num_common_dci,
+ dci_alloc,
+ 0,
+ AMP,
+ &eNB->frame_parms,
+ eNB->common_vars.txdataF[eNB_id],
+ subframe);
+
+ if (num_pdcch_symbols_2 > num_pdcch_symbols) {
+ msg("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols);
+ exit(-1);
+ }
+
+ for (k=0;kframe_parms,
+ eNB->dlsch[k][TB]->harq_processes[0]->nb_rb,
+ eNB->dlsch[k][TB]->harq_processes[0]->rb_alloc,
+ get_Qm(eNB->dlsch[k][TB]->harq_processes[0]->mcs),
+ eNB->dlsch[k][TB]->harq_processes[0]->Nl,
+ num_pdcch_symbols,
+ 0,subframe,
+ transmission_mode>=7?transmission_mode:0);
+ #ifdef TBS_FIX // This is for MESH operation!!!
+ tbs[TB] = (double)3*TBStable[get_I_TBS(eNB->dlsch[k][TB]->harq_processes[0]->mcs)][eNB->dlsch[k][TB]->nb_rb-1]/4;
+ #else
+ tbs[TB] = eNB->dlsch[k][TB]->harq_processes[0]->TBS;
+ #endif
+
+ rate[TB] = (double)tbs[TB]/(double)coded_bits_per_codeword[TB];
+
+ if ((SNR == snr0) && (trials == 0) && (round == 0) && (pmi_feedback == 0))
+ printf("User %d, TB %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n",
+ k,TB,rate[TB],rate[TB]*get_Qm(eNB->dlsch[k][TB]->harq_processes[0]->mcs),
+ coded_bits_per_codeword[TB],
+ tbs[TB],
+ get_Qm(eNB->dlsch[k][TB]->harq_processes[0]->mcs),
+ num_pdcch_symbols,
+ eNB->dlsch[k][TB]->harq_processes[0]->round);
+
+ // use the PMI from previous trial
+ if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
+ eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
+ UE->dlsch[0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+ if (n_users>1)
+ eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555);
+ /*
+ if ((trials<10) && (round==0)) {
+ printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(eNB->dlsch[0][0]->pmi_alloc),pmi_feedback);
+ if (transmission_mode ==5)
+ printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(eNB->dlsch[1][0]->pmi_alloc));
+ }
+ */
+ }
+
+ //if standard case when both TBs are active
+ if (transmission_mode == 4) {
+ if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) && TB0_active == 1 && TB1_active == 1){
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I am calling from the eNode B 1\n");
+#endif
+
+ eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I am calling from the eNode B 2\n");
+#endif
+
+ UE->dlsch[0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+ }
+
+ else if (updated_csi == 0){
+
+ if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I am calling from the eNode B 1\n");
+#endif
+ eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,5,eNB->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I am calling from the eNode B 2\n");
+#endif
+ UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
+ }
+
+ else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I am calling from the eNode B 1\n");
+#endif
+ eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,6,eNB->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I am calling from the eNode B 2\n");
+#endif
+ UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
+ }
+ } else if (updated_csi == 1){
+
+ if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] Updating CSI\n");
+ printf ("[DLSIM] I quantize from ENodeB 1\n");
+#endif
+
+ eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n");
+#endif
+ eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,5,eNB->frame_parms.N_RB_DL);
+
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I quantize from ENodeB 2\n");
+#endif
+ UE->dlsch[0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n");
+#endif
+ UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
+ }
+ else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] Updating CSI\n");
+ printf ("[DLSIM] I quantize from ENodeB 1\n");
+#endif
+
+ eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n");
+#endif
+ eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,6,eNB->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I quantize from ENodeB 2\n");
+#endif
+ UE->dlsch[0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n");
+#endif
+ UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
+ }
+
+ }
+ }
+
+ start_meas(&eNB->dlsch_encoding_stats);
+ if (dlsch_encoding(eNB,
+ (TB==0) ? input_buffer0[k] : input_buffer1[k],
+ num_pdcch_symbols,
+ eNB->dlsch[k][TB],
+ 0,
+ subframe,
+ &eNB->dlsch_rate_matching_stats,
+ &eNB->dlsch_turbo_encoding_stats,
+ &eNB->dlsch_interleaving_stats)<0)
+ exit(-1);
+
+ stop_meas(&eNB->dlsch_encoding_stats);
+
+ eNB->dlsch[k][TB]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI;
+ start_meas(&eNB->dlsch_scrambling_stats);
+ dlsch_scrambling(&eNB->frame_parms,
+ 0,
+ eNB->dlsch[k][TB],
+ coded_bits_per_codeword[TB],
+ TB,
+ subframe<<1);
+ stop_meas(&eNB->dlsch_scrambling_stats);
+
+ if (n_frames==2) {
+ for (s=0;sdlsch[k][TB]->harq_processes[0]->C;s++) {
+ if (sdlsch[k][TB]->harq_processes[0]->Cminus)
+ Kr = eNB->dlsch[k][TB]->harq_processes[0]->Kminus;
+ else
+ Kr = eNB->dlsch[k][TB]->harq_processes[0]->Kplus;
+ Kr_bytes = Kr>>3;
+ }
+ }
+ }
+
+ start_meas(&eNB->dlsch_modulation_stats);
+ re_allocated = dlsch_modulation(eNB,
+ eNB->common_vars.txdataF[eNB_id],
+ AMP,
+ subframe,
+ num_pdcch_symbols,
+ ((TB0_active == 1)? eNB->dlsch[k][0]: NULL),
+ ((TB1_active == 1)? eNB->dlsch[k][1]: NULL));
+ stop_meas(&eNB->dlsch_modulation_stats);
+ } //n_users
+
+
+ if (((transmission_mode == 3) || (transmission_mode == 4)) && (SNR == snr0) && (trials == 0) && (round == 0)){
+ rate0_init = rate[0];
+ rate1_init = rate[1];
+ tbs0_init=tbs[0];
+ tbs1_init=tbs[1];
+ mod_order0_init=get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs);
+ mod_order1_init=get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs);
+ mcs0_init=eNB->dlsch[0][0]->harq_processes[0]->mcs;
+ mcs1_init=eNB->dlsch[0][1]->harq_processes[0]->mcs;
+ }
+
+ generate_pilots(eNB,
+ eNB->common_vars.txdataF[eNB_id],
+ AMP,
+ LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
+
+ 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);
+
+ stop_meas(&eNB->ofdm_mod_stats);
+ stop_meas(&eNB->phy_proc_tx);
+
+ do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
+ eNB->common_vars.txdata[eNB_id],
+ (subframe*2)+2,
+ &eNB->frame_parms);
+
+ if (n_frames==1) {
+ 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);
+ if (eNB->frame_parms.nb_antennas_tx>1)
+ write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+ }
+
+ tx_lev = 0;
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+ tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa]
+ [subframe*eNB->frame_parms.samples_per_tti],
+ eNB->frame_parms.samples_per_tti);
+ }
+ tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
+
+ if (n_frames==1) {
+ 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);
+ if (eNB->frame_parms.nb_antennas_tx>1)
+ write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+ }
+
+ tx_lev = 0;
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+ tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa]
+ [subframe*eNB->frame_parms.samples_per_tti],
+ eNB->frame_parms.samples_per_tti);
+ }
+ tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
+
+ if (n_frames==2) {
+ 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);
+ }
+ }
+ // 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*frame_parms->samples_per_tti;i++) {
+ for (aa=0;aaframe_parms.nb_antennas_tx;aa++) {
+ if (awgn_flag == 0) {
+ s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
+ s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+ }
+ else {
+ if (transmission_mode==4) {
+ r_re[0][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][0]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)])+((double)(((short *)eNB->common_vars.txdata[eNB_id][1]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+ r_im[0][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][0]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)eNB->common_vars.txdata[eNB_id][1]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+
+ r_re[1][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][0]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)eNB->common_vars.txdata[eNB_id][1]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+ r_im[1][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][0]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)eNB->common_vars.txdata[eNB_id][1]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+ //printf("r_re0 = %d\n",r_re[0][i]);
+ //printf("r_im0 = %d\n",r_im[0][i]);
+ //printf("r_re1 = %d\n",r_re[1][i]);
+ //printf("r_im1 = %d\n",r_im[1][i]);
+
+ }
+ else {
+ for (aarx=0;aarxframe_parms.nb_antennas_rx;aarx++) {
+ if (aa==0) {
+ r_re[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+ r_im[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+ }
+ else {
+ r_re[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+ r_im[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Multipath channel
+ if (awgn_flag == 0) {
+ multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
+ 2*frame_parms->samples_per_tti,hold_channel);
+ // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
+ if(abstx==1 && num_rounds>1)
+ if(round==0 && hold_channel==0){
+ random_channel(eNB2UE[1],0);
+ random_channel(eNB2UE[2],0);
+ random_channel(eNB2UE[3],0);
+ }
+ if (UE->perfect_ce==1){
+ freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
+ // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8);
+ // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL +1,1,8);
+ }
+ }
+
+ // freq_channel(eNB2UE[0], NB_RB,12*NB_RB + 1);
+ if(abstx){
+ if (trials==0 && round==0) {
+ // calculate freq domain representation to compute SINR
+ freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1);
+ // snr=pow(10.0,.1*SNR);
+ fprintf(csv_fd,"%f,",SNR);
+
+ for (u=0;u<2*NB_RB;u++){
+ for (aarx=0;aarxnb_rx;aarx++) {
+ for (aatx=0;aatxnb_tx;aatx++) {
+ channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x;
+ channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+
+ if(num_rounds>1){
+ freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1);
+
+ for (u=0;u<2*NB_RB;u++){
+ for (aarx=0;aarxnb_rx;aarx++) {
+ for (aatx=0;aatxnb_tx;aatx++) {
+ channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x;
+ channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+ freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1);
+
+ for (u=0;u<2*NB_RB;u++){
+ for (aarx=0;aarxnb_rx;aarx++) {
+ for (aatx=0;aatxnb_tx;aatx++) {
+ channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x;
+ channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+
+ freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1);
+
+ for (u=0;u<2*NB_RB;u++){
+ for (aarx=0;aarxnb_rx;aarx++) {
+ for (aatx=0;aatxnb_tx;aatx++) {
+ channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x;
+ channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y;
+ fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //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 = pow(10,sigma2_dB/10);
+ if (n_frames==1)
+ printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(eNB->pdsch_config_dedicated));
+
+ for (i=0; i<2*frame_parms->samples_per_tti; i++) {
+ for (aa=0;aaframe_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));
+ ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
+ (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+ }
+ }
+
+ // lte_sync_time_init(eNB->frame_parms,common_vars);
+ // lte_sync_time(common_vars->rxdata, eNB->frame_parms);
+ // lte_sync_time_free();
+
+ /*
+ // optional: read rx_frame from file
+ if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL)
+ {
+ printf("Cannot open rx_frame.m data file\n");
+ exit(0);
+ }
+
+ result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file);
+ printf("Read %d bytes\n",result);
+ result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file);
+ printf("Read %d bytes\n",result);
+
+ fclose(rx_frame_file);
+ */
+
+ if (n_frames==1) {
+ printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
+ printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
+ printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
+ printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
+ }
+
+ if (eNB->frame_parms.Ncp == 0) { // normal prefix
+ pilot1 = 4;
+ pilot2 = 7;
+ pilot3 = 11;
+ }
+ else { // extended prefix
+ pilot1 = 3;
+ pilot2 = 6;
+ pilot3 = 9;
+ }
+
+ start_meas(&UE->phy_proc_rx);
+ // Inner receiver scheduling for 3 slots
+ for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) {
+ for (l=0;lofdm_demod_stats);
+ slot_fep(UE,
+ l,
+ Ns%20,
+ 0,
+ 0,
+ 0);
+
+ stop_meas(&UE->ofdm_demod_stats);
+
+ if (UE->perfect_ce==1) {
+
+ if (awgn_flag==0) {
+ for(k=0; knb_antennas_tx; aa++) {
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ for (i=0; iN_RB_DL*12; i++) {
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
+ (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
+ (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
+ }
+ }
+ }
+ }
+ }else {
+ if (transmission_mode==4) {
+ for (i=0; iN_RB_DL*12; i++) {
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP);
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+ }
+ } else {
+ for(aa=0; aanb_antennas_tx; aa++) {
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ for (i=0; iN_RB_DL*12; i++) {
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+ ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ((Ns==((2*subframe))) && (l==0)) {
+ lte_ue_measurements(UE,
+ subframe*UE->frame_parms.samples_per_tti,
+ 1,
+ 0,
+ subframe);
+ //printf ("Trial %d, Measurements are done \n", trials);
+ /*
+ debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
+ UE->measurements.rx_rssi_dBm[0] - ((UE->frame_parms.nb_antennas_rx==2) ? 3 : 0),
+ UE->measurements.wideband_cqi_dB[0][0],
+ UE->measurements.wideband_cqi_dB[0][1],
+ UE->measurements.wideband_cqi[0][0],
+ UE->measurements.wideband_cqi[0][1],
+ UE->measurements.rx_power_avg_dB[0],
+ UE->measurements.rx_power_avg[0],
+ UE->rx_total_gain_dB);
+ debug_msg("N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n",
+ UE->measurements.n0_power_tot_dBm,
+ UE->measurements.n0_power_dB[0],
+ UE->measurements.n0_power_dB[1],
+ UE->measurements.n0_power[0],
+ UE->measurements.n0_power[1],
+ UE->measurements.n0_power_avg_dB,
+ UE->measurements.n0_power_avg);
+ debug_msg("Wideband CQI tot %d dB, wideband cqi avg %d dB\n",
+ UE->measurements.wideband_cqi_tot[0],
+ UE->measurements.wideband_cqi_avg[0]);
+ */
+
+ if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) {
+ if (pmi_feedback == 1) {
+ pmi_feedback = 0;
+ hold_channel = 1;
+
+ if (updated_csi==0) {
+ if (hold_rank1_precoder == 0)
+ hold_rank1_precoder = 1;
+ }
+ //printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback);
+ //printf ("go to PMI feedback\n");
+#ifdef DEBUG_HARQ
+ printf ("[DLSIM] I am doing measurements and coming back to reencoding\n");
+#endif
+ goto PMI_FEEDBACK;
+ }
+ }
+
+ }
+
+
+ if ((Ns==(2*subframe)) && (l==pilot1)) {// process symbols 0,1,2
+ if (dci_flag == 1) {
+ UE->UE_mode[0] = PUSCH;
+ start_meas(&UE->dlsch_rx_pdcch_stats);
+
+ rx_pdcch(&UE->common_vars,
+ UE->pdcch_vars,
+ &UE->frame_parms,
+ trials,
+ subframe,
+ 0,
+ (UE->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
+ UE->high_speed_flag,
+ UE->is_secondary_ue);
+
+ stop_meas(&UE->dlsch_rx_pdcch_stats);
+ // overwrite number of pdcch symbols
+ UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols;
+
+ dci_cnt = dci_decoding_procedure(UE,
+ dci_alloc_rx,1,
+ eNB_id,
+ subframe);
+ printf("dci_cnt %d\n",dci_cnt);
+
+ if (dci_cnt==0) {
+ dlsch_active = 0;
+ if (round==0) {
+ dci_errors++;
+
+ round=5; // this is meant to stop the "while" loop if DCI is wrong;
+ errs[0][0]++;
+
+ if (n_frames==2)
+ printf("DCI error trial %d errs[0][0] %d\n",trials,errs[0][0]);
+ }
+ }
+
+ for (i=0;idlsch[0][0]->harq_processes[0]->first_tx=1;
+ }
+ if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) {
+ UE->dlsch[0][1]->harq_processes[0]->first_tx=1;
+ }
+
+ if ((dci_alloc_rx[i].rnti == n_rnti) &&
+ (generate_ue_dlsch_params_from_dci(0,
+ subframe,
+ dci_alloc_rx[i].dci_pdu,
+ dci_alloc_rx[i].rnti,
+ dci_alloc_rx[i].format,
+ UE->dlsch[0],
+ &UE->frame_parms,
+ UE->pdsch_config_dedicated,
+ SI_RNTI,
+ 0,
+ P_RNTI,
+ transmission_mode<7?0:transmission_mode,
+ UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0)==0)) {
+ dump_dci(&UE->frame_parms,&dci_alloc_rx[i]);
+ coded_bits_per_codeword[0]= get_G(&eNB->frame_parms,
+ UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->nb_rb,
+ UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->rb_alloc_even,
+ get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs),
+ UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->Nl,
+ UE->pdcch_vars[0]->num_pdcch_symbols,
+ 0,
+ subframe,
+ transmission_mode>=7?transmission_mode:0);
+ if (transmission_mode == 3 || transmission_mode == 4) {
+ coded_bits_per_codeword[1]= get_G(&eNB->frame_parms,
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->nb_rb,
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->rb_alloc_even,
+ get_Qm(UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs),
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->Nl,
+ UE->pdcch_vars[1]->num_pdcch_symbols,
+ 0,
+ subframe,
+ transmission_mode>=7?transmission_mode:0);
+ }
+ /*
+ rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs)][UE->dlsch[0][0]->nb_rb-1]/(coded_bits_per_codeword);
+ rate*=get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs);
+ */
+ printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->TBS);
+
+ dlsch_active = 1; // what does it indicates???
+ } else {
+ dlsch_active = 0;
+ if (round==0) {
+ dci_errors++;
+ errs[0][0]++;
+ //round_trials[0]++;
+ round=5;
+
+ if (n_frames==1)
+ printf("DCI misdetection trial %d\n",trials);
+
+ }
+ // for (i=1;i<=round;i++)
+ // round_trials[i]--;
+ // round=5;
+ }
+ }
+ } else { //dci_flag == 0
+ UE->pdcch_vars[0]->crnti = n_rnti;
+ UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols;
+ if (round == 0) {
+ UE->dlsch[0][0]->harq_processes[0]->first_tx=1;
+ UE->dlsch[0][1]->harq_processes[0]->first_tx=1;
+ }
+
+ switch (transmission_mode) {
+ case 1:
+ case 2:
+ generate_ue_dlsch_params_from_dci(0,
+ subframe,
+ &DLSCH_alloc_pdu_1[0],
+ (common_flag==0)? C_RNTI : SI_RNTI,
+ (common_flag==0)? format1 : format1A,
+ UE->dlsch[0],
+ &UE->frame_parms,
+ UE->pdsch_config_dedicated,
+ SI_RNTI,
+ 0,
+ P_RNTI,
+ transmission_mode<7?0:transmission_mode,
+ UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0);
+ break;
+ case 3:
+
+ //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx);
+
+ generate_ue_dlsch_params_from_dci(0,
+ subframe,
+ &DLSCH_alloc_pdu_1[0],
+ (common_flag==0)? C_RNTI : SI_RNTI,
+ (common_flag==0)? format2A : format1A,
+ UE->dlsch[0],
+ &UE->frame_parms,
+ UE->pdsch_config_dedicated,
+ SI_RNTI,
+ 0,
+ P_RNTI,
+ transmission_mode<7?0:transmission_mode,
+ UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0);
+ //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx);
+ break;
+ case 4:
+ generate_ue_dlsch_params_from_dci(0,
+ subframe,
+ &DLSCH_alloc_pdu_1[0],
+ (common_flag==0)? C_RNTI : SI_RNTI,
+ (common_flag==0)? format2 : format1A,//format1A only for a codeblock
+ UE->dlsch[0],
+ &UE->frame_parms,
+ UE->pdsch_config_dedicated,
+ SI_RNTI,
+ 0,
+ P_RNTI,
+ transmission_mode<7?0:transmission_mode,
+ UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0);
+
+ break;
+ case 5:
+ case 6:
+ generate_ue_dlsch_params_from_dci(0,
+ subframe,
+ &DLSCH_alloc_pdu2_1E[0],
+ C_RNTI,
+ format1E_2A_M10PRB,
+ UE->dlsch[0],
+ &UE->frame_parms,
+ UE->pdsch_config_dedicated,
+ SI_RNTI,
+ 0,
+ P_RNTI,
+ transmission_mode<7?0:transmission_mode,
+ UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0);
+ break;
+ }
+ dlsch_active = 1;
+ } // if dci_flag == 1
+ }
+
+ if (dlsch_active == 1) {
+ if (TB0_active==1)
+ cur_harq_pid =UE->dlsch[0][0]->current_harq_pid;
+ else
+ cur_harq_pid =UE->dlsch[0][1]->current_harq_pid;
+
+ if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix
+ /* if (transmission_mode == 5) {
+ if ((UE->dlsch[eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) &&
+ (openair_daq_vars.use_ia_receiver ==1)) {
+ rx_type = rx_IC_single_stream;
+ } else {
+ rx_type = rx_standard;
+ }
+ }*/
+
+
+ start_meas(&UE->dlsch_llr_stats);
+
+ for (m=UE->pdcch_vars[0]->num_pdcch_symbols; mpdcch_vars[0]->num_pdcch_symbols)?1:0,
+ rx_type,
+ i_mod,
+ UE->dlsch[0][0]->current_harq_pid)==-1){
+ dlsch_active = 0;
+ break;
+ }
+ }
+ stop_meas(&UE->dlsch_llr_stats);
+ }
+
+ if ((Ns==(1+(2*subframe))) && (l==pilot1)){// process symbols (6 Extended Prefix),7,8,9
+ start_meas(&UE->dlsch_llr_stats);
+ for (m=pilot2;mdlsch_llr_stats);
+ }
+
+ if ((Ns==(2+(2*subframe))) && (l==0)) { // process symbols 10,11,(12,13 Normal Prefix) do deinterleaving for TTI
+ start_meas(&UE->dlsch_llr_stats);
+ for (m=pilot3; mframe_parms.symbols_per_tti; m++) {
+ if (rx_pdsch(UE,
+ PDSCH,
+ eNB_id,
+ eNB_id_i,
+ 0,
+ subframe,
+ m,
+ 0,
+ rx_type,
+ i_mod,
+ cur_harq_pid)==-1) {
+ dlsch_active=0;
+ break;
+ }
+ }
+ stop_meas(&UE->dlsch_llr_stats);
+ }
+ }
+ }
+ }
+
+ //saving PMI in case of Transmission Mode > 5
+
+ if(abstx){
+ if (trials==0 && round==0 && transmission_mode>=4){
+ for (iii=0; iiipdsch_vars[eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id_i]->pmi_ext[iii]));
+ fprintf(csv_fd,"%x,",(UE->pdsch_vars[subframe&0x1][eNB_id]->pmi_ext[iii]));
+ //printf("%x ",(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
+ }
+ }
+ }
+
+
+ for (TB=0; TBdlsch[0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+ coded_bits_per_codeword[TB] = get_G(&eNB->frame_parms,
+ eNB->dlsch[0][TB]->harq_processes[0]->nb_rb,
+ eNB->dlsch[0][TB]->harq_processes[0]->rb_alloc,
+ get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs),
+ eNB->dlsch[0][TB]->harq_processes[0]->Nl,
+ num_pdcch_symbols,
+ 0,subframe,
+ transmission_mode>=7?transmission_mode:0);
+
+ UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB];
+ UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs);
+
+ if (n_frames==2) {
+ printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB],
+ UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->TBS);
+
+ // calculate uncoded BER
+ uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]);
+
+ AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL");
+
+ sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB);
+ sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB);
+ write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0);
+ sprintf(fname,"dlsch_cw%d_e.m", TB);
+ sprintf(vname,"dlschcw%d_e", TB);
+ write_output(fname, vname,eNB->dlsch[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4);
+ uncoded_ber=0;
+ printf("trials=%d\n", trials);
+
+ for (i=0;idlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword][i]<0)) {
+ uncoded_ber_bit[i] = 1;
+ uncoded_ber++;
+ }
+ else
+ uncoded_ber_bit[i] = 0;
+
+ uncoded_ber/=coded_bits_per_codeword[TB];
+ avg_ber += uncoded_ber;
+ sprintf(fname,"cw%d_uncoded_ber_bit.m", TB);
+ sprintf(vname,"uncoded_ber_bit_cw%d", TB);
+ write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[TB],1,0);
+ printf("cw %d, uncoded ber %f\n",TB,uncoded_ber);
+
+ free(uncoded_ber_bit);
+ uncoded_ber_bit = NULL;
+
+ }
+
+ start_meas(&UE->dlsch_unscrambling_stats);
+ dlsch_unscrambling(&UE->frame_parms,
+ 0,
+ UE->dlsch[0][TB],
+ coded_bits_per_codeword[TB],
+ UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword],
+ TB,
+ subframe<<1);
+ stop_meas(&UE->dlsch_unscrambling_stats);
+
+ start_meas(&UE->dlsch_decoding_stats);
+ ret[TB] = dlsch_decoding(UE,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword],
+ &UE->frame_parms,
+ UE->dlsch[0][TB],
+ UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid],
+ 0,
+ subframe,
+ UE->dlsch[0][TB]->current_harq_pid,
+ 1,llr8_flag);
+ stop_meas(&UE->dlsch_decoding_stats);
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] ret[%d] = %d\n", TB, ret[TB]);
+#endif
+
+ //printf("retr cw 0 = %d\n", ret[0]);
+ //printf("current round = %d\n", UE->dlsch[0][cw_non_sic]->harq_processes[UE->dlsch[0][cw_non_sic]->current_harq_pid]->round);
+
+
+
+ if (ret[TB] <= UE->dlsch[0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] TB%d is decoded\n", TB);
+#endif
+
+ /*avg_iter[TB] += ret[TB];
+ iter_trials[TB]++;*/
+
+ if (n_frames==2) {
+ printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber);
+#ifdef PRINT_BYTES
+ for (s=0;sdlsch[0][TB]->harq_processes[0]->C;s++) {
+ if (sdlsch[0][TB]->harq_processes[0]->Cminus)
+ Kr = UE->dlsch[0][TB]->harq_processes[0]->Kminus;
+ else
+ Kr = UE->dlsch[0][TB]->harq_processes[0]->Kplus;
+
+ Kr_bytes = Kr>>3;
+
+ printf("Decoded_output (Segment %d):\n",s);
+ for (i=0;idlsch[0][TB]->harq_processes[0]->c[s][i],
+ UE->dlsch[0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
+ }
+#endif
+ }
+
+ UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[eNB_id][TB]->harq_processes[UE->dlsch[eNB_id][TB]->current_harq_pid]->TBS;
+
+ // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER
+ //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained)
+ if (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC
+ /*
+ //for (round = 0 ; round < UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->round ; round++) {
+ // we assume here that the second stream has a lower MCS and is thus more likely to be decoded
+ // re-encoding of second stream
+ dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+ dlsch0_eNB_harq = UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+
+ dlsch0_eNB_harq->mimo_mode = LARGE_CDD;
+ dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0];
+ dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb;
+ dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs;
+ dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx;
+ dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl;
+ dlsch0_eNB_harq->round = dlsch0_ue_harq->round;
+
+ dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS;
+ dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
+ dlsch0_eNB_harq->status = dlsch0_ue_harq->status;
+
+ UE->dlsch[eNB_id]->active = UE->dlsch[eNB_id][0]->active;
+ UE->dlsch[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti;
+ UE->dlsch[eNB_id]->current_harq_pid = UE->dlsch[eNB_id][0]->current_harq_pid;
+
+ dlsch_encoding(UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b,
+ &UE->frame_parms,
+ num_pdcch_symbols,
+ UE->dlsch[eNB_id],
+ 0,subframe,
+ &UE->dlsch_rate_matching_stats,
+ &UE->dlsch_turbo_encoding_stats,
+ &UE->dlsch_interleaving_stats
+ );
+
+ coded_bits_per_codeword = get_G(&UE->frame_parms,
+ UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->nb_rb,
+ UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->rb_alloc,
+ get_Qm(UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->mcs),
+ UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->Nl,
+ num_pdcch_symbols,
+ 0,subframe);
+
+
+ //scrambling
+ dlsch_scrambling(&UE->frame_parms,
+ 0,
+ UE->dlsch[eNB_id],
+ coded_bits_per_codeword,
+ 0,
+ subframe<<1);
+
+
+ //modulation
+ re_allocated = dlsch_modulation(sic_buffer,
+ AMP,
+ subframe,
+ &UE->frame_parms,
+ num_pdcch_symbols,
+ &UE->dlsch[0][0],
+ NULL);
+ // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding
+ // precoding is contained in effective channel estimate
+ // compute the norm of the effective channel for both receive antennas -> alphha[0], alphha[2]
+ // multiply with the norm of the effective channnel
+ */
+
+ //stripping (from matched filter output of first stream = rxdataF_comp0)
+ // this is pseudocode
+ /*
+ for (i=0; inb_antennas_rx; i++) {
+ UE->pdsch_vars[eNB_id].rxdataF_ext[i] -= alpha[i].*sic_buffer[i];
+ }
+ */
+
+ //apply rho to output
+ /*
+ dlsch_channel_compensation(UE->pdsch_vars[eNB_id].rxdataF_ext,
+ UE->pdsch_vars[eNB_id].dl_ch_rho_ext[harq_pid][round],
+ UE->pdsch_vars[eNB_id]->dl_ch_mag1,
+ UE->pdsch_vars[eNB_id]->dl_ch_magb1,
+ UE->pdsch_vars[eNB_id]->rxdataF_comp1,
+ NULL,
+ frame_parms,
+ symbol,
+ first_symbol_flag,
+ i_mod,
+ nb_rb,
+ pdsch_vars[eNB_id]->log2_maxh,
+ phy_measurements); // log2_maxh+I0_shift
+ */
+
+
+ //detection of second stream
+ //}
+
+ }
+
+
+ if ((UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+ (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) &&
+ (rx_type==rx_SIC_dual_stream)) {
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] Starting SIC procedure\n");
+#endif
+ // printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round);
+
+
+ //printf("\n CW 0 is decoded, i go for , round %d\n", round);
+ //printf("\n ret[TB0] = %d round %d\n", ret[TB], round);
+ sic_attempt[round]++;
+
+ for (round_sic = 0 ; round_sic < (round +1); round_sic++) {
+
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] 0 Round sic = %d\n", round_sic);
+#endif
+ //printf("I enter round_sic loop \n");
+ //printf("round_sic= %d\n", round_sic);
+ dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+ dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+
+ dlsch0_eNB_harq->mimo_mode = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode;
+ dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0];
+ dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb;
+ dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs;
+ dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx;
+ dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl;
+ dlsch0_eNB_harq->round = dlsch0_ue_harq->round;
+ dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS;
+ dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
+ dlsch0_eNB_harq->status = dlsch0_ue_harq->status;
+
+ if (round_sic == 0){
+ UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 0;
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=0;
+ }
+ else if (round_sic == 1){
+ UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 1;
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=1;
+ }
+ else if (round_sic == 2){
+ UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 2;
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=2;
+ }
+ else{
+ UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 3;
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=3;
+ }
+
+ UE->dlsch_eNB[eNB_id]->active = UE->dlsch[eNB_id][0]->active;
+ UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti;
+ UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[eNB_id][0]->current_harq_pid;
+
+ dlsch_encoding_SIC(UE,
+ input_buffer0[0], //UE->dlsch[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,,
+ num_pdcch_symbols,
+ UE->dlsch_eNB[eNB_id],
+ 0,
+ subframe,
+ &UE->dlsch_rate_matching_stats,
+ &UE->dlsch_turbo_encoding_stats,
+ &UE->dlsch_interleaving_stats);
+
+
+ coded_bits_per_codeword[0]= get_G(&UE->frame_parms,
+ UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb,
+ UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc,
+ get_Qm(UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs),
+ UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl,
+ num_pdcch_symbols,
+ 0,
+ subframe,
+ transmission_mode>=7?transmission_mode:0);
+
+ dlsch_scrambling(&UE->frame_parms,
+ 0,
+ UE->dlsch_eNB[eNB_id],
+ coded_bits_per_codeword[0],
+ 0,
+ subframe<<1);
+
+ re_allocated = dlsch_modulation_SIC(sic_buffer,
+ subframe,
+ &UE->frame_parms,
+ num_pdcch_symbols,
+ &UE->dlsch_eNB[0][0],
+ coded_bits_per_codeword[0]);
+
+ // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1);
+ // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1);
+ // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1);
+
+
+ switch (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){
+
+
+
+ case 2:
+
+ dlsch_qpsk_llr_SIC(&UE->frame_parms,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ sic_buffer,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword],
+ num_pdcch_symbols,
+ dlsch0_eNB_harq->nb_rb,
+ subframe,
+ dlsch0_eNB_harq->rb_alloc[0],
+ get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
+ UE->dlsch[eNB_id][0]);
+ break;
+
+ case 4:
+
+ dlsch_16qam_llr_SIC(&UE->frame_parms,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ sic_buffer,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword],
+ num_pdcch_symbols,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ dlsch0_eNB_harq->nb_rb,
+ subframe,
+ dlsch0_eNB_harq->rb_alloc[0],
+ get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs),
+ UE->dlsch[eNB_id][0]);
+ break;
+ case 6:
+ dlsch_64qam_llr_SIC(&UE->frame_parms,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ sic_buffer,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword],
+ num_pdcch_symbols,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[0][0]->current_harq_pid][round_sic],
+ dlsch0_eNB_harq->nb_rb,
+ subframe,
+ dlsch0_eNB_harq->rb_alloc[0],
+ get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
+ UE->dlsch[eNB_id][TB]);
+ break;
+ }
+ //}// rouns sic
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword);
+#endif
+
+ // write_output("rxdata_llr1.m","llr1", UE->pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0);
+
+ // replace cw_sic with TB+1
+ UE->dlsch[0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+ coded_bits_per_codeword[1]= get_G(&eNB->frame_parms,
+ eNB->dlsch[0][1]->harq_processes[0]->nb_rb,
+ eNB->dlsch[0][1]->harq_processes[0]->rb_alloc,
+ get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs),
+ eNB->dlsch[0][1]->harq_processes[0]->Nl,
+ num_pdcch_symbols,
+ 0,
+ subframe,
+ transmission_mode>=7?transmission_mode:0);
+
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->G = coded_bits_per_codeword[1];
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs);
+
+ if (n_frames==2) {
+ printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1],
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->TBS);
+
+ // calculate uncoded BER
+ uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]);
+ AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL");
+ sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round,1);
+ sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, 1);
+ write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[1],coded_bits_per_codeword[1],1,0);
+ sprintf(fname,"dlsch_cw%d_e.m", 1);
+ sprintf(vname,"dlschcw%d_e", 1);
+ write_output(fname, vname,eNB->dlsch[0][1]->harq_processes[0]->e,coded_bits_per_codeword[1],1,4);
+ uncoded_ber=0;
+ printf("trials=%d\n", trials);
+ for (i=0;idlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword][i]<0)) {
+ uncoded_ber_bit[i] = 1;
+ uncoded_ber++;
+ }
+ else
+ uncoded_ber_bit[i] = 0;
+
+ uncoded_ber/=coded_bits_per_codeword[1];
+ avg_ber += uncoded_ber;
+ sprintf(fname,"cw%d_uncoded_ber_bit.m", 1);
+ sprintf(vname,"uncoded_ber_bit_cw%d", 1);
+ write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[1],1,0);
+ printf("cw %d, uncoded ber %f\n",1,uncoded_ber);
+ free(uncoded_ber_bit);
+ uncoded_ber_bit = NULL;
+ }
+
+ start_meas(&UE->dlsch_unscrambling_stats);
+ dlsch_unscrambling(&UE->frame_parms,
+ 0,
+ UE->dlsch[0][1],
+ coded_bits_per_codeword[1],
+ UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword],
+ 1,
+ subframe<<1);
+ stop_meas(&UE->dlsch_unscrambling_stats);
+
+ start_meas(&UE->dlsch_decoding_stats);
+
+ ret[1] = dlsch_decoding(UE,
+ UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword],
+ &UE->frame_parms,
+ UE->dlsch[0][1],
+ UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid],
+ 0,
+ subframe,
+ UE->dlsch[0][1]->current_harq_pid,
+ 1,llr8_flag);
+ stop_meas(&UE->dlsch_decoding_stats);
+
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] Decoding TB1 in SIC: ret[1] = %d, round sic %d\n", ret[1], round_sic);
+#endif
+
+ //printf("ret TB 1 = %d round %d \n", ret[1], round);
+
+ if (ret[1] <=UE->dlsch[0][0]->max_turbo_iterations ) {
+ decoded_in_sic[round]++;
+ round_sic = round+1; // to exit round_sic
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] TB1 is decoded in SIC loop\n");
+#endif
+ avg_iter[1] += ret[1];
+ iter_trials[1]++;
+
+
+ if (n_frames==2) {
+ printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber);
+
+ #ifdef PRINT_BYTES
+ for (s=0;sdlsch[0][1]->harq_processes[0]->C;s++) {
+ if (sdlsch[0][1]->harq_processes[0]->Cminus)
+ Kr = UE->dlsch[0][1]->harq_processes[0]->Kminus;
+ else
+ Kr = UE->dlsch[0][1]->harq_processes[0]->Kplus;
+
+ Kr_bytes = Kr>>3;
+
+ printf("Decoded_output (Segment %d):\n",s);
+
+ for (i=0;idlsch[0][1]->harq_processes[0]->c[s][i],
+ UE->dlsch[0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
+ }
+ #endif
+ }
+ }
+ } //round_sic
+
+
+ if (ret[1] > UE->dlsch[0][0]->max_turbo_iterations ){
+ errs[1][round]++;
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]);
+#endif
+
+ // exit(0);
+
+ avg_iter[1] += ret[1]-1;
+ iter_trials[1]++;
+
+ if (n_frames==2) {
+ //if ((n_frames==1) || (SNR>=30)) {
+ printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber);
+#ifdef PRINT_BYTES
+ for (s=0;sdlsch[0][1]->harq_processes[0]->C;s++) {
+ if (sdlsch[0][1]->harq_processes[0]->Cminus)
+ Kr = UE->dlsch[0][1]->harq_processes[0]->Kminus;
+ else
+ Kr = UE->dlsch[0][1]->harq_processes[0]->Kplus;
+
+ Kr_bytes = Kr>>3;
+
+ printf("Decoded_output (Segment %d):\n",s);
+ for (i=0;idlsch[0][1]->harq_processes[0]->c[s][i],
+ UE->dlsch[0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
+ }
+#endif
+ } //n_frames==1
+ // exit(0);
+ } //if (ret > UE->dlsch[0][1]->max_turbo_iterations )
+ }//if SIC
+ } else {
+
+ errs[TB][round]++;
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", TB, TB, round, errs[TB][round]);
+#endif
+
+
+ /*if (cw_non_sic==0) {
+ avg_iter[0] += ret[0]-1;
+ iter_trials[0]++;
+ }*/
+
+ if ((UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+ (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) &&
+ (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) {
+ errs[1][round]++;
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", 1, 1, round, errs[1][round]);
+#endif
+ }
+
+
+ /*if (cw_non_sic==1) {
+ avg_iter[1] += ret[1]-1;
+ iter_trials[1]++;
+ }*/
+
+
+ if (n_frames==2) {
+ //if ((n_frames==1) || (SNR>=30)) {
+ printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber);
+#ifdef PRINT_BYTES
+ for (s=0;sdlsch[0][TB]->harq_processes[0]->C;s++) {
+ if (sdlsch[0][TB]->harq_processes[0]->Cminus)
+ Kr = UE->dlsch[0][TB]->harq_processes[0]->Kminus;
+ else
+ Kr = UE->dlsch[0][TB]->harq_processes[0]->Kplus;
+
+ Kr_bytes = Kr>>3;
+
+ printf("Decoded_output (Segment %d):\n",s);
+ for (i=0;idlsch[0][TB]->harq_processes[0]->c[s][i],
+ UE->dlsch[0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
+ }
+#endif
+ }
+ }
+ if (rx_type==rx_SIC_dual_stream)
+ TB++; // to terminate the loop over TB
+ }
+
+ stop_meas(&UE->phy_proc_rx);
+
+ if (n_frames==1) {
+
+ //rxsig
+ sprintf(fname,"rxsig0_r%d.m",round);
+ sprintf(vname,"rxs0_r%d",round);
+ write_output(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+ sprintf(fname,"rxsigF0_r%d.m",round);
+ sprintf(vname,"rxs0F_r%d",round);
+ write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+ if (UE->frame_parms.nb_antennas_rx>1) {
+ sprintf(fname,"rxsig1_r%d.m",round);
+ sprintf(vname,"rxs1_r%d",round);
+ write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
+ sprintf(fname,"rxsig1F_r%d.m",round);
+ sprintf(vname,"rxs1F_r%d",round);
+ write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+ }
+
+ //channel
+ write_output("chanF11.m","chF11",eNB2UE[0]->chF[0],12*NB_RB,1,8);
+ write_output("chan11.m","ch11",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8);
+
+ if (eNB->frame_parms.nb_antennas_rx==2 && eNB->frame_parms.nb_antennas_tx==1 ){
+ write_output("chan21.m","ch21",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8);
+ }
+ if (eNB->frame_parms.nb_antennas_tx>1){
+ write_output("chan12.m","ch12",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8);
+ if ( eNB->frame_parms.nb_antennas_rx>1){
+ write_output("chan21.m","ch21",eNB2UE[0]->ch[2],eNB2UE[0]->channel_length,1,8);
+ write_output("chan22.m","ch22",eNB2UE[0]->ch[3],eNB2UE[0]->channel_length,1,8);
+ }
+ }
+
+ //channel estimates
+ sprintf(fname,"dlsch00_r%d.m",round);
+ sprintf(vname,"dl00_r%d",round);
+ write_output(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+ if (UE->frame_parms.nb_antennas_rx>1) {
+ sprintf(fname,"dlsch01_r%d.m",round);
+ sprintf(vname,"dl01_r%d",round);
+ write_output(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+ }
+ if (eNB->frame_parms.nb_antennas_tx>1) {
+ sprintf(fname,"dlsch10_r%d.m",round);
+ sprintf(vname,"dl10_r%d",round);
+ write_output(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+ }
+ if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) {
+ sprintf(fname,"dlsch11_r%d.m",round);
+ sprintf(vname,"dl11_r%d",round);
+ write_output(fname,vname,
+ &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+ UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+ }
+ //pdsch_vars
+ dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid);
+ /*
+ write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+ write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
+ write_output("dlsch_eNB_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
+ write_output("dlsch_UE_w.m","w",UE->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+ */
+
+ //pdcch_vars
+ 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],300*3,1,1);
+
+ write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1);
+ write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4);
+
+ if (round == 3) exit(-1);
+ }
+
+ if (xforms==1) {
+ phy_scope_UE(form_ue,
+ UE,
+ eNB_id,
+ 0,// UE_id
+ subframe);
+ }
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]);
+#endif
+
+ if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[0][0]->max_turbo_iterations)){
+ //printf("flag 1 \n");
+ round++;
+ }
+
+
+ if (transmission_mode == 3 || transmission_mode == 4 ) {
+ if (ret[0] > UE->dlsch[0][0]->max_turbo_iterations &&
+ ret[1] > UE->dlsch[0][0]->max_turbo_iterations){
+ resend_both[round]++;
+ round++;
+ resend_cw0_cw1=1; //resend both cws
+ resend_cw1=0;
+ TB0_active=1;
+ TB1_active=1;
+ }
+ else if (ret[1] > UE->dlsch[0][0]->max_turbo_iterations &&
+ ret[0] <= UE->dlsch[0][0]->max_turbo_iterations){
+ resend_one[round]++;
+ resend_cw0_cw1=0;
+ TB0_active=0;
+ TB1_active=1;
+ if (rx_type == rx_IC_dual_stream)
+ TB0_deact[round]++;
+ if(is_first_time) {
+ hold_rank1_precoder = 0;
+ is_first_time = false;
+ }
+ else
+ hold_rank1_precoder = 1;
+
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
+ printf("[DLSIM] TB0 deactivated\n");
+#endif
+ round++;
+ }
+ else if (ret[0] > UE->dlsch[0][0]->max_turbo_iterations &&
+ ret[1] <= UE->dlsch[0][0]->max_turbo_iterations){
+ resend_one[round]++;
+ resend_cw0_cw1=0;
+ TB0_active=1;
+ TB1_active=0;
+ if (rx_type == rx_IC_dual_stream)
+ TB1_deact[round]++;
+ if(is_first_time) {
+ hold_rank1_precoder = 0;
+ is_first_time = false;
+ }
+ else
+ hold_rank1_precoder = 1;
+
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
+ printf("[DLSIM] TB1 deactivated\n");
+#endif
+ round++;
+ }
+ }
+
+#ifdef DEBUG_HARQ
+ printf("[DLSIM] Now round is %d, trial %d\n" , round, trials);
+#endif
+ }
+
+
+ if(transmission_mode != 3 && transmission_mode !=4 ){
+ if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) )
+ break;
+ }
+
+ //len = chbch_stats_read(stats_buffer,NULL,0,4096);
+ //printf("%s\n\n",stats_buffer);
+
+ if (UE->proc.proc_rxtx[0].frame_rx % 10 == 0) {
+ UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10;
+ LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],UE->bitrate[eNB_id]/1000);
+ UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id];
+ }
+
+
+ UE->proc.proc_rxtx[0].frame_rx++;
+
+ /* calculate the total processing time for each packet,
+ * get the max, min, and number of packets that exceed t>2000us
+ */
+ double t_tx = (double)eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0;
+ double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0;
+ double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0;
+ double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
+
+
+ double t_rx = (double)UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0;
+ double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
+ double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
+ double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0;
+
+
+ if (t_tx > t_tx_max)
+ t_tx_max = t_tx;
+ if (t_tx < t_tx_min)
+ t_tx_min = t_tx;
+ if (t_rx > t_rx_max)
+ t_rx_max = t_rx;
+ if (t_rx < t_rx_min)
+ t_rx_min = t_rx;
+ if (t_tx > 2000)
+ n_tx_dropped++;
+ if (t_rx > 2000)
+ n_rx_dropped++;
+
+
+ push_front(&time_vector_tx, t_tx);
+ push_front(&time_vector_tx_ifft, t_tx_ifft);
+ push_front(&time_vector_tx_mod, t_tx_mod);
+ push_front(&time_vector_tx_enc, t_tx_enc);
+
+ push_front(&time_vector_rx, t_rx);
+ push_front(&time_vector_rx_fft, t_rx_fft);
+ push_front(&time_vector_rx_demod, t_rx_demod);
+ push_front(&time_vector_rx_dec, t_rx_dec);
+
+
+ } //trials
+
+#ifdef DEBUG_HARQ
+ printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]);
+ printf(" only one failed round 0 = %d, only one failed round 1 = %d, only one failed round 2 = %d, only one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]);
+ if (rx_type == rx_SIC_dual_stream){
+ printf(" sic attempt round 0 = %d, sic attempt round 1 = %d, sic attempt round 2 = %d, sic attempt round 3 = %d\n", sic_attempt[0], sic_attempt[1], sic_attempt[2], sic_attempt[3]);
+ printf(" decoded in sic round 0 = %d, decoded in sic round 1 = %d, decoded in sic round 2 = %d, decoded in sic round 3 = %d\n", decoded_in_sic[0], decoded_in_sic[1], decoded_in_sic[2], decoded_in_sic[3]);
+ }
+ else if (rx_type == rx_IC_dual_stream){
+ printf(" TB0 deactiv round 0 = %d, TB0 deactiv round 1 = %d, TB0 deactiv round 2 = %d, TB0 deactiv round 3 = %d\n", TB0_deact[0], TB0_deact[1], TB0_deact[2], TB0_deact[3]);
+ printf(" TB1 deactiv round 0 = %d, TB1 deactiv round 1 = %d, TB1 deactiv round 2 = %d, TB1 deactiv round 3 = %d\n", TB1_deact[0], TB1_deact[1], TB1_deact[2], TB1_deact[3]);
+ }
+#endif
+ // round_trials[0]: number of code word : goodput the protocol
+ double table_tx[time_vector_tx.size];
+ totable(table_tx, &time_vector_tx);
+ double table_tx_ifft[time_vector_tx_ifft.size];
+ totable(table_tx_ifft, &time_vector_tx_ifft);
+ double table_tx_mod[time_vector_tx_mod.size];
+ totable(table_tx_mod, &time_vector_tx_mod);
+ double table_tx_enc[time_vector_tx_enc.size];
+ totable(table_tx_enc, &time_vector_tx_enc);
+
+ double table_rx[time_vector_rx.size];
+ totable(table_rx, &time_vector_rx);
+ double table_rx_fft[time_vector_rx_fft.size];
+ totable(table_rx_fft, &time_vector_rx_fft);
+ double table_rx_demod[time_vector_rx_demod.size];
+ totable(table_rx_demod, &time_vector_rx_demod);
+ double table_rx_dec[time_vector_rx_dec.size];
+ totable(table_rx_dec, &time_vector_rx_dec);
+
+
+ // sort table
+ qsort (table_tx, time_vector_tx.size, sizeof(double), &compare);
+ qsort (table_rx, time_vector_rx.size, sizeof(double), &compare);
+
+ if (dump_table == 1 ) {
+ set_component_filelog(USIM); // file located in /tmp/usim.txt
+ int n;
+ LOG_F(USIM,"The transmitter raw data: \n");
+
+ for (n=0; n< time_vector_tx.size; n++) {
+ printf("%f ", table_tx[n]);
+ LOG_F(USIM,"%f ", table_tx[n]);
+ }
+
+ LOG_F(USIM,"\n");
+ LOG_F(USIM,"The receiver raw data: \n");
+
+ for (n=0; n< time_vector_rx.size; n++) {
+ // printf("%f ", table_rx[n]);
+ LOG_F(USIM,"%f ", table_rx[n]);
+ }
+
+ LOG_F(USIM,"\n");
+ }
+
+ double tx_median = table_tx[time_vector_tx.size/2];
+ double tx_q1 = table_tx[time_vector_tx.size/4];
+ double tx_q3 = table_tx[3*time_vector_tx.size/4];
+
+ double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2];
+ double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4];
+ double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4];
+
+ double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2];
+ double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4];
+ double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4];
+
+ double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2];
+ double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4];
+ double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4];
+
+ double rx_median = table_rx[time_vector_rx.size/2];
+ double rx_q1 = table_rx[time_vector_rx.size/4];
+ double rx_q3 = table_rx[3*time_vector_rx.size/4];
+
+ double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2];
+ double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4];
+ double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4];
+
+ double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2];
+ double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4];
+ double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4];
+
+ double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2];
+ double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4];
+ double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4];
+
+ double std_phy_proc_tx=0;
+ double std_phy_proc_tx_ifft=0;
+ double std_phy_proc_tx_mod=0;
+ double std_phy_proc_tx_enc=0;
+
+ double std_phy_proc_rx=0;
+ double std_phy_proc_rx_fft=0;
+ double std_phy_proc_rx_demod=0;
+ double std_phy_proc_rx_dec=0;
+
+
+ if (transmission_mode != 3 && transmission_mode !=4) {
+ effective_rate = ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3]));
+ }
+ else {
+ effective_rate = ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3]))+
+ ((double)(round_trials[1][0])/((double)round_trials[1][0] + round_trials[1][1] + round_trials[1][2] + round_trials[1][3]));
+ }
+
+ /*
+ Here we compute throughput per cw based on the formula
+ T=P_suc[r1]R(mcs) + sum[r=2 ..r=4] (P_(suc r, fail r-1)*R/r).
+ The non-constr formula should not be used, when there are some errors on the last round,
+ meaning when not all the packages are finally decoded.
+ */
+
+ if (transmission_mode == 3 || transmission_mode == 4) {
+ // FOR CW0
+ thr_cw0[0] = rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0]));
+ if (num_rounds > 1)
+ thr_cw0[1] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/2)*(((double)errs[0][0] - (double)errs[0][1])/(double)round_trials[0][0]);
+ else
+ thr_cw0[1]=0;
+ if (num_rounds > 2)
+ thr_cw0[2] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/3)*(((double)errs[0][1] - (double)errs[0][2])/(double)round_trials[0][0]);
+ else
+ thr_cw0[2]=0;
+ if (num_rounds > 3)
+ thr_cw0[3] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/4)*(((double)errs[0][2] - (double)errs[0][3])/(double)round_trials[0][0]);
+ else
+ thr_cw0[3]=0;
+ thr_cw0_tot = (double)thr_cw0[0]+(double)thr_cw0[1]+(double)thr_cw0[2]+(double)thr_cw0[3];
+#ifdef PRINT_THROUGHPUT
+ printf("rate %f \n", rate0_init);
+ printf("rate*mod_order %f \n", rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs));
+ printf("Probability %f \n", (1-((double)errs[0][0]/(double)round_trials[0][0])));
+ printf("Throughput cw0 sum = %f \n", thr_cw0_tot);
+ printf("Throughput cw0 round 0 = %f \n", thr_cw0[0]);
+ printf("Throughput cw0 round 1 = %f \n", thr_cw0[1]);
+ printf("Throughput cw0 round 2 = %f \n", thr_cw0[2]);
+ printf("Throughput cw0 round 3 = %f \n", thr_cw0[3]);
+ printf("round_trials = %d, errs[0][0] = %d, round_trials[0][1] = %d, errs[0][1] = %d, round_trials[0][2] = %d, errs[0][2] = %d, \
+ round_trials[0][3] = %d, errs[0][3] = %d \n", round_trials[0][0], errs[0][0],round_trials[0][1], errs[0][1], round_trials[0][2], \
+ errs[0][2], round_trials[0][3], errs[0][3]);
+#endif
+
+ thr_cw1[0] = rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0]));
+ if (num_rounds > 1)
+ thr_cw1[1] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]);
+ else
+ thr_cw1[1] = 0;
+ if (num_rounds > 2)
+ thr_cw1[2] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/3)*(((double)errs[1][1] - (double)errs[1][2])/(double)round_trials[1][0]);
+ else
+ thr_cw1[2] = 0;
+ if (num_rounds > 3)
+ thr_cw1[3] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/4)*(((double)errs[1][2] - (double)errs[1][3])/(double)round_trials[1][0]);
+ else
+ thr_cw1[3]=0;
+ thr_cw1_tot = (double)thr_cw1[0]+(double)thr_cw1[1]+(double)thr_cw1[2]+(double)thr_cw1[3];
+#ifdef PRINT_THROUGHPUT
+ printf("Throughput cw1 sum = %f \n", thr_cw1_tot);
+ printf("Throughput cw1 round 0 = %f \n", thr_cw1[0]);
+ printf("Throughput cw1 round 1 = %f \n", thr_cw1[1]);
+ printf("Throughput cw1 round 2 = %f \n", thr_cw1[2]);
+ printf("Throughput cw1 round 3 = %f \n", thr_cw1[3]);
+ printf("round_trials[1][0] = %d, errs[1][0] = %d, round_trials[1][1] = %d, errs[1][1] = %d, round_trials[1][2] = %d, errs[1][2] = %d, \
+ round_trials[1][3] = %d, errs[1][3] = %d \n", round_trials[1][0], errs[1][0], round_trials[1][1], errs[1][1], round_trials[1][2], \
+ errs[1][2], round_trials[1][3], errs[1][3]);
+#endif
+ }
+
+#if 0
+ thr_cw0_tm4_nonconst = rate[0]*get_Qm(PHY_vars_eNB->dlsch[0][0]->harq_processes[0]->mcs)* \
+ ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3]));
+ printf("Throughput cw0 noncnstr = %f \n", thr_cw0_tm4_nonconst);
+#endif
+ //FOR CW1
+ /*thr_cw1[0] = rate[1]*get_Qm(PHY_vars_eNB->dlsch[0][1]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])) \
+ *(1-((double)errs[1][0]/(double)round_trials[1][0]));
+ printf("thr cw1 round 0 = %f\n", thr_cw1[0]);
+ thr_cw1[1]=(rate[1]*get_Qm(PHY_vars_eNB->dlsch[0][1]->harq_processes[0]->mcs)/2)*\
+ (((double)errs[1][0]-(double)errs[1][1])*((double)round_trials[0][0] - (double)errs[0][1])/((double)round_trials[0][0]*(double)round_trials[1][0]));
+ printf("thr cw1 round 1 = %f\n", thr_cw1[1]);
+ thr_cw1[2] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch[0][0]->harq_processes[0]->mcs)/3)*\
+ ((double)errs[1][1]-(double)errs[1][2])*((double)round_trials[0][0]-(double)errs[0][2])/((double)round_trials[0][0]*(double)round_trials[1][0]);
+ printf("thr cw1 round 2 = %f\n", thr_cw1[2]);
+ thr_cw1[3] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch[0][0]->harq_processes[0]->mcs)/4)*\
+ ((double)errs[1][2]-(double)errs[1][3])*((double)round_trials[0][0] - (double)errs[0][3])/((double)round_trials[0][0]*(double)round_trials[1][0]);
+ resid_errs=
+ printf("thr cw1 round 3 = %f\n", thr_cw1[3]);
+ thr_cw1_tot =thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+thr_cw1[3];
+ printf("Throughput cw1 sum = %f \n", thr_cw1_tot);
+ printf("round_trials = %d, errs[1][0] = %d, round_trials[1][1] = %d, errs[1][1] = %d, round_trials[1][2] = %d, errs[1][2] = %d, \
+ round_trials[1][3] = %d, errs[1][3] = %d \n", round_trials[1][0], errs[1][0],round_trials[1][1], errs[1][1], round_trials[1][2], \
+ errs[1][2], round_trials[1][3], errs[1][3]);
+ }*/
+
+
+ printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n",
+ SNR,
+ (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)),
+ sigma2_dB);
+ if ((transmission_mode != 3) && (transmission_mode != 4)){
+ printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e)),"
+ "dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f), "
+ "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n",
+ errs[0][0],
+ errs[1][0],
+ round_trials[0][0],
+ errs[0][1],
+ errs[1][1],
+ round_trials[0][0],
+ errs[0][2],
+ errs[1][2],
+ round_trials[0][0],
+ errs[0][3],
+ errs[1][3],
+ round_trials[0][0],
+ (double)errs[0][0]/(round_trials[0][0]),
+ (double)errs[1][0]/(round_trials[0][0]),
+ (double)errs[0][1]/(round_trials[0][0]),
+ (double)errs[1][1]/(round_trials[0][0]),
+ (double)errs[0][2]/(round_trials[0][0]),
+ (double)errs[1][2]/(round_trials[0][0]),
+ (double)errs[0][3]/(round_trials[0][0]),
+ (double)errs[1][3]/(round_trials[0][0]),
+ dci_errors,
+ round_trials[0][0],
+ (double)dci_errors/(round_trials[0][0]),
+ rate[0]*effective_rate,
+ 100*effective_rate,
+ rate[0],
+ rate[0]*get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs),
+ (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+
+ 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])
+ +4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]),
+ thr_cw0_tot,
+ thr_cw1_tot,
+ thr_cw0_tot + thr_cw1_tot,
+ rate[0],
+ rate[1]);
+ }else{
+ printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d),"
+ "dci_errors %d/%d, thr TB0 = %f , thr TB1 = %f, overall thr = %f , rate 0 = %f , rate 1 = %f \n",
+ errs[0][0],
+ errs[1][0],
+ round_trials[0][0],
+ errs[0][1],
+ errs[1][1],
+ round_trials[0][0],
+ errs[0][2],
+ errs[1][2],
+ round_trials[0][0],
+ errs[0][3],
+ errs[1][3],
+ round_trials[0][0],
+ dci_errors,
+ round_trials[0][0],
+ thr_cw0_tot,
+ thr_cw1_tot,
+ thr_cw0_tot + thr_cw1_tot,
+ rate0_init,
+ rate1_init);
+ }
+
+ if (print_perf==1) {
+ printf("eNB TX function statistics (per 1ms subframe)\n\n");
+ std_phy_proc_tx = sqrt((double)eNB->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/eNB->phy_proc_tx.trials - pow((double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000,2));
+ printf("Total PHY proc tx :%f us (%d trials)\n",(double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_tx.trials);
+ printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n",std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3,
+ n_tx_dropped);
+ std_phy_proc_tx_ifft = sqrt((double)eNB->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/eNB->ofdm_mod_stats.trials - pow((double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2));
+ printf("OFDM_mod time :%f us (%d trials)\n",(double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,eNB->ofdm_mod_stats.trials);
+ printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3);
+ std_phy_proc_tx_mod = sqrt((double)eNB->dlsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/eNB->dlsch_modulation_stats.trials - pow((double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000,2));
+ printf("DLSCH modulation time :%f us (%d trials)\n",(double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000.0,
+ eNB->dlsch_modulation_stats.trials);
+ printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3);
+ printf("DLSCH scrambling time :%f us (%d trials)\n",(double)eNB->dlsch_scrambling_stats.diff/eNB->dlsch_scrambling_stats.trials/cpu_freq_GHz/1000.0,
+ eNB->dlsch_scrambling_stats.trials);
+ std_phy_proc_tx_enc = sqrt((double)eNB->dlsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/eNB->dlsch_encoding_stats.trials - pow((double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000,2));
+ printf("DLSCH encoding time :%f us (%d trials)\n",(double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000.0,
+ eNB->dlsch_modulation_stats.trials);
+ printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3);
+ printf("|__ DLSCH turbo encoding time :%f us (%d trials)\n",
+ ((double)eNB->dlsch_turbo_encoding_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
+ eNB->dlsch_turbo_encoding_stats.diff/eNB->dlsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_turbo_encoding_stats.trials);
+ printf("|__ DLSCH rate-matching time :%f us (%d trials)\n",
+ ((double)eNB->dlsch_rate_matching_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
+ eNB->dlsch_rate_matching_stats.diff/eNB->dlsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_rate_matching_stats.trials);
+ printf("|__ DLSCH sub-block interleaving time :%f us (%d trials)\n",
+ ((double)eNB->dlsch_interleaving_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
+ eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
+
+ printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
+ std_phy_proc_rx = sqrt((double)UE->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/UE->phy_proc_rx.trials - pow((double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000,2));
+ printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000.0,
+ UE->phy_proc_rx.trials*2/3);
+ 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)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/UE->ofdm_demod_stats.trials - pow((double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2));
+ printf("DLSCH OFDM demodulation and channel_estimation time :%f us (%d trials)\n",(nsymb)*(double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0,
+ UE->ofdm_demod_stats.trials*2/3);
+ 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);
+ printf("|__ DLSCH rx dft :%f us (%d trials)\n",
+ (nsymb*UE->frame_parms.nb_antennas_rx)*(double)UE->rx_dft_stats.diff/UE->rx_dft_stats.trials/cpu_freq_GHz/1000.0,UE->rx_dft_stats.trials*2/3);
+ printf("|__ DLSCH channel estimation time :%f us (%d trials)\n",
+ (4.0)*(double)UE->dlsch_channel_estimation_stats.diff/UE->dlsch_channel_estimation_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_channel_estimation_stats.trials*2/3);
+ printf("|__ DLSCH frequency offset estimation time :%f us (%d trials)\n",
+ (4.0)*(double)UE->dlsch_freq_offset_estimation_stats.diff/UE->dlsch_freq_offset_estimation_stats.trials/cpu_freq_GHz/1000.0,
+ UE->dlsch_freq_offset_estimation_stats.trials*2/3);
+ printf("DLSCH rx pdcch :%f us (%d trials)\n",(double)UE->dlsch_rx_pdcch_stats.diff/UE->dlsch_rx_pdcch_stats.trials/cpu_freq_GHz/1000.0,
+ UE->dlsch_rx_pdcch_stats.trials);
+ std_phy_proc_rx_demod = sqrt((double)UE->dlsch_llr_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/UE->dlsch_llr_stats.trials - pow((double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000,2));
+ printf("DLSCH Channel Compensation and LLR generation time :%f us (%d trials)\n",(3)*(double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0,
+ UE->dlsch_llr_stats.trials/3);
+ printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3);
+ printf("DLSCH unscrambling time :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0,
+ UE->dlsch_unscrambling_stats.trials);
+ std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+ 2)/UE->dlsch_decoding_stats.trials - pow((double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000,2));
+ printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f) :%f us (%d trials, max %f)\n",
+ eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter[0]/iter_trials[0],
+ (double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats.trials,
+ (double)UE->dlsch_decoding_stats.max/cpu_freq_GHz/1000.0);
+ printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
+ printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n",
+ (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
+ printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n",
+ UE->dlsch[0][0]->harq_processes[0]->Cminus ? UE->dlsch[0][0]->harq_processes[0]->Kminus : UE->dlsch[0][0]->harq_processes[0]->Kplus,
+ (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
+ printf(" |__ init %f us (cycles/iter %f, %d trials)\n",
+ (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
+ (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/((double)avg_iter[0]/iter_trials[0]),
+ UE->dlsch_tc_init_stats.trials);
+ printf(" |__ alpha %f us (cycles/iter %f, %d trials)\n",
+ (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0,
+ (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials*2,
+ UE->dlsch_tc_alpha_stats.trials);
+ printf(" |__ beta %f us (cycles/iter %f,%d trials)\n",
+ (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0,
+ (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials*2,
+ UE->dlsch_tc_beta_stats.trials);
+ printf(" |__ gamma %f us (cycles/iter %f,%d trials)\n",
+ (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0,
+ (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials*2,
+ UE->dlsch_tc_gamma_stats.trials);
+ printf(" |__ ext %f us (cycles/iter %f,%d trials)\n",
+ (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0,
+ (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials*2,
+ UE->dlsch_tc_ext_stats.trials);
+ printf(" |__ intl1 %f us (cycles/iter %f,%d trials)\n",
+ (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0,
+ (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials,
+ UE->dlsch_tc_intl1_stats.trials);
+ printf(" |__ intl2+HD+CRC %f us (cycles/iter %f,%d trials)\n",
+ (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0,
+ (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials,
+ UE->dlsch_tc_intl2_stats.trials);
+ }
+
+ if ((transmission_mode != 3) && (transmission_mode != 4)) {
+ fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
+ SNR,
+ mcs1,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ rate[0],
+ errs[0][0],
+ round_trials[0][0],
+ errs[0][1],
+ round_trials[0][1],
+ errs[0][2],
+ round_trials[0][2],
+ errs[0][3],
+ round_trials[0][3],
+ dci_errors);
+ }
+ else if ( rx_type== rx_SIC_dual_stream) {
+ fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%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;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+ SNR,
+ mcs1,
+ mcs2,
+ tbs0_init,
+ tbs1_init,
+ rate0_init,
+ rate1_init,
+ errs[0][0],
+ errs[1][0],
+ round_trials[0][0],
+ round_trials[1][0],
+ sic_attempt[0],
+ decoded_in_sic[0],
+ resend_both[0],
+ resend_one[0],
+ errs[0][1],
+ errs[1][1],
+ round_trials[0][1],
+ round_trials[1][1],
+ sic_attempt[1],
+ decoded_in_sic[1],
+ resend_both[1],
+ resend_one[1],
+ errs[0][2],
+ errs[1][2],
+ round_trials[0][2],
+ round_trials[1][2],
+ sic_attempt[2],
+ decoded_in_sic[2],
+ resend_both[2],
+ resend_one[2],
+ errs[0][3],
+ errs[1][3],
+ round_trials[0][3],
+ round_trials[1][3],
+ sic_attempt[3],
+ decoded_in_sic[3],
+ thr_cw0[0],
+ thr_cw1[0],
+ thr_cw0[0]+thr_cw1[0],
+ thr_cw0[1],
+ thr_cw1[1],
+ thr_cw0[1]+thr_cw1[1],
+ thr_cw0[2],
+ thr_cw1[2],
+ thr_cw0[2]+thr_cw1[2],
+ thr_cw0[3],
+ thr_cw1[3],
+ thr_cw0[3]+thr_cw1[3],
+ thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]);
+ }
+ else{
+ fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%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;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+ SNR,
+ mcs1,
+ mcs2,
+ tbs0_init,
+ tbs1_init,
+ rate0_init,
+ rate1_init,
+ errs[0][0],
+ errs[1][0],
+ round_trials[0][0],
+ round_trials[1][0],
+ TB0_deact[0],
+ TB1_deact[0],
+ resend_both[0],
+ resend_one[0],
+ errs[0][1],
+ errs[1][1],
+ round_trials[0][1],
+ round_trials[1][1],
+ TB0_deact[1],
+ TB1_deact[1],
+ resend_both[1],
+ resend_one[1],
+ errs[0][2],
+ errs[1][2],
+ round_trials[0][2],
+ round_trials[1][2],
+ TB0_deact[2],
+ TB1_deact[2],
+ resend_both[2],
+ resend_one[2],
+ errs[0][3],
+ errs[1][3],
+ round_trials[0][3],
+ round_trials[1][3],
+ thr_cw0[0],
+ thr_cw1[0],
+ thr_cw0[0]+thr_cw1[0],
+ thr_cw0[1],
+ thr_cw1[1],
+ thr_cw0[1]+thr_cw1[1],
+ thr_cw0[2],
+ thr_cw1[2],
+ thr_cw0[2]+thr_cw1[2],
+ thr_cw0[3],
+ thr_cw1[3],
+ thr_cw0[3]+thr_cw1[3],
+ thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]);
+ }
+
+
+ if(abstx){ //ABSTRACTION
+ if ((transmission_mode != 3)&& (transmission_mode != 4)) {
+
+ blerr[0][0] = (double)errs[0][0]/(round_trials[0][0]);
+
+ if(num_rounds>1){
+ blerr[0][1] = (double)errs[0][1]/(round_trials[0][1]);
+
+ blerr[0][2] = (double)errs[0][2]/(round_trials[0][2]);
+
+ blerr[0][3] = (double)errs[0][3]/(round_trials[0][3]);
+
+ fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]);
+ }
+ else {
+ fprintf(csv_fd,"%e;\n",blerr[0][0]);
+ }
+ }
+ else {
+ blerr[0][0] = (double)errs[0][0]/(round_trials[0][0]);
+ blerr[1][0] = (double)errs[1][0]/(round_trials[0][0]);
+ if(num_rounds>1){
+ blerr[0][1] = (double)errs[0][1]/(round_trials[0][1]);
+ blerr[1][1] = (double)errs[1][1]/(round_trials[1][1]);
+ blerr[0][2] = (double)errs[0][2]/(round_trials[0][2]);
+ blerr[1][2] = (double)errs[1][2]/(round_trials[1][2]);
+ blerr[0][3] = (double)errs[0][3]/(round_trials[0][3]);
+ blerr[1][3] = (double)errs[1][3]/(round_trials[1][3]);
+
+ fprintf(csv_fd,"%e;%e;%e;%e;%e;%e;%e;%e;\n",blerr[0][0],blerr[1][0],blerr[0][1],blerr[1][1],blerr[0][2],blerr[1][2], blerr[0][3], blerr[1][3]);
+ }
+ else {
+ fprintf(csv_fd,"%e,%e;\n",blerr[0][0], blerr[1][0]);
+ }
+ }
+ }
+
+ if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
+ //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
+ if ((transmission_mode != 3) && (transmission_mode != 4)) {
+ fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
+ SNR,
+ mcs1,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ rate[0],
+ errs[0][0],
+ round_trials[0][0],
+ errs[0][1],
+ round_trials[0][1],
+ errs[0][2],
+ round_trials[0][2],
+ errs[0][3],
+ round_trials[0][3],
+ dci_errors);
+
+ //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
+ fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;",
+ SNR,
+ mcs1,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ rate[0]*effective_rate,
+ 100*effective_rate,
+ rate[0],
+ (double)avg_iter[0]/iter_trials[0],
+ errs[0][0],
+ round_trials[0],
+ errs[0][1],
+ round_trials[1],
+ errs[0][2],
+ round_trials[2],
+ errs[0][3],
+ round_trials[3],
+ (double)errs[0][0]/(round_trials[0][0]),
+ (double)errs[0][1]/(round_trials[0][0]),
+ (double)errs[0][2]/(round_trials[0][0]),
+ (double)errs[0][3]/(round_trials[0][0]),
+ dci_errors,
+ round_trials[0],
+ (double)dci_errors/(round_trials[0][0]),
+ (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]));
+ }
+ else {
+ fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
+ SNR,
+ mcs1,mcs2,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ eNB->dlsch[0][1]->harq_processes[0]->TBS,
+ rate[0],
+ errs[0][0],
+ round_trials[0][0],
+ errs[0][1],
+ round_trials[0][1],
+ errs[0][2],
+ round_trials[0][2],
+ errs[0][3],
+ round_trials[0][3],
+ dci_errors);
+
+ //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
+ fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;",
+ SNR,
+ mcs1,mcs2,
+ eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ eNB->dlsch[0][1]->harq_processes[0]->TBS,
+ rate[0]*effective_rate,
+ 100*effective_rate,
+ rate[0],
+ (double)avg_iter[0]/iter_trials[0],
+ errs[0][0],
+ round_trials[0][0],
+ errs[0][1],
+ round_trials[0][1],
+ errs[0][2],
+ round_trials[0][2],
+ errs[0][3],
+ round_trials[3],
+ (double)errs[0][0]/(round_trials[0][0]),
+ (double)errs[0][1]/(round_trials[0][0]),
+ (double)errs[0][2]/(round_trials[0][0]),
+ (double)errs[0][3]/(round_trials[0][0]),
+ dci_errors,
+ round_trials[0][0],
+ (double)dci_errors/(round_trials[0][0]),
+ (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+ (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]));
+ }
+ //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n",
+ fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;",
+ eNB->phy_proc_tx.trials,
+ eNB->ofdm_mod_stats.trials,
+ eNB->dlsch_modulation_stats.trials,
+ eNB->dlsch_scrambling_stats.trials,
+ eNB->dlsch_encoding_stats.trials,
+ UE->phy_proc_rx.trials,
+ UE->ofdm_demod_stats.trials,
+ UE->dlsch_rx_pdcch_stats.trials,
+ UE->dlsch_llr_stats.trials,
+ UE->dlsch_unscrambling_stats.trials,
+ UE->dlsch_decoding_stats.trials
+ );
+ fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
+ get_time_meas_us(&eNB->phy_proc_tx),
+ get_time_meas_us(&eNB->ofdm_mod_stats),
+ get_time_meas_us(&eNB->dlsch_modulation_stats),
+ get_time_meas_us(&eNB->dlsch_scrambling_stats),
+ get_time_meas_us(&eNB->dlsch_encoding_stats),
+ get_time_meas_us(&UE->phy_proc_rx),
+ nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
+ get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
+ 3*get_time_meas_us(&UE->dlsch_llr_stats),
+ get_time_meas_us(&UE->dlsch_unscrambling_stats),
+ get_time_meas_us(&UE->dlsch_decoding_stats)
+ );
+ //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped);
+
+ //fprintf(time_meas_fd,"IFFT;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3);
+
+ //fprintf(time_meas_fd,"MOD;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3);
+
+ //fprintf(time_meas_fd,"ENC;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3);
+
+
+ //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped);
+
+ //fprintf(time_meas_fd,"FFT;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3);
+
+ //fprintf(time_meas_fd,"DEMOD;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3);
+
+ //fprintf(time_meas_fd,"DEC;\n");
+ fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
+
+
+ /*
+ fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
+ eNB->phy_proc_tx.trials,
+ eNB->ofdm_mod_stats.trials,
+ eNB->dlsch_modulation_stats.trials,
+ eNB->dlsch_scrambling_stats.trials,
+ eNB->dlsch_encoding_stats.trials,
+ UE->phy_proc_rx.trials,
+ UE->ofdm_demod_stats.trials,
+ UE->dlsch_rx_pdcch_stats.trials,
+ UE->dlsch_llr_stats.trials,
+ UE->dlsch_unscrambling_stats.trials,
+ UE->dlsch_decoding_stats.trials);
+ */
+ printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate[0]);
+ break;
+ } else if (test_perf !=0 ){
+ printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate[0]*effective_rate, 100*effective_rate, rate[0]);
+ }
+ if (abstx == 1) {
+ if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_SIC_dual_stream)) {
+
+ if ((((double)errs[0][0]/(round_trials[0][0]))<1e-2) && (((double)errs[1][0]/(round_trials[1][0]))<1e-2))
+ if ((((double)errs[0][0]/(round_trials[0][0]))<1e-2) && (((double)errs[1][0]/(round_trials[1][0]))<1e-2))
+ break;
+ }
+ else{
+ if (((double)errs[0][0]/(round_trials[0][0]))<1e-2)
+ break;
+
+ }
+ }
+ else {
+
+ if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_SIC_dual_stream)) {
+ if ((((double)errs[0][0]/(round_trials[0][0]))<1e-3) && (((double)errs[1][0]/(round_trials[1][0]))<1e-3))
+ break;
+ }
+ else{
+ if (((double)errs[0][0]/(round_trials[0][0]))<1e-3)
+ break;
+
+ }
+
+ }
+
+ if (n_frames==1)
+ break;
+
+ }// SNR
+
+ } //ch_realization
+
+ fclose(bler_fd);
+
+ if (test_perf !=0)
+ fclose (time_meas_fd);
+
+ //fprintf(tikz_fd,"};\n");
+ //fclose(tikz_fd);
+
+ if (input_trch_file==1)
+ fclose(input_trch_fd);
+
+ if (input_file==1)
+ fclose(input_fd);
+
+ if(abstx) { // ABSTRACTION
+ fprintf(csv_fd,"];");
+ fclose(csv_fd);
+ }
+
+ if (uncoded_ber_bit)
+ free(uncoded_ber_bit);
+
+ uncoded_ber_bit = NULL;
+
+ for (k=0; kdlsch[0][i]);
+ printf("UE %d\n",i);
+ free_ue_dlsch(UE->dlsch[0][i]);
+ }
+
+
+ printf("Freeing channel I/O\n");
+
+ for (i=0; i<2; i++) {
+ free(s_re[i]);
+ free(s_im[i]);
+ free(r_re[i]);
+ free(r_im[i]);
+ }
+
+ free(s_re);
+ free(s_im);
+ free(r_re);
+ free(r_im);
+
+ // lte_sync_time_free();
+
+ // printf("[MUMIMO] mcs %d, mcsi %d, offset %d, bler %f\n",mcs,mcs_i,offset_mumimo_llr_drange_fix,((double)errs[0])/((double)round_trials[0]));
+
+ return(0);
+}
+
+
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
index 874af41f45..195f27f72e 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -1,31 +1,23 @@
- /******************************************************************************
- OpenAirInterface
- Copyright(c) 1999 - 2014 Eurecom
-
- OpenAirInterface is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
-
- OpenAirInterface is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with OpenAirInterface.The full GNU General Public License is
- included in this distribution in the file called "COPYING". If not,
- see .
-
- Contact Information
- OpenAirInterface Admin: openair_admin@eurecom.fr
- OpenAirInterface Tech : openair_tech@eurecom.fr
- OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
-
- Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
-
- *******************************************************************************/
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
/*! \file dlsim.c
\brief Top-level DL simulator
diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c
index 8fce4d25a6..88b3ce6406 100644
--- a/openair1/SIMULATION/TOOLS/abstraction.c
+++ b/openair1/SIMULATION/TOOLS/abstraction.c
@@ -115,7 +115,7 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples)
start_meas(&desc->interp_freq);
- for (f=-n_samples_max/2,f2=-n_samples/2; f<=n_samples_max/2; f+=d,f2++) {
+ for (f=-n_samples_max/2,f2=-n_samples/2; fnb_tx = nb_tx;
chan_desc->nb_rx = nb_rx;
@@ -64,31 +67,29 @@ void fill_channel_desc(channel_desc_t *chan_desc,
chan_desc->channel_length = channel_length;
chan_desc->amps = amps;
LOG_D(OCM,"[CHANNEL] Doing delays ...\n");
-
if (delays==NULL) {
chan_desc->delays = (double*) malloc(nb_taps*sizeof(double));
delta_tau = Td/nb_taps;
-
for (i=0; idelays[i] = ((double)i)*delta_tau;
- } else
- chan_desc->delays = delays;
-
- chan_desc->Td = Td;
- chan_desc->sampling_rate = sampling_rate;
- chan_desc->channel_bandwidth = channel_bandwidth;
- chan_desc->ricean_factor = ricean_factor;
- chan_desc->aoa = aoa;
- chan_desc->random_aoa = random_aoa;
- chan_desc->forgetting_factor = forgetting_factor;
- chan_desc->channel_offset = channel_offset;
- chan_desc->path_loss_dB = path_loss_dB;
- chan_desc->first_run = 1;
- chan_desc->ip = 0.0;
- chan_desc->max_Doppler = max_Doppler;
- chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*));
- chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*));
- chan_desc->a = (struct complex**) malloc(nb_taps*sizeof(struct complex*));
+ }
+ else
+ chan_desc->delays = delays;
+ chan_desc->Td = Td;
+ chan_desc->sampling_rate = sampling_rate;
+ chan_desc->channel_bandwidth = channel_bandwidth;
+ chan_desc->ricean_factor = ricean_factor;
+ chan_desc->aoa = aoa;
+ chan_desc->random_aoa = random_aoa;
+ chan_desc->forgetting_factor = forgetting_factor;
+ chan_desc->channel_offset = channel_offset;
+ chan_desc->path_loss_dB = path_loss_dB;
+ chan_desc->first_run = 1;
+ chan_desc->ip = 0.0;
+ chan_desc->max_Doppler = max_Doppler;
+ chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*));
+ chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*));
+ chan_desc->a = (struct complex**) malloc(nb_taps*sizeof(struct complex*));
LOG_D(OCM,"[CHANNEL] Filling ch \n");
@@ -99,27 +100,30 @@ void fill_channel_desc(channel_desc_t *chan_desc,
chan_desc->chF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); // allocate for up to 100 RBs, 12 samples per RB
LOG_D(OCM,"[CHANNEL] Filling a (nb_taps %d)\n",nb_taps);
-
for (i = 0; ia[i],nb_tx*nb_rx * sizeof(struct complex));
chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex));
}
LOG_D(OCM,"[CHANNEL] Doing R_sqrt ...\n");
-
if (R_sqrt == NULL) {
- chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*));
-
+ chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*));
for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
-
+ chan_desc->R_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
for (j = 0; jR_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0;
}
}
- } else {
- chan_desc->R_sqrt = R_sqrt;
+ }
+ else {
+ chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*));
+ for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
+ //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0];
+ /* all chan_desc share the same R_sqrt, coming from caller */
+ chan_desc->R_sqrt[i] = R_sqrt[0];
+ }
}
for (i = 0; iricean_factor);
-
- for (i=0; inb_taps; i++)
+ for (i=0;inb_taps;i++)
LOG_D(OCM,"[CHANNEL] tap %d: amp %f, delay %f\n",i,chan_desc->amps[i],chan_desc->delays[i]);
chan_desc->nb_paths=10;
@@ -160,12 +163,14 @@ double etu_amps_dB[] = {-1.0,-1.0,-1.0,0.0,0.0,0.0,-3.0,-5.0,-7.0};
double default_amps_lin[] = {0.3868472 , 0.3094778 , 0.1547389 , 0.0773694 , 0.0386847 , 0.0193424 , 0.0096712 , 0.0038685};
double default_amp_lin[] = {1};
+double ts_shift_delays[] = {0, 1/7.68};
+double ts_shift_amps[] = {0, 1};
+
//correlation matrix for a 2x2 channel with full Tx correlation
struct complex R_sqrt_22_corr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
- {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0},
- {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
- {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}
-};
+ {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0},
+ {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
+ {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}};
struct complex *R_sqrt_22_corr[1] = {R_sqrt_22_corr_tap};
//correlation matrix for a fully correlated 2x1 channel (h1==h2)
@@ -174,10 +179,9 @@ struct complex *R_sqrt_21_corr[1] = {R_sqrt_21_corr_tap};
//correlation matrix for a 2x2 channel with full Tx anti-correlation
struct complex R_sqrt_22_anticorr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0},
- {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0},
- {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
- {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0}
-};
+ {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0},
+ {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0},
+ {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0}};
struct complex *R_sqrt_22_anticorr[1] = {R_sqrt_22_anticorr_tap};
//correlation matrix for a fully anti-correlated 2x1 channel (h1==-h2)
@@ -186,12 +190,62 @@ struct complex *R_sqrt_21_anticorr[1] = {R_sqrt_21_anticorr_tap};
struct complex **R_sqrt_ptr2;
+// full correlation matrix in vectorized form for 2x2 channel, where h1 is perfectly orthogonal to h2
+
+struct complex R_sqrt_22_orthogonal_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0},
+ {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.0,0.0},
+ {0.0,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0},
+ {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.70711,0.0}};
+struct complex *R_sqrt_22_orthogonal[1] = {R_sqrt_22_orthogonal_tap};
+
+// full correlation matrix for TM4 to make orthogonal effective channel
+
+
+
+
+struct complex R_sqrt_22_orth_eff_ch_TM4_prec_real_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0},
+ {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {-0.70711,0.0},
+ {0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0},
+ {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}};
+struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_real[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_real_tap};
+
+
+
+
+struct complex R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap[16] = {{0.70711,0.0}, {0.0,0.0}, {0.0, -0.70711}, {0.0,0.0},
+ {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.0,0.70711},
+ {0.0,-0.70711}, {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0},
+ {0.0, 0.0}, {0.0,0.70711}, {0.0, 0.0}, {-0.70711,0.0}};
+struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_imag[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap};
+
+//Correlation matrix for EPA channel
+struct complex R_sqrt_22_EPA_low_tap[16] = {{1.0,0.0}, {0.0,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.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}, {1.0,0.0}};
+struct complex *R_sqrt_22_EPA_low[1] = {R_sqrt_22_EPA_low_tap};
+
+struct complex R_sqrt_22_EPA_high_tap[16] = {{0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0},
+ {0.4500,0.0}, {0.7179,0.0}, {0.2821,0.0}, {0.4500,0.0},
+ {0.4500,0.0}, {0.2821,0.0}, {0.7179,0.0}, {0.4500,0.0},
+ {0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0}};
+struct complex *R_sqrt_22_EPA_high[1] = {R_sqrt_22_EPA_high_tap};
+
+struct complex R_sqrt_22_EPA_medium_tap[16] = {{0.8375,0.0}, {0.5249,0.0}, {0.1286,0.0}, {0.0806,0.0},
+ {0.5249,0.0}, {0.8375,0.0}, {0.0806,0.0}, {0.1286,0.0},
+ {0.1286,0.0}, {0.0806,0.0}, {0.8375,0.0}, {0.5249,0.0},
+ {0.0806,0.0}, {0.1286,0.0}, {0.5249,0.0}, {0.8375,0.0}};
+struct complex *R_sqrt_22_EPA_medium[1] = {R_sqrt_22_EPA_medium_tap};
+
+
+
+//Rayleigh1_orth_eff_ch_TM4
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
double sampling_rate,
- double channel_bandwidth,
+ double channel_bandwidth,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB)
@@ -203,15 +257,15 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
double aoa,ricean_factor,Td,maxDoppler;
int channel_length,nb_taps;
- chan_desc->nb_tx = nb_tx;
- chan_desc->nb_rx = nb_rx;
- chan_desc->sampling_rate = sampling_rate;
- chan_desc->channel_bandwidth = channel_bandwidth;
- chan_desc->forgetting_factor = forgetting_factor;
- chan_desc->channel_offset = channel_offset;
- chan_desc->path_loss_dB = path_loss_dB;
- chan_desc->first_run = 1;
- chan_desc->ip = 0.0;
+ chan_desc->nb_tx = nb_tx;
+ chan_desc->nb_rx = nb_rx;
+ chan_desc->sampling_rate = sampling_rate;
+ chan_desc->channel_bandwidth = channel_bandwidth;
+ chan_desc->forgetting_factor = forgetting_factor;
+ chan_desc->channel_offset = channel_offset;
+ chan_desc->path_loss_dB = path_loss_dB;
+ chan_desc->first_run = 1;
+ chan_desc->ip = 0.0;
LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model);
@@ -220,27 +274,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
LOG_W(OCM,"channel model not yet supported\n");
free(chan_desc);
return(NULL);
-
case SCM_B:
LOG_W(OCM,"channel model not yet supported\n");
free(chan_desc);
return(NULL);
-
case SCM_C:
chan_desc->nb_taps = 18;
chan_desc->Td = 4.625;
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double));
-
for (i = 0; i